如何用树莓派搭建一个RFID考勤系统完整项目(Raspberry Pi+python+arduino+mysql+C#)

Raspberry Pi 已经出到3B+版本了,看到后随即入手了一个,刚好赶上学校课程要求做一个有关RFID的项目,于是这个小玩意就有了用武之处,我们的目标就是搭建一个完整的RFID考勤系统项目,

这个项目必须拥有能对RFID卡进行识别读取,并且联网和数据库进行交互,有相应的WINDOWS下的GUI界面可以直观的看到我们的结果

(说做就做,马上淘宝下单买部件,现在初始开发阶段想到什么买什么,不会什么学什么2018.12.14)

使用的硬件:

1.Raspberry Pi (3B+)

2.ESP8266 开发板

3.RC522 RFID射频模块

4.有源峰鸣器

5.LED 3色模块

6.跳线和S50卡(这里用复旦卡)

使用的软件:

1.Raspbian OS(树莓派原生系统)

2.Arduino IDE (这种跨平台的东西,哪个平台都一样)

3.python 2.7     (与上同理)

4.My SQL Database(数据库)

5.Visual Studio 2017(C#用于编制GUI界面)

前期准备:

1.硬件设计:

我们需要让他利用树莓派运行arduino和python,当RFID卡扫描时可以让蜂鸣器滴一声,并且读取时候LED灯由初始红灯变成黄灯,读取成功后变成绿灯

所以我们需要一个蜂鸣器(有源),3色LED模块一个,ESP开发板(有这个你才能用arduino),还有我们的RFID模块(RC522),当然树莓派和跳线还有空卡自不用说

(树莓派后续可以做数据库的脚本操作和一些显示交互)

2.数据库的设计

由于硬件在运输途中,正好赶上双12,所以有点慢,我们先把数据库给构建出来

数据库设计图:

其中ID为唯一标识ID,RFIDNUM为卡号/工号/学号(爱怎么叫都行)NAME为姓名flag为签到标志位,如果你不知道这个表项的作用关注后续就明白了,如果你愿意还可以加上SEX(性别)

数据库之前设计的字段太少了,后面又补充了一些,旧图删了上新图(2018.12.21)

3.服务器搭建

我们有许多智能化的运维工具,利用他们方便我们更好的搭建服务器,这里我们选用宝塔控制面板(请根据不同系统敲)

Centos安装命令:

yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh

Ubuntu/Deepin安装命令:

wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh

Debian安装命令:

wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh

Fedora安装命令:

wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh

4.创建数据库

用宝塔界面创建数据库是一个非常简单的事情,这里我们就不多说,详情自行百度,面板创建好后记得安装phpadmin和mysql,然后根据我们步骤2的设计,构建我们的数据库即可(记得要放行3306端口,这不是废话嘛,不放行怎么连接,但总有萌新要连不放,我这里还是提醒一下)

结果如图:

5.配置开发环境和接线

硬件终于陆陆续续来了(2018.12.16)

现在我们拥有了一大堆模块,但是没有写程序,他们什么都做不了,下面开始写硬件的程序

我们下载安装Arduino IDE并在首选项中设置附加开发板管理目录以便我们导入ESP8266的开发板

https://github.com/esp8266/Arduino/releases/download/2.5.0-beta1/package_esp8266com_index.json

然后打开工具-开发板管理器-搜索ESP8266(可能会自动更新源比较慢等一会)

然后安装

安装后重启一下,切换开发板到WIFIduino(就是这么坑爹这是第一个坑别选错了,不然串口传不了程序噢)

接线图为:

6下面我们开始初步调试程序:

ESP8266开发板程序

根据社区的资料和官方的库文件,记得导入RFID的头文件噢(头文件点击这里下载rfid.h)

我们写了如下代码:


/*

(0 0)
+=============oOO====(_)================+
| By Linmb – www.linmb.com |
| Phone:15006008002 |
| Creation:2018.12.16 |
+==========================oOO==========+
|||
|| ||
ooO Ooo

/
#include <RFID.h>
/
Include the standard Arduino SPI library /
#include <SPI.h>
/
导入SPI库 /
#include <RFID.h>
/
定义引脚. /
#define SDA_DIO 2
#define RESET_DIO 15
RFID RC522(SDA_DIO, RESET_DIO);
void setup()
{
Serial.begin(9600);
SPI.begin(); /
开启SPI接口波特率为9600 /
RC522.init(); /
读卡器初始化 */
}

void loop()
{
/* 如果卡被读取 */
if (RC522.isCard())
{
RC522.readCardSerial(); //读取序列号
Serial.print(“卡号为:”);
for(int i=0;i<5;i++)
{
Serial.print(RC522.serNum[i],DEC); //十进制5次循环输出完整卡号
//Serial.print(RC522.serNum[i],HEX); //十六进制输出卡号
}
Serial.print(“\n”);

Serial.print(“卡类型为: “);
Serial.print(“S50”);
Serial.println(” “);
}
delay(1000);
}


7.进一步调试程序

我们把程序编译然后写入开发板(如果你开发板没选对,就会报错,我已经花了很多时间排查这个bug的原因,希望你不要再一次浪费时间,上面已经和你说了如何选择)

顺利写入!

8.再次出现问题

测试一下传参,将射频卡(这里用的是S50复旦卡)放入发现不论如何都无法返回值,程序再三检查确定无误,开发板和射频模块指示灯都正常

发现问题点:由于模块共有6个SPI接线,金手指很大可能存在虚触(即3.3V和GND成功连接,但是数据部分没有正常连接)OK我们进行手工焊锡

9.手工焊锡

一年多前做了一个太阳能充电器和温度报警装置,有点手生了但没事咱们理工男拿起电烙铁就是焊

OK完成了(焊技勿喷,我不是电工.)

10.再次测试

插上面包板(这个时候就不存在有些针脚虚触的情况了)

再写一遍程序

卡片放上去(有反应了!)

每放上去一次S50卡就返回一次参数

OK到这里我们能看到返参了,这样我们就可以下一步写python的脚本了

(太累了,今天先到这,不写了明天再写,未完待续2018.12.17)

11.进一步增加功能

单纯的读卡功能太单一,用户无法直观的了解卡读取的状态,我们添加LED和蜂鸣器来解决这一个问题

读卡提示声

蜂鸣器:我们用MH-FMG有源蜂鸣器来解决这个问题

这是一个高电平触发的蜂鸣器,我们只需要在I/O給他一个高电平,他就会鸣叫了(如果你是无源蜂鸣器记得要有方波驱动才能响噢)

GND接地,VCC接3.3V然后我们找一个I/O口给他.

看了一下就给他开发板最旁边的2个和D8(GPIO15引脚)

在前面程序中适当的位置写入以下程序


void setup(){

digitalWrite(biPin, LOW); /* 蜂鸣器电平置为低电平 */

}

void loop()
{

digitalWrite(biPin, HIGH);
delay(150); //蜂鸣器响0.15s
RC522.readCardSerial(); //读取序列号
digitalWrite(biPin, LOW);//关闭蜂鸣器

}


OK成功了,现在已经实现了读卡提示声

演示视频:


读卡提示灯

LED灯:为了简介我们这里直接买了LED3色模块(这个模块自带了电阻,如果你是单独的发光二极管那问题也不是很大,但记得加电阻保护二极管噢)

我们还是要给他找3个引脚,我们看到开发板上面D1-D3(D0和开发板小灯绑定一块)刚好3个连续的直接给他(R-D1,G-D2,B-D3)GND怎么高兴怎么来

(非常蛋疼,卖家给我少发货了导致这步做不了,又得等2天了2018.12.18)

OK,终于到货了我们开始做

模块模样:

为了让他更亮些,我们先制定一套计划,开机的时候先让他亮红色程序读取完毕后亮绿色,读取过程中绿灯交替闪烁(在蓝红灯亮的情况下)

那我们开始写程序

为了让主程序跟简洁一些定义一个类是必须,不过这么小的程序有时候还是想省事,后面就不写注释了,简单繁琐


/读写时蜂鸣器和LED灯过程/

void readerled(){
digitalWrite(ledBulePin, LOW);
digitalWrite(biPin, HIGH);
digitalWrite(ledGreenPin, HIGH);
delay(130);
}


/初始化时灯和蜂鸣器的变化/

void initled(){
pinMode(biPin, OUTPUT);
pinMode(ledRedPin, OUTPUT);
pinMode(ledGreenPin, OUTPUT);
pinMode(ledBulePin, OUTPUT);
digitalWrite(biPin, HIGH); //响
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledBulePin, HIGH);
delay(350);
digitalWrite(biPin, LOW);//关闭蜂鸣器
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBulePin, LOW);
digitalWrite(ledRedPin, HIGH);
delay(150);
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, HIGH);
delay(150);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBulePin, HIGH);
delay(150);
digitalWrite(ledBulePin, LOW);
delay(150);
digitalWrite(biPin, HIGH);
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledBulePin, HIGH);
delay(200);
digitalWrite(biPin, LOW);//关闭蜂鸣器
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBulePin, LOW);
delay(100);
digitalWrite(biPin, HIGH);
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledBulePin, HIGH);
delay(200);
digitalWrite(biPin, LOW);//关闭蜂鸣器
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBulePin, LOW);
}


程序添加到主循环部分相应的地方即可

下面我们看看效果,唔是有点样子出来了,那么在硬件上的程序就已经全部写完了,从一坨没有感情的芯片模块已经进化成RFID考勤系统装置了

上个图片:

再上个效果视频:

12.C#数据库GUI窗体前端设计

C#的前端也可以开始做了,现在就初步做了个前端数据库部分还不完善,先做2个窗体吧,关键部分还有待完善.

效果图1:

效果图2:

总体来说今天进度还是增进了不少,至少硬件上的开发已经全部结束.

我们看看还剩下多少目标进度:

1.一个Python来交付数据给数据库,

2.一个WINDOWS的应用窗体来管理和查看

(今天宿舍来了只猫,和猫玩了一下午,进度是凌晨做的也算是过了惬意的一天,明天还有早课就先到这里.2018.12.19)

13.Python 部分

python是很好的一种跨平台语言,我们这次采用python作为脚本语言来帮助我们实现与数据库的交互

有心要做的话,干脆连同CLI里的可视化回参也做了,所以让自己更加累了

python的Mysql真的是坑,有一个语句格式找了整个百度还是都是错的(真的是坑人),但你不用担心,我已经找到答案了,我写的代码都是正确的,所以在关键时候还是谷歌靠谱(真的不知道他们都是怎么用数据库的)

写代码过程还是毕竟累的,写了2天,就懒得再写如何写的,直接上代码了(这个程序部分也懒得写注释了)


/*

(0 0)
+=============oOO====(_)================+
| By Linmb – www.linmb.com |
| Phone:15006008002 |
| Creation:2018.12.16 |
+==========================oOO==========+
|||
|| ||
ooO Ooo

*/

#!/usr/bin/python
#coding:utf-8
import serial
import time
import MySQLdb
#配置数据库实例
dbConn=MySQLdb.connect(‘45.76.99.98′,’lmb’,’123456′,’rfidesp’,3306,charset=’utf8′)
device=”””/dev/ttyUSB0″””
while True:
try:

print “——————————————-“
print “连接串口中…..”,device
time.sleep(0.2)
print “……..”
time.sleep(0.2)
print “……..”
time.sleep(0.2)
print “……..”
time.sleep(0.2)
arduino=serial.Serial(device,9600)
print “连接成功!!!”
print “\n\n\n正在进入系统……..”
time.sleep(0.1)
print “……..”
time.sleep(0.1)
print “……..”
time.sleep(0.1)
print “……..”
time.sleep(0.1)
print “……..”
time.sleep(0.1)
print “……..”
time.sleep(0.1)
print “……..”
time.sleep(0.6)
print “……..”,”成功!”
time.sleep(0.5)
print “\n\n\n\n”
print “\n”
print “—————————————————“
print “欢迎使用福建工程学院出勤系统”
print “等待读卡…….”
print “\n\n\n\n\n\n\n\n\n\n\n”
break
except:
print”连接失败!!!(2s后重试……)”,device
time.sleep(0.5)
print “……..”
time.sleep(1)
print “……..”
time.sleep(1)
continue
while True:
try:
data=arduino.readline() #从串口读取数据
print data
pieces=data.split(“: “) #分割符划分数据段”’
piecesint=int(pieces[1])
print”读取卡片信息………”
time.sleep(0.2)
print”…….”
time.sleep(0.2)
print”…….”
time.sleep(0.2)
print”…….”
time.sleep(0.2)
print”…….”
cursor=dbConn.cursor()
cursor.execute(“””SELECT STUDENTNAME,STUDENTID,SEX,FLAG FROM rfesp WHERE RFIDNUM=%s”””,[piecesint])
time.sleep(0.5)
print “读取成功”
results = cursor.fetchall()
for row in results:
name = row[0]
studentid=row[1]
SEX=row[2]
FLAG=row[3]
display=data.split(” “) #分割符划分数据段
print “——————–“
print “信息如下:\n”
print “学 号:”,studentid,”\n姓 名:”,name,”\n性 别:”,SEX,”\n状 态:”,FLAG,”\n”
print “——————–\n”
try:
print “卡ID:”,piecesint
print”数据库写入中……”
cursor.execute(“””UPDATE rfesp SET FLAG=’出勤’ WHERE RFIDNUM = %s “””,[piecesint])
time.sleep(0.1)
dbConn.commit()#执行语句
cursor.close()
print “签到成功,状态已更新!!!\n当前状态:出勤”
except MYSQLdb.IntegrityError:
cursor.close()
print”数据库信息写入失败!!!”
finally:
cursor.close() # 关闭数据库实例

except:
print”等待串口连接…….”


今天给RFID做了个简易的小盒子,这样就不是电路板暴露在外面了,其实有心的话可以定制一个3D打印盒子就可以当成一个产品拿出去展示了

现在python也写好了,他已经可以帮我们实现打卡的交互,最基本的刷卡后,签到功能也实现了,并且还可以在树莓派上显示出用户的信息,体验感MAX

上个图吧:

(总结一下:今天我们做了一个小盒子,还把LED代码部分给优化了一点(现在看起来更加cool了),拖着一直没写的python部分,今天也写好了总体来说完成了很多东西进度进一步的推进了(目前就差最后的C#部分了).但是身体有些劳累想先去睡觉了毕竟现在已经是凌晨3点半,晚安2018.12.21)

来上传一个整体的效果视频:

14.C#应用程序进一步开发完善

今天迁移了服务器,而且最近花了好几天的时间优化我的网站,从原先的加载12s-15s现在基本都能在2s内加载完,优化真的是累….(2018.12.29)

好进入正题

我们在实况列表的右边又做了信息读取,现在可以点击学生的名字,照片等信息

我们还需要加入一个,查询特定学号学生的功能

6 Comments

  1. 凡人退散 says:

    很好解决了我的问题,谢谢博主

    1. 不用谢

  2. Ich bin beeindruckt, ich muss zugeben. Wirklich selten sollte ich einem weblog begegnen, das sowohl lehrreich als auch unterhaltsam ist, und lass mich dir sagen, du hast vielleicht den Nagel über den Kopf geschlagen. Ihre Idee ist hervorragend, das problem ist ein element, über das nicht genügend Menschen intelligent sprechen. Ich freue mich sehr, dass wir das bei meiner Suche nach etwas damit erfahren haben.

    1. what are u talking about ?

  3. 大神好,请问mysql需不需要写语句,还是最后的Python自动生成库

    1. Mysql并不是Python自动生成的,而是手动创建的数据库与表字段,结构在第一部分已经写明,手动创建即可

发表评论

电子邮件地址不会被公开。 必填项已用*标注