How to load/save data from serial port to a .txt file?

edited January 2019 in Arduino

Hello there,

Last week thanks to the help of GoToLoop I manage to get a RFIP reader to work. And eventually I made this code that shows a picture for a a few second if the RFID reader reads the correct card.

import processing.serial.Serial;

static final String COMPARADOR = "4500B8C02A17";
static final String DEPOSITO = "Deposito $50";
static final String SALDO = "Saldo en 0";

String mensaje = "Texto inicial";

int tiempo;
int espera = 5000;

PImage imagen;

int contador = 1;

void setup() {
  size(900, 600);
  frame.setBackground(new java.awt.Color(0, 0, 0));
  imagen = loadImage("1.jpg");

  String[] portas = Serial.list();
  printArray(portas);

  new Serial(this, portas[0], 9600).bufferUntil(ENTER);

  tiempo = millis();
}

void draw () {


  if (COMPARADOR.equals(mensaje)) {
    imageMode(CENTER);
    image(imagen, width/2, height/2);
    if (millis() - tiempo >= espera) {
      mensaje = SALDO;
      tiempo = millis();
      contador++;
    }
  } else {
    background(0);
  }



  println(mensaje);
  print("Pasada #: ");
  println(contador);
  print("Tiempo: ");
  println(tiempo);
}

void serialEvent(Serial s) {
  mensaje = s.readString().trim();
}

The thing is that there will be many cards and what I want is that each card can be used only once. So If a card is read for the first time, the image is displayed. If the same card is read later nothing happens.

So far I read about saving/loading data from a .txt file, and I guess this is the easiest way. To store (in a .txt file) the cards that have been read, and to check (in the same .txt file) every time a new card is read and if has been already read nothing happens, and if it is the first time is read the image is displayed.

I am trying but with no success, any ideas?

Thanks!

Answers

  • The thing is that there will be many cards and what I want is that each card can be used only once.

    • I'm assuming each card has its own COMPARADOR, right?
    • So you're gonna need a String[] array in order to store every valid "card".
    • You also say that a "card" can only be used once.
    • So another boolean[] is necessary to accompany the String[] array.
  • Exactly, each card will have its own COMPARADOR (which is its own ID). What I need is a String that stores the "used cards" (because the can only be used once).

    What is not clear to me is when to save to the .txt file. Because I want the used cards information to be available always, I mean in case I restart the program.

    And also is not clear the boolean[] what is for?

  • To store the "used up" state as true. Not used as false:
    https://Processing.org/reference/boolean.html

    Perhaps you may consider using the Table class to both loadTable() & saveTable() the IDs states:

    https://processing.org/reference/Table.html
    https://processing.org/reference/loadTable_.html
    https://processing.org/reference/saveTable_.html

  • @GoToLoop Thanks! I had no idea about tables, I'll try

  • So I've been dealing with this table but with no success. I made a table with the first column, named id which contains all of the ids of the cards (I will have to load them later) and the second column with the state, 0 = the card hasn't been read yet. 1 = the card has been read.

    I have 2 problems:

    1. I get NullPointerException while trying to get the row corresponding to the id read from the serial. If I print the row's value I get a NULL

    2. If the state is 0, which means that the vcard hasn't been used, I show the image for a few seconds and then I need to change the value of the state to 1. I don't know the row ID for the setInt

    The .csv file is this:

    Please take a look at the comments in the code:

    import processing.serial.Serial;
    
    static final String COMPARADOR = "4500B8C02A17";
    static final String DEPOSITO = "Deposito $50";
    static final String SALDO = "Saldo en 0";
    
    String mensaje = "Texto inicial";
    
    int tiempo; // this line and the next is for the delay time of the image
    int espera = 5000;
    
    PImage imagen;
    
    int contador = 1;
    
    Table table;
    
    void setup() {
      size(900, 600);
      frame.setBackground(new java.awt.Color(0, 0, 0)); // fullscreen moder with black background
      imagen = loadImage("1.jpg");
    
      String[] portas = Serial.list(); // load serial port
      printArray(portas);
    
      new Serial(this, portas[0], 9600).bufferUntil(ENTER);
    
      tiempo = millis();
    
      table = loadTable("data.csv", "header"); // load the table with "id" and "state"
    }
    
    void draw () {  
    
      TableRow result = table.findRow(mensaje, "id"); //here i try to find the row with the ID i get from the serial port
      int state = result.getInt("state"); //here i try to get the value of the state of the id read by the serial
                                          // but i get a NullPointerException
    
      if (state == 0) {                   // if state is 0, wich means false, which means that is the first time the card is read, then show the image
        imageMode(CENTER);
        image(imagen, width/2, height/2); // show the image
        if (millis() - tiempo >= espera) { //wait 5 seconds
          mensaje = SALDO;
          tiempo = millis();
          contador++;
        }
        result.setInt("state", 1);   // here i try to change the value of state, it has to be 1 now, BUT i need the row index, wichi i dont know (HOW TO KNOW??)
      } else {   // if state is 1, it means that the card was used, so don't display anything
        background(0);
      }
    }
    
    void serialEvent(Serial s) {
      mensaje = s.readString().trim();
    }
    

    Any ideas???

    Thanks!!!!

  • edited October 2015
    • AFAIK, in a Table got from loadTable(), all its column types are Table.STRING.
    • So we need to manually setColumnType() the 1s which aren't. :-<
    • (table = loadTable("data.csv", "header")).setColumnType("state", Table.INT);
    • After that, I expect getInt() may start working. ^#(^
    • Some Table sketch samples using setColumnTypes(): http://forum.Processing.org/two/discussions/tagged?Tag=setcolumntypes()
  • hmmmm... I tried setColumnType() and it seems to work because then I print the columns types println(table.getColumnTypes()); and column state is int now.

    void setup() {
      size(900, 600);
      frame.setBackground(new java.awt.Color(0, 0, 0)); // fullscreen moder with black background
      imagen = loadImage("1.jpg");
    
      String[] portas = Serial.list(); // load serial port
      printArray(portas);
    
      new Serial(this, portas[0], 9600).bufferUntil(ENTER);
    
      tiempo = millis();
    
      table = loadTable("data.csv", "header"); // load the table with "id" and "state"
      table.setColumnType("state", Table.INT);
    
    
      println(table.getColumnTitles());
      println();
      println(table.getColumnTypes());
      println();
    }
    

    BUT the problem is in the read of mensaje: TableRow result = table.findRow(mensaje, "id");

    Please see the print when I try to find the row of the id 4500B8C02A17 (the only card i have now)

  • edited October 2015
  • I see, but I don't get null (and I shouldn't as the card I'm reading is the one in the third position), I get this strange reads:

    Card I'm reading has the id in the 3rd position:

    So I have no idea what is happening :(

    • Those "strange" reads are toString()'s default behavior.
    • When we create a class and it doesn't @Override toString() method, that's what happens when we attempt to print() it.
    • Neither Table nor RowPointer bothered to do that though.
    • Nevertheless, everything else works. Including getInt().
  • I have no idea what you are talking about here: :-?

    Those "strange" reads are toString()'s default behavior.

    When we create a class and it doesn't @Override toString() method, that's what happens when we attempt to print() it.

    Neither Table nor RowPointer bothered to do that though.

    And is not working, because the ID of the card that I have is: 4500B8C02A17. When I read the card, I should get a 0 when printing result (instead of the "strange values") , or am I missing something? :-/

  • edited October 2015 Answer ✓

    I should get a 0 when printing result.

    Nope! You should get a 0 (or 1) when using method getInt().
    If instead you attempt to directly print() a Table or a TableRow object, you'll get those "strange" things.

    Again, due to lack of @Override their toString() method:
    http://docs.Oracle.com/javase/8/docs/api/java/lang/Object.html#toString--

  • edited October 2015

    I feel so dumb L-)

    Thanks again for your help! ^:)^ I can continue on my own (for a bit). :D

Sign In or Register to comment.