正常开柜子的姿势一般是:用钥匙插进钥匙孔还要扭一下才能开,锁上的时候又要扭一下,多麻烦。。 而我比较懒。。我拿出饭卡在感应器上刷一下,锁开了,一关门自动上锁。
首先是硬件接线: 先是RC 522的接线
默认的spi没什么好说的
然后是led指示灯的接线
输出低电平亮
(读到匹配的卡亮绿灯,否则闪红灯,录入卡的时候亮蓝灯,删除卡的时候亮红灯)
再到按钮的接线
(我知道我画的很丑–。) 按钮很简单,就两个按钮,蓝色的是录入按钮,红色是删除按钮。 对了,录入的信息是保存在eeprom里面的,所以断电也能保存。 但是eeprom的容量只有512字节(听说是 –。)所以我设定是只能保存128张卡,感觉应该够用吧,毕竟这不是服务器
最后就是舵机部分了
为什么要用一个mos管做开关呢,因为舵机特别耗电,我的柜子不能拉电源线,用的是电池,所以舵机工作完成后就要把它的电断掉。 经过测试整体待机电流80毫安左右,用10000毫安时的电池,大约可以工作100小时左右,就是4、5天
在编程之前需要安装一个RFID库,把里面的文件夹放到arduino ide安装目录下的libraries文件夹就可以了
开源代码:
程序为4.2版 加入红外线开门、关门检测。检测解锁后会等待开门,开门后会等待关门,如此循环。
#include
#include
#include
#include
#define gled 2
#define rled 3
#define bled 4
#define key 6 //蓝色按钮(录入卡片)
#define key2 7 //红色色按钮(删除卡片)
#define kg 9 //舵机电源驱动
//D10 – 读卡器CS引脚、D5 – 读卡器RST引脚
RFID rfid(10,5);
void huodeshuju(char a);
void jieshou();
void jilu();
void shanchu();
unsigned char yanzhengka();
void kaisuo();
void shangsuo();
//4字节卡序列号,第5字节为校验字节
unsigned char da[7];//取卡的8位数据
unsigned char jl[50][8];//从eeprom获取已记录的数据
unsigned char zong;//卡的总数 储存在eeprom的401地址
unsigned char ckjieshou[4];
Servo myservo; //创建一个舵机控制对象
void setup()
{
Serial.begin(9600);
myservo.attach(8); // 该舵机由arduino第8脚控制
SPI.begin();
rfid.init();
pinMode(gled, OUTPUT);
pinMode(rled, OUTPUT);
pinMode(bled, OUTPUT);
pinMode(kg, OUTPUT);//舵机驱动
pinMode(key, INPUT_PULLUP);
pinMode(key2, INPUT_PULLUP);
digitalWrite(gled, 1);
digitalWrite(rled, 1);
digitalWrite(bled, 1);
//********************************
Serial.print(“**********************”);
Serial.println(“”);
Serial.print(“* 卡片解锁器 *”);
Serial.println(“”);
Serial.print(“*使用方法: *”);
Serial.println(“”);
Serial.print(“*按一次蓝色按钮录入卡片*”);
Serial.println(“”);
Serial.print(“*按一次红色按钮删除卡片*”);
Serial.println(“”);
Serial.print(“*程序编写: *”);
Serial.println(“”);
Serial.print(“*中山市技师学院家电系:*”);
Serial.println(“”);
Serial.print(“*吴文峰 *”);
Serial.println(“”);
Serial.print(“*程序版本:4.2 *”);
Serial.println(“”);
Serial.print(“**********************”);
Serial.println(“”);
//*******************************
//xingchusuoyou();//清除eeprom全部数据
huodeshuju(1);//从eeprom获得数据 并发送
//fasonghuodeshuju();//发送获得的数据
}
void loop()
{
//Serial.print(analogRead(A0));
//Serial.println(“”);
unsigned char kaxuhao;
jieshou();
if(digitalRead(key)==0)
{
jilu();
}
if(digitalRead(key2)==0)
{
shanchu();
}
rfid.findCard(PICC_REQIDL, da);//防冲突检测,读取卡序列号
if (rfid.anticoll(da) == MI_OK)
{
for(char i = 0; i < 8; i++)
{
Serial.print(da[i],HEX);
}
kaxuhao=yanzhengka();
Serial.print(“:”);
Serial.print(kaxuhao);
Serial.println(“”);
//从这里开始验证 卡是否存在
if(kaxuhao>0)
{
digitalWrite(gled, 0);
kaisuo();
//delay(1500);
while(analogRead(A0)<32);//等待开门
digitalWrite(gled, 1);
while(analogRead(A0)>32)//等待关门 等待时可以录入或删除
{
//jieshou();
if(digitalRead(key)==0)
{
jilu();
}
if(digitalRead(key2)==0)
{
shanchu();
}
}
digitalWrite(gled, 0);
delay(100);
if(zong==0)//这里可能删除过卡 要再验证一次是否没卡了
{
kaisuo();
}
else
{
shangsuo();
}
digitalWrite(gled, 1);
}else
{
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
}
}
}
void shangsuo()
{
digitalWrite(kg, 1);//打开舵机驱动
myservo.write(90); // 指定舵机转向的角度 90上锁
delay(2000);
digitalWrite(kg, 0);//关闭舵机驱动
}
void kaisuo()
{
digitalWrite(kg, 1);//打开舵机驱动
myservo.write(40); // 指定舵机转向的角度 40开锁
delay(1000);
digitalWrite(kg, 0);//关闭舵机驱动
}
unsigned char yanzhengka()
{
unsigned char i=0,j;
unsigned int l=0;
while((EEPROM.read(l)!=0))
{
if(da[0]==EEPROM.read(l)&&da[1]==EEPROM.read(l+1)&&da[2]==EEPROM.read(l+2)&&da[3]==EEPROM.read(l+3)&&da[4]==EEPROM.read(l+4)&&da[5]==EEPROM.read(l+5)&&da[6]==EEPROM.read(l+6)&&da[7]==EEPROM.read(l+7))
{break;}
else
{i++;l+=8;}
}
if(i==zong)
{j=0;}
else
{
j=i+1;
}
return j;
}
/*
void fasonghuodeshuju()
{
unsigned char i=0,j;
while((jl[i][0]!=0))
{
for(j=0;j<8;j++)
{
Serial.print(jl[i][j],HEX);
}
Serial.println(“”);
i++;
}
}
*/
void huodeshuju(char a)//从eeprom获得数据
{
unsigned int i=0,k=0;
Serial.print(“*********EEPROM DATA**********”);
Serial.println(“”);
while((EEPROM.read(i)!=0))
{
if(a==1)
{
for(char j=0;j<8;j++)
{
Serial.print(EEPROM.read(k*8+j),HEX);
}
i+=8;
k+=1;
Serial.print(“:”);
Serial.print(k);
Serial.println(“”);
}else
{
i+=8;
k+=1;
}
}
zong=k;
Serial.print(“****************************”);
Serial.println(“”);
Serial.print(“quantity:”);
Serial.print(zong);
Serial.println(“”);
Serial.print(“****************************”);
Serial.println(“”);
if(zong==0)//如果一张卡都没有 保持开锁
{
digitalWrite(gled, 0);
kaisuo();
}else
{
digitalWrite(gled, 1);
//shangsuo();
}
}
void xingchusuoyou()
{
for(unsigned int i=0;i<1024;i++)
{
EEPROM.write(i,0x00);
}
}
void jilu()
{
unsigned char a=100;
unsigned int j;
j=zong;
j=j*8;
while(a–)
{
digitalWrite(bled, 0);//点亮蓝灯
rfid.findCard(PICC_REQIDL, da);
//防冲突检测,读取卡序列号
if (rfid.anticoll(da) == MI_OK)
{
if(zong==127)//如果卡的总数到了127上限
{
digitalWrite(rled, 0);
digitalWrite(gled, 0);
digitalWrite(bled, 0);
delay(1000);
digitalWrite(rled, 1);
digitalWrite(gled, 1);
digitalWrite(bled, 1);
}else
{
if(yanzhengka()==0)//如果卡不存在 开始记录
{
for(char i = 0; i < 8; i++)
{
EEPROM.write(j, da[i]);
j++;
}
//EEPROM.write(401, zong+=1);//记录完成后卡的数量加一
a=0;
huodeshuju(0);
}else
{
digitalWrite(gled, 0);
delay(100);
digitalWrite(gled, 1);
delay(100);
digitalWrite(gled, 0);
delay(100);
digitalWrite(gled, 1);
delay(100);
digitalWrite(gled, 0);
delay(100);
digitalWrite(gled, 1);
delay(100);
a=0;
}
}
}
}
digitalWrite(bled, 1);
}
void shanchu()
{
unsigned char a=100;
unsigned int j=0,k=0,m=0;
while(a–)
{
digitalWrite(rled, 0);//点亮红灯
rfid.findCard(PICC_REQIDL, da);
//防冲突检测,读取卡序列号
if (rfid.anticoll(da) == MI_OK)
{
if(yanzhengka()>0)//如果卡存在 开始删除
{
j=yanzhengka();
j=j-1;
j=j*8;
k=yanzhengka();//为排版使用的变量
m=zong-yanzhengka();
m=m+1;
m=m*8;
k=k*8;
for(char i = 0; i < 8; i++)
{
EEPROM.write(j,0);
j++;
}
//到这里已经删除完成 需要排版
while(m–)//开始排版
{
EEPROM.write(k-8,EEPROM.read(k));
k++;
}
//EEPROM.write(401, zong-=1);//删除完成后卡的数量减一
a=0;
huodeshuju(0);
}else
{
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
a=0;
}
}
}
digitalWrite(rled, 1);
}
void zhidingshanchu(unsigned char xh)
{
unsigned int j=0,k=0,m=0;
digitalWrite(rled, 0);//点亮红灯
if(xh>127)
{
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
digitalWrite(rled, 0);
delay(100);
digitalWrite(rled, 1);
delay(100);
}else
{
j=xh;
j=j-1;
j=j*8;
k=xh;//为排版使用的变量
m=zong-xh;
m=m+1;
m=m*8;
k=k*8;
for(char i = 0; i < 8; i++)
{
EEPROM.write(j,0);
j++;
}
//到这里已经删除完成 需要排版
while(m–)//开始排版
{
EEPROM.write(k-8,EEPROM.read(k));
k++;
}
//EEPROM.write(401, zong-=1);//删除完成后卡的数量减一
huodeshuju(0);
digitalWrite(rled, 1);
}
}
void jieshou()
{
unsigned char hcshu;
if(Serial.available()>0)
{
for(char i=0;i<5;i++)
{
ckjieshou[i]=Serial.read();
}
Serial.flush();
if(ckjieshou[0]==’D’&&ckjieshou[1]==’E’&&ckjieshou[2]==’L’)
{
if(ckjieshou[4]==0xff)
{
ckjieshou[3]=char (ckjieshou[3]);
ckjieshou[3]=ckjieshou[3]-48;
hcshu=ckjieshou[3];
}else
{
ckjieshou[3]=char (ckjieshou[3]);
ckjieshou[3]=ckjieshou[3]-48;
ckjieshou[4]=char (ckjieshou[4]);
ckjieshou[4]=ckjieshou[4]-48;
hcshu=ckjieshou[3];
hcshu=hcshu*10;
hcshu=hcshu+ckjieshou[4];
}
if(hcshu>0&&hcshu<128)
{
digitalWrite(rled, 0);
zhidingshanchu(hcshu);
//Serial.print(hcshu);
//Serial.println(“”);
Serial.print(“OK”);
Serial.println(“”);
digitalWrite(rled, 1);
}
}
for(char i=0;i<4;i++)
{
ckjieshou[i]=0;
}
}
}