我正在使用带有arduino nano的125Khz RFID模块RDM6300。 当卡在RFID读取器附近时,环路将多次读取卡。我希望它只读取一次,当卡在读卡器附近时,如果正在建立新连接,则再次读取它。 *此代码不是由我写的,这是来源: https://github.com/Wookai/arduino-rfid
// define constants for pins
//int SUCCESS = 10;
//int ERROR = 13;
// variables to keep state
int readVal = 0; // individual character read from serial
unsigned int readData[10]; // data read from serial
int counter = -1; // counter to keep position in the buffer
char tagId[11]; // final tag ID converted to a string
char* authorizedTags[4]; // array to hold the list of authorized tags
// fills the list of authorzied tags
void initAuthorizedTags() {
// add your own tag IDs here
authorizedTags[0] = "0400680B85";
authorizedTags[1] = "0400063EB9";
authorizedTags[2] = "040004F3F5";
authorizedTags[3] = "04006813AB";
}
void setup() {
Serial.begin(9600);
// pinMode(SUCCESS, OUTPUT);
//pinMode(ERROR, OUTPUT);
initAuthorizedTags();
}
// check if the tag ID we just read is any of the authorized tags
int checkTag() {
int i;
for (i = 0; i < 4; ++i) {
if (strcmp(authorizedTags[i], tagId) == 0) {
return 1;
}
}
return 0;
}
// convert the int values read from serial to ASCII chars
void parseTag() {
int i;
for (i = 0; i < 10; ++i) {
tagId[i] = readData[i];
}
tagId[10] = 0;
}
// once a whole tag is read, process it
void processTag() {
// convert id to a string
parseTag();
// print it
printTag();
// check if the tag is authorized
if (checkTag() == 1) {
tagSuccess(); // if so, perform an action (blink a led, open a door, etc...)
} else {
tagFailed(); // otherwise, inform user of failure
}
}
void printTag() {
Serial.print("Tag value: ");
Serial.println(tagId);
}
// perform an action when an authorized tag was read
void tagSuccess() {
Serial.println("Tag authorized.");
// here, we simply turn on the success LED for 2s
// digitalWrite(SUCCESS, HIGH);
//digitalWrite(ERROR, LOW);
// delay(2000);
}
// inform the user that the tag is not authorized
void tagFailed() {
Serial.println("Unauthorized access!");
//digitalWrite(SUCCESS, LOW);
// digitalWrite(ERROR, HIGH);
// delay(2000);
}
// this function clears the rest of data on the serial, to prevent multiple scans
void clearSerial() {
while (Serial.read() >= 0) {
; // do nothing
}
}
void loop() {
// turn LEDs off
// digitalWrite(SUCCESS, LOW);
// digitalWrite(ERROR, LOW);
if (Serial.available() > 0) {
// read the incoming byte:
readVal = Serial.read();
// a "2" signals the beginning of a tag
if (readVal == 2) {
counter = 0; // start reading
}
// a "3" signals the end of a tag
else if (readVal == 3) {
// process the tag we just read
processTag();
// clear serial to prevent multiple reads
clearSerial();
// reset reading state
counter = -1;
}
// if we are in the middle of reading a tag
else if (counter >= 0) {
// save valuee
readData[counter] = readVal;
// increment counter
++counter;
}
}
}
谢谢。
感谢您的回答。我试图接受多次读取并只打印一次,但它会保持打印“已读”而不是第一次读卡,这是代码:
void printTag() {
if(strcmp(tagId,previous)==1){
strcpy(previous, tagId);
Serial.print("Tag value: ");
Serial.println(tagId);
}
else
{
Serial.print("already read");
}
}
我还尝试在标签结束后延迟,但它仍然会多次读取卡片。
我尝试了另一个代码,它仍然多次读取标记。
#include <SoftwareSerial.h>
// RFID | Nano
// Pin 1 | D2
// Pin 2 | D3
SoftwareSerial Rfid = SoftwareSerial(2,3);
int timer=0;
int reference = 1000;
int card_status = 0;
void setup() {
// Serial Monitor to see results on the computer
Serial.begin(9600);
// Communication to the RFID reader
Rfid.begin(9600);
}
void read() {
// check, if any data is available
// as long as there is data available...
while(Rfid.available() > 0 ){
// read a byte
int r = Rfid.read();
// print it to the serial monitor
Serial.print(r, DEC);
Serial.print(" ");
}
// linebreak
Serial.println();
timer=0;
}
void loop()
{
if((Rfid.available() > 0 ) && (card_status == 0) )
{
read();
}
if((!Rfid.available() > 0 ) && (card_status == 1) )
{
card_status=0;
}
}
对于迟到的回复我很抱歉。我忘记了这个话题。
我通过在第一次写入RFID代码之后让arduino等待响应来解决问题。 我能够做到这一点,因为我的arduino通过串口将代码发送到C#应用程序。
以下是它的工作原理:arduino在串行打印RFID代码,从那里它被C#应用程序拾取,该应用程序搜索数据库以查看代码是否存储在那里。根据结果,应用程序打印一个由arduino拾取的字符('y'或'n')。根据收到的字符,arduino会点亮LED(绿色或红色)并发出噪音。现在可以进行新的RFID阅读。
以下是代码:
#include <SoftwareSerial.h>
#include "RDM6300.h"
SoftwareSerial rdm_serial(8, 9);
RDM6300<SoftwareSerial> rdm(&rdm_serial);
String comanda;
char c="";
int led_verde = 2;
int led_rosu = 7;
int buzzer = 12;
int i;
void buzz(int n = 1)
{
for (int i = 0; i < n; i++) {
digitalWrite(buzzer, LOW);
delay(200);
digitalWrite(buzzer, HIGH);
delay(200);
}
}
void ledVerde()
{
digitalWrite(led_verde, HIGH);
buzz(1);
delay(1000);
digitalWrite(led_verde, LOW);
}
void ledRosu()
{
digitalWrite(led_rosu, HIGH);
buzz(3);
delay(1000);
digitalWrite(led_rosu, LOW);
}
void setup()
{
pinMode(led_verde, OUTPUT);
pinMode(led_rosu, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(led_verde, LOW);
digitalWrite(led_rosu, LOW);
digitalWrite(buzzer, HIGH);
Serial.begin(9600);
}
void loop()
{
static unsigned long long last_id = 0;
last_id = rdm.read();
rdm.print_int64(last_id);
Serial.println();
rdm_serial.end();
Serial.flush();
while(!Serial.available());
c=Serial.read();
if(c=='y')
{
ledVerde();
c="";
}
if(c=='n')
{
ledRosu();
}
Serial.flush();
last_id="";
c="";
rdm_serial.begin(9600);
}
您可以在此处找到RDM6300库:https://github.com/arliones/RDM6300-Arduino
答案 0 :(得分:0)
您可以在阅读(标签结尾)后设置延迟(例如delay(2000)
)。 (例如)2秒的延迟将允许用户将卡移动远离读取器。请注意,delay
是一个阻止命令,可能不适合您的目的,在这种情况下,您可能会考虑使用millis
计数来激活/停用Serial.read
。
另一种选择是接受多次读取,但保持已读取哪种卡的状态。如果新卡号与旧卡号相同(在合理的时间范围内),则忽略。
答案 1 :(得分:0)
例如,您可能更喜欢在首次接近天线时读取RFID卡一次;当它不断接触天线时,仍然不再采取行动。当您取出卡并将其再次放置在天线附近时,MCU会再次开始读取卡。
如果是这样,以下代码可供您参考。我所做的只是在检查RFID卡是否靠近天线之前再添加1个标志以继续检查
card_status
。
int card_status = 0; //0:readable; 1:not-readable
if ( (Serial.available() > 0) && (card_status == 0) ) {
card_status = 1; //disable to read card after exit this loop
//your code, a card is near to the antenna, try to read it.
readVal = Serial.read();
if (readVal == 2) {
counter = 0; // start reading
} else if (readVal == 3) {
processTag();
clearSerial();
counter = -1;
} else if (counter >= 0) {
readData[counter] = readVal;
++counter;
}
}
在没有RFID信号进入时重置卡状态&amp;&amp;卡状态为真,
if ( (!(Serial.available() > 0)) && (card_status == 1) ) {
card_status = 0; //enable to read card again
//no signal, no card is near to the antenna.
}
答案 2 :(得分:0)
很长时间过去了最初的问题,但也许我的回答对将来的访问者有用。
RDM6300的工作原理:
把它想象成机场的行李传送带。转盘(读取器)上有多个行李(数据),您可以一个接一个地挑选它们(转移到缓冲区)。
因此,多次读取的问题是,您已经在读取器中读取了数据(轮播中的行李),您的代码正在将它们逐渐转移到缓冲区(捡起行李)。
在我们的示例中,如果您不想收拾所有行李,则可以要求某人在他们拿到您之前将其中一些拿走。
下面的代码可以做到这一点。当读取器中有数据时(卡靠近读取器),它将数据从读取器传输到缓冲区,然后将缓冲区中的所有数据清零:
首先,将此代码放在“ void setup()”之前:
boolean multipleRead = false;
这定义了一个false / true变量,以告诉您这是您是第一次读取标签(false),还是被多次读取(true)。
然后,将其放在代码块的末尾,以显示标记已被完全读取。如果将Michael Schoeffler的库用于RDM6300 / 630 RFID,请将其放在“ else if(ssvalue == 3){”之后:
multipleRead = true;
读取标签后,它将变量更改为true。这表明程序已完成您的第一次读取,而下一个即将发生的读取将是“多次读取”,而您不希望它们。
然后将其放在RFID阅读器代码的末尾(如果您的RFID代码在void loop()下,请将下面的代码放在“ void loop(){”之后:
if (multipleRead) {
while (ssrfid.available() > 0) {
int ssvalue = ssrfid.read(); // read
if (ssvalue == -1) { // no data was read
break;
}
}
for (int x = 0; x < 14; x++)
{
buffer[x] = 0;
}
multipleRead = false;
}
在附近有卡的情况下,它将清空读取器,然后将缓冲区清零。当您将卡移开时,multipleRead值将变为false,这将启动另一个RFID读取循环。
希望有帮助:)