Sending Data from Arduino to Processing with RFID Reader

Hey,

I'm currently working on a project where I want to switch the colors of a square in processing through using rfid chips with arduino. So everytime I place a rfid-chip on my rfid-reader, arduino should send the data to processing, and depending on the card-number the color of the square in processing should change.
The connection is somehow not working and I cannot switch the colors of the square in processing.
I use the Arduino Elegoo Uno R3 and the joy-it RFID Reader.
Would love to get some help, how to solve this problem!

Here is my Arduino-Code:

#define TIMEOUT 200

//reader class that makes a String from the RFID-chip input
class reader  
{
  public:
    unsigned long timer;
    String input;
    int state;

    //Sets the state of the switch to 0
    reader()
    {
      state = 0;
    }

/*2240920, 1080180
Method that gets chars and adds them to the input string. The char string actually looks something like ("2-27-5-39-47-39-3")
The start of the text will be represented by the number 2 and the end by 3. Thats the Ascii way of telling the start of text and the end of text. We are only interested in sending the information inbetween those two numbers. This method will help sorting this out in the right way.*/

  bool data(char c)
    {
      bool result = false;

      switch (state)
      {

/*Because the RFIDs first char is always 2, the program can clean the input string. The program then sets the state to 1.*/

        case 0:
          if (c == 2)
          {
            input = "";
            state = 1;
          }
          break;

/*The RFIDs last character is always 3. Therefore the program can add chars to the input string until it reach the character 3.
When the program reach the char 3, the result is true and the programs tracks the time. That's because we need a timeout where the program can't add more chars to the string.*/

        case 1:
          if (c == 0)
          {
            timer = millis();
            result = true;
            state = 2;
          }
          else
          {
            input += c;
          }
          break;

        case 2:
          timer = millis();
          break;
      }
      return result;
    }

/*This methods is updating the state to 0 when the timeout is reached*/

    void update()
    {
      if (state == 2)
      {
        if (millis() > timer + TIMEOUT)
          state = 0;
      }
    }
};

//Initialize a reader named port1
reader port1;

void setup()  
{

  //Begins the serial communication with a baudrate

  Serial.begin(9600);

}


void loop()

{

/*This is running when the serial is available and if there is a data input it will print the input string*/

  while
  (Serial.available())
  {
    if (port1.data(Serial.read()) == true)
    {
      Serial.println(port1.input);
    }
  }
  port1.update();
}

and here is my processing-Code

import processing.serial.*;

Serial myPort;         // The serial port  
String finalRead = ""; // Variable with final data  
String inputRead = ""; // Variable that recieves the data  
int state = 0;         // Variable to store the program state  

void setup() {

  size(800, 800); //Size of the program window
  background(50, 50, 150); //Background colour

  // List all the available serial ports
  printArray(Serial.list());

  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[6], 9600);

  // The rectangle will be placed based on it's own center
  rectMode(CENTER);

}

void draw() {

  /*When the serial port is available the data from the RFID is 
    loaded into the finalRead variable.*/

  while (myPort.available() > 0)
  {
    //The c variable is updated with the read method

    char c=(char)myPort.read();

    /*
      When processing recieves data from Arduinos println command 
      it is recieved with a \r in the beginning
      and a c\ in the end. 
      Therefore we add c to inputRead when 
      we are not encountering \r.

      If we encounter \n we know that the string is done reading. 
      The string is loaded into the finalRead variable and 
      the data is cleared from inputRead.
     */

    if (c=='\n')
    {
      finalRead = inputRead;
      inputRead = ""; 
      println("data: " + finalRead);
    } else if (c!='\r')
    {
      inputRead+=c;
    }
  } 

   /*Now the program checks if the data is equal to the data
   on a wanted RFID-chip. If thats the case the state of the   
   program changes. Here you need to fill in data from a specific 
   RFID-chip*/

  if (finalRead.equals("D36BEF02")) {
    state = 1;
  }

  /*Another RFID-chip if-statement with another state. You can do this with as many RFID-chips you want.*/

  if (finalRead.equals("040047C00A89")) {
    state = 2;
  }

  /*If the state is changed to 1, the colour of the center Rectangle 
    is changed to red.*/

  if (state == 1) {
    fill(200, 20, 20);
  }

  /*If the state is change to 2, the colour of the center Rectangle is changed to green.*/
  if (state == 2) {
    fill(20, 200, 20);
  }

  /*The program now draws a rectangle with a fill colour dependent on the state variable*/
  rect(width/2, height/2, width-100, height-100);
}

Welcome

To compare a character you have to add single quotes around the character, like this :
if (c == '2')

1 Like

Thank you guix, i still can't see the rfid-numbers from my chips in the compiler of the arduino. :frowning: Is there something else you can find?

When the program reach the char 3, the result is true and the programs tracks the time. That's because we need a timeout where the program can't add more chars to the string.

case 1:
          if (c == 0)
          {
            timer = millis();
            result = true;
            state = 2;
          }

According to the comment, shouldn't case 1 be
if (c == '3')

Good point I changed it, it is still not working

What is the problem. Previously you said

i still can't see the rfid-numbers from my chips in the compiler of the arduino

When I take the code you provided with the two corrections previously pointed out, I can see the date when entered from the Serial monitor.

One issue that I see is when you enter data in the Serial monitor like 2-27-5-39-47-39-3 the reading stops at the 3 in 39 and all that is printed is -27-5-

2-27-5-49-47-69-3 comes through completely as -27-5-49-47-69-

You can not have start and end characters which are part of the data. How exactly is the data coming from the reader. Is it an ascii numerical character string where 3 can be a part of the data?

Honestly , I'm so desperate this is all not working out! I can't get the connection between Arduino and processing right

Hello :), so I finally receive my data i processing. I can see the rfid chip codes in the Processing compiler! Yey! Unfortunately the color of the inner square is still not changing. Here is the code. Thank you for your help.

Here is my Arduino-Code:

/*
 * ----------------------------------------------------------------------
 * Example program showing how to read new NUID from a PICC to serial.
 * ----------------------------------------------------------------------
 * https://circuits4you.com
 * 
 * RC522 Interfacing with NodeMCU
 * 
 Typical pin layout used:
 * ---------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * ----------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

#include <SPI.h>
#include <MFRC522.h>

constexpr uint8_t RST_PIN = 9;     // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 10;     // Configurable, see typical pin layout above
 
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key; 

// Init array that will store new NUID 
byte nuidPICC[4];

void setup() { 
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("This code scan the MIFARE Classsic NUID."));
  Serial.print(F("Using the following key:"));
  printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}
 
void loop() {

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }

  if (rfid.uid.uidByte[0] != nuidPICC[0] || 
    rfid.uid.uidByte[1] != nuidPICC[1] || 
    rfid.uid.uidByte[2] != nuidPICC[2] || 
    rfid.uid.uidByte[3] != nuidPICC[3] ) {
    Serial.println(F("A new card has been detected."));

    // Store NUID into nuidPICC array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }
   
    Serial.println(F("The NUID tag is:"));
    Serial.print(F("In hex: "));
    printHex(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    Serial.print(F("In dec: "));
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
  }
  else Serial.println(F("Card read previously."));

  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
}


/**
 * Helper routine to dump a byte array as hex values to Serial. 
 */
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

/**
 * Helper routine to dump a byte array as dec values to Serial.
 */
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}

Here my processing code

import processing.serial.*;

Serial myPort;         // The serial port  
String finalRead = ""; // Variable with final data  
String inputRead = ""; // Variable that recieves the data  
int state = 0;         // Variable to store the program state  

void setup() {

  size(800, 800); //Size of the program window
  background(50, 50, 150); //Background colour

  // List all the available serial ports
  printArray(Serial.list());

  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[4], 9600);

  // The rectangle will be placed based on it's own center
  rectMode(CENTER);

}

void draw() {

  /*When the serial port is available the data from the RFID is 
    loaded into the finalRead variable.*/

  while (myPort.available() > 0)
  {
    //The c variable is updated with the read method

    char c=(char)myPort.read();

    /*
      When processing recieves data from Arduinos println command 
      it is recieved with a \r in the beginning
      and a c\ in the end. 
      Therefore we add c to inputRead when 
      we are not encountering \r.

      If we encounter \n we know that the string is done reading. 
      The string is loaded into the finalRead variable and 
      the data is cleared from inputRead.
     */

    if (c=='\n')
    {
      finalRead = inputRead;
      inputRead = ""; 
      println("data: " + finalRead);
    } else if (c!='\r')
    {
      inputRead+=c;
    }
  } 

   /*Now the program checks if the data is equal to the data
   on a wanted RFID-chip. If thats the case the state of the   
   program changes. Here you need to fill in data from a specific 
   RFID-chip*/

  if (finalRead.equals("7320574163")) {
    state = 1;
  }

  /*Another RFID-chip if-statement with another state. You can do this with as many RFID-chips you want.*/

  if (finalRead.equals("21110723902")) {
    state = 2;
  }

  /*If the state is changed to 1, the colour of the center Rectangle 
    is changed to red.*/

  if (state == '1') {
    fill(#ffffff);
  }

  /*If the state is change to 2, the colour of the center Rectangle is changed to green.*/
  if (state == '2') {
    fill(#000000);
  }

  /*The program now draws a rectangle with a fill colour dependent on the state variable*/
  rect(width/2, height/2, width-100, height-100);
}

Good progress. :grinning:
If you are seeing the correct id on the Serial printing from the Arduino, then that piece is correct.

It would appear that your issues are on the Processing side, and I know little about Processing.

One thing do see in the Processing code is this where state is declared as an int.

if (finalRead.equals("7320574163")) {
    state = 1;
  }
 if (finalRead.equals("21110723902")) {
    state = 2;
  }

Later you use this test, where "state" is used a a char.

if (state == '1')
if (state == '2')

Try without the single quotes.

You may have better success with your questions on a Processing forum.

1 Like

Okay thank you, I will try it in the Processing Forum