您当前位置: Arduino >  ArduinoRFID读卡器

扫描二维码,快速下载本应用说明文档(免费)

ArduinoRFID读卡器      

下载: 1  点击: 962


大小:0.11KB 价格:0.00元 更新日期:2017-09-18 开发者:小R科技
  

ArduinoRFID读卡器
    • 应用名称
    • 所属分类
    • 更新时间
    • 立即下载
    • ArduinoRFID读卡器
    • Arduino
    • 2017-09-18
【ArduinoRFID读卡器】 应用介绍

                                ArduinoRFID读卡器

很随意的从tb买了个RF读卡模块,串口的,准备以后加在饮水机上或者改良一下考勤机。
公司的考勤卡都是125k的ID卡,应该可以直接用

              

 
说明:

管脚定义:(从上到下)

GND
VCC(3-5V)
天线1
天线2
EN卡有效信号输出
TXD串口输出
RXD串口输入
性能参数:

输入电压:3~5.5V
输入电流:刷卡电流<25mA
通讯格式:9600-8-1串口输出卡号
(格式:1bit:start、8bit:data、1bit:stop)

有效刷卡高度:3-20cm(视天线、卡和周围环境而定)
使用环境:-25~70摄氏度
尺寸:28mm*20mm(mini版)

 

 
 

Arduino连接方式:

RF模块                     Arduino
1脚                            GND
2脚                            +5v
3脚  天线            
4脚  天线
5脚                            D2
6脚                            RX0
7脚                            TX0

 
 
第一版程序:
 
//RFID test by Thomas 2012.05.07
int incomingByte = 0;        // for incoming serial data
const int ENPin = 2;     // the number of the EN pin
int ENState = 1;  //default EN state was HIGH
 
void setup() {
  Serial.begin(9600);        // opens serial port, sets data rate to 9600 bps
  pinMode(ENPin, INPUT);     
}
 
void loop() {
 
  // read the state of the EN value:
  ENState = digitalRead(ENPin);
 
  // check if the EN is LOW,the output the data.
  if (ENState == LOW&&Serial.available() > 0) {     
    // read the incoming byte:
    incomingByte = Serial.read();
    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
  }
 
}

 
读出数据输出

 
 
第二版:

    本程序是在第一版原有程序的基础上进行修改的,来个传送门:thomas的程序有个小BUG,在测试的时候发现卡号并没有依次存入递增的数组下标地址中,而是重复的存入下标为0的首地址中,导致了调试的时候,不能够进行很好的有效卡号设置和匹配。奋斗了两天,把数组接收改成了字符串变量接收,调用的时候,可以以数组的形式依次调用。

comdata += char(Serial.read()) 这里最后直接输出 Serial.println(comdata) 时,输出的是ASCII码的形式,所以改成了逐个地址输出,转成了16进制。有兴趣的一起研究改进哈~

下面放代码:

const int ENPin = 2;     //使能端口
int ENState = 1;  // 初始化为高电平  
 
String comdata = ""; //定义一个字符串变量
 
char ID[4] = {0x00,0x17,0x3E,0x41};  //设置一个有效卡的卡号
  
void setup()
{
  Serial.begin(9600);
  pinMode(ENPin, INPUT);
}
void loop()
{
  // 读取使能端的电平,如果使能端为低电平,则读出卡号
  for(ENState = digitalRead(ENPin) ; ENState == LOW && Serial.available() > 0; )
  {     
     comdata += char(Serial.read());   //读出ID卡号
     delay(2);                         //加一个短延时,给单片机足够的时间读取卡号
  }
  if(comdata.length() > 0)             //如果comdata接收到卡号,则读出卡号
  {
     Serial.print(comdata[0],HEX);
     Serial.print(comdata[1],HEX);
     Serial.print(comdata[2],HEX);
     Serial.println(comdata[3],HEX);
     if(comdata[0] == ID[0] && comdata[1] == ID[1] && comdata[2] == ID[2] && comdata[3] == ID[3])
     {                                //判断读入的ID卡是否与预先设置的有效卡号匹配,匹配则输入welcome
       Serial.println("welcome");
     }
     else Serial.println("sorry,you are not allowed.");
     comdata = "";                    //清除comdata内的值
  }
}

 
第三版:

    小更新一下。这次是将卡号存在EEPROM中,通过读取,然后再进行对比。目前正在思考利用什么算法能个加快卡号匹配的速度,还用了单独的EEPROM读写程序先存储一遍卡号,通过读写的结果,因为存的是数字量,一个数就占一位了,卡号10个数,所以第二个卡号的地址从10开始写入:

#include <EEPROM.h>
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
 
unsigned long ID = 4294916953;
unsigned long ID1 = 4294917240;
unsigned long IDR = 0;
unsigned long IDR1 = 0;
 
void setup()
{
  Serial.begin(9600);
  EEPROM_write(0, ID);
  EEPROM_write(10, ID1);
  EEPROM_read(0, IDR);
  Serial.println(IDR);
  EEPROM_read(10, IDR1);
  Serial.println(IDR1);
}
 
void loop()
{
  
}

结果如下:


 
 
第四版:


    半夜不睡觉,爬起来码程序,最后优化修改过的程序,估计短时间内不会再改了,要改也要配合其他模块一起。读卡识别这部分的程序改成了for循环依次进入地址读取卡号进行匹配,正确则跳出循环,或是循环结束仍不匹配;EEPROM卡号存储改成了读卡时将卡号自行写入EEPROM,就不用人工一个一个变量的定义写入了。具体的往下看吧,欢迎拍砖~

#include <EEPROM.h>
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
 
const int ENPin = 2;     // 定义使能端的管脚
int ENState = 1;  //初始化使能端为高电平
 
void setup()
{
  Serial.begin(9600);
  pinMode(ENPin, INPUT);
}
void loop()
{
  unsigned long ID = 0;    //定义一个变量用于存储读入的ID卡号
  unsigned long IDR = 0; //定义一个变量用于存储从EEPROM读出的ID卡号
  for(ENState = digitalRead(ENPin) ; ENState == LOW && Serial.available() > 0; ) // 读取使能端的电平,判断是否为低电平,是且串口有输入,则进入循环
  {        
    ID = ID * 10 + int(Serial.read()-'0'); //读出卡号
    delay(2);                        
  }
  if(ID != 0)             //如果变量ID不为0
  {
     Serial.println(ID);      //输出读入的卡号,实际应用中考虑到安全性可不输出
     for(int addr = 0; addr <= 1020; addr = addr + 10)    //定义一个变量表示为EEPROM的地址位,UNO的EEPROM有1024B,所以这里设定地址位在小于等于1020时进入循环
     {
       EEPROM_read(addr, IDR);    //读出EEPROM中存放的ID卡号
       if(ID == IDR)                        //判断串口读入的ID卡号与EEPROM中的卡号是否匹配
       {
         Serial.println("Welcome!"); break;          //匹配则输出WELCOME,并跳出循环
       }                                                              //若不匹配,则地址位加10,进行下一卡号匹配,直到与EEPROM内存储的所有卡号对比完,均不匹配,则跳出循环
     }
     if(ID != IDR) Serial.println("Sorry,you are not allowed!");   //均不匹配,则输出SORRY
     ID = 0;                    //变量ID清0
  }
}



效果如下:


 
 
最后一版:这次只改了读卡识别的,加了个液晶显示,就不用电脑的串口监视器了,设置好,通电就能用:

#include <LiquidCrystal.h>
#include <EEPROM.h>
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
 
LiquidCrystal lcd(12, 11, 10, 9, 8, 7, 6);
int backLight = 13;
const int ENPin = 2;     // the number of the EN pin
int ENState = 1;  //default EN state was HIGH
 
void setup()
{
  Serial.begin(9600);
  pinMode(ENPin, INPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH);
  lcd.begin(16,2);
  lcd.clear();
}
void loop()
{
  unsigned long ID = 0;    //define a string variable
  unsigned long IDR = 0;
  for(ENState = digitalRead(ENPin) ; ENState == LOW && Serial.available() > 0; ) // read the state of the EN value,check if the EN is LOW,the output the data.
  {        
    ID = ID * 10 + int(Serial.read()-'0'); //read the number from IDcard
    delay(2);                        
  }
  if(ID != 0)             //if comdata gets the IDcard number,show it
  {
     lcd.setCursor(0,0);
     lcd.print("ID: ");
     lcd.print(ID);
     for(int addr = 0; addr <= 1020; addr = addr + 10)
     {
       EEPROM_read(addr, IDR);
       if(ID == IDR)
       {
         lcd.setCursor(0,1);
         lcd.print("Welcome!        "); break;
       }
     }
     if(ID != IDR)
     {
       lcd.setCursor(0,1);
       lcd.print("who you are?      ");
     }
       ID = 0;                    //clean the comdata
  }
}
 


     说下以后的想法:考勤机,一个当日过生日的员工刷考勤卡上班时,如果能给他奏上一曲《生日快乐》,是多么惬意的事情。
饮水机,做成缩小版加油机形式,刷卡饮水,记录每人用水量。(看看谁喝水太少,就应该督促一下。这个纯属无聊,公司肯定不会收水费)


网友评论仅供网友表达个人看法,并不表明 小R科技 Robots-Store机器人应用商城 同意其观点或证实其描述
昵称: 验证码: