首页 LMVE论坛 资讯 插画 时光机 我的社区 用户 搜索

[Arduino]DIY饭卡锁

无闻风
发表于 2019-06-27 13:46:28
0
128

正常开柜子的姿势一般是:用钥匙插进钥匙孔还要扭一下才能开,锁上的时候又要扭一下,多麻烦。。 而我比较懒。。我拿出饭卡在感应器上刷一下,锁开了,一关门自动上锁。

首先是硬件接线: 先是RC 522的接线

默认的spi没什么好说的

 

然后是led指示灯的接线

输出低电平亮

(读到匹配的卡亮绿灯,否则闪红灯,录入卡的时候亮蓝灯,删除卡的时候亮红灯)

再到按钮的接线

(我知道我画的很丑–。) 按钮很简单,就两个按钮,蓝色的是录入按钮,红色是删除按钮。 对了,录入的信息是保存在eeprom里面的,所以断电也能保存。 但是eeprom的容量只有512字节(听说是 –。)所以我设定是只能保存128张卡,感觉应该够用吧,毕竟这不是服务器

最后就是舵机部分了

为什么要用一个mos管做开关呢,因为舵机特别耗电,我的柜子不能拉电源线,用的是电池,所以舵机工作完成后就要把它的电断掉。 经过测试整体待机电流80毫安左右,用10000毫安时的电池,大约可以工作100小时左右,就是4、5天

 

在编程之前需要安装一个RFID库。链接: https://pan.baidu.com/s/1gfceerx 密码: bn5y 已上传,把里面的文件夹放到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;
}

}
}

程序完成与2017年

2019年再来回顾一下当年写的shi 

没用状态机(当时也没这个概念)

不遵循驼峰编程原则

最后修改 2019-06-27 13:46:28
0
128
用户评论
一起折腾