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);
}
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')
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?
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);
}