Hi there. I am having some problems in using the RFID reader. Right now, I am trying to access control an LED and FAN with two RFID card readers. So ideally if I swipe Card A once, it should turn ON the Led and on the next swipe it should turn OFF the led. And the same applies to controlling the FAN using RFID card 2. However, it seems that the Serial1.Available function detects the card twice on a single swipe, due to which it sends the command twice for controlling the LED/FAN. So it will momentarily switch ON the led/fan and then switch it off. Also, the serial1.available function returns null every time even after swipping the RFID card. So if you could help me with it please, it would be great. Thanks in advance
Here is my code snippet:
#include "PietteTech_DHT/PietteTech_DHT.h"
#include "RelayShield/RelayShield.h"
#include "RelayShield/RelayShield.h"
#include "PietteTech_DHT/PietteTech_DHT.h"
#define DHTTYPE DHT22
#define DHTPIN D1
RelayShield myRelays;
void dht_wrapper();
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
int lastPub;
int temp;
int hum;
float current;
uint16_t messageid;
int val = 0;
char code[10];
int bytesread = 0;
int num;
int enable = D0;
int read;
int led = D7;
int Relay=D3;
double potentiometer;
int light_status=0;
int fan_status=0;
void setup()
{
myRelays.begin();
Serial1.begin(2400);
// Serial.begin(9600);
pinMode(enable,OUTPUT);
digitalWrite(enable, LOW);
read = 1;
pinMode(led, OUTPUT);
pinMode(Relay, OUTPUT);
String FanAccessKey="2600D610B3";
String LightAccessKey="02007F6479";
}
//int mVperAmp = 66; // use 100 for 20A Module and 66 for 30A Module
//int ACSoffset = 2500;
void loop()
{
String FanAccessKey="2600D610B3";
String LightAccessKey="02007F6479";
DHT.acquire();
hum = DHT.getHumidity();
temp = (DHT.getFahrenheit()-32)*5/9;
potentiometer= (analogRead(A0) * 3.3 )/4095 ; // current = ((current - ACSoffset) / mVperAmp);
// if ( (millis() - lastPub) > 2000 ) //It publishes every 2 secs
{
Particle.publish("Humidity", String(hum) + "%");
Particle.publish("Temperature", String(temp) + " °C");
Particle.publish("Frob knob: ", String(potentiometer) +"V");
//lastPub = millis();
}
digitalWrite(enable, LOW); // Activate the RFID reader
Particle.publish("Swipe now","Ready");
while(Serial1.available())
{
Particle.publish("Serial.Available is ", Serial1.available());
if((val = Serial1.read()) == 10)
{
bytesread = 0;
while(bytesread<10)
{ // read 10 digit code
if( Serial1.available() > 0)
{
val = Serial1.read();
if((val == 10)||(val == 13))
{
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}
}
//}
if(bytesread==10)
{
//2600D610B3
if(code[0]=='2' & code[1]=='6' & code[2]=='0' & code[3]=='0' & code[4]=='D' & code[5]=='6' & code[6]=='1' & code[7]=='0' & code[8]=='B' & code[9]=='3')
{
if(light_status==0) // Heater is OFF
{
Particle.publish("Turning led","on");
digitalWrite(led, HIGH);
light_status=1;
}
else if(light_status==1)
{
Particle.publish("Turning led","OFF");
digitalWrite(led, LOW);
light_status=0;
}
}
//02007F6479
else if(code[0]=='0' & code[1]=='2' & code[2]=='0' & code[3]=='0' & code[4]=='7' & code[5]=='F' & code[6]=='6' & code[7]=='4' & code[8]=='7' & code[9]=='9')
{
if(fan_status==0) // Heater is OFF
{
Particle.publish("Turning Fan","on");
digitalWrite(Relay, HIGH);
fan_status=1;
}
else if(fan_status==1)
{
Particle.publish("Turning fan","OFF");
digitalWrite(Relay, LOW);
fan_status=0;
}
}
for(int i=0;i<10;i++) code[i]=0;
bytesread = 0;
digitalWrite(enable, HIGH); // deactivate the RFID reader for a moment so it will not flood
delay(600); // wait for a second
digitalWrite(enable, LOW);
}
}
}
}
void dht_wrapper()
{
DHT.isrCallback();
}
ANother issue is that, even through the fan/led turn on/off intermittently, the Particle does not Publish the message on Dashboard. It just gets stuck and publishes the event:
spark/device/app-hash53752DBA3712ED004266DCC7C73932990B
you should move the access key variables out of any function to make them global.
you should add a timeout variable that blocks the redetection of the last scanned card for a few seconds.
you should flush the serial buffer once you got a full key
in your code you need some logic to limit your publishing rate to 1 per second (with burst of four with an at least four sec pause), but in many cases you will violate the burst limit by attempting six or more publishes.
the way you compare your strings could be improved considerably by using strcmp(code, (const char*)accessKey) == 0). You just need to append a '\0' to your code[] in order to make it a C string.
why do you have two sets of includes for the same libraries?
memset(code, 0, sizeof(code)) is quicker than your for() to clear the code array, but since you are not using code and bytesread globally anyway, having them local would rid you of the need to clear them completely
Maybe just write
AFAIK there are different kinds of NFC cards - you’d need to look at the readers datasheet which kinds are supported and check if your key fob is compatible.