第十五章 用RFID+MySQL实现小区门禁系统(RFID522
本系列文章为作者原创,未经作者书面同意,不得转载!
(为什么突然跳过这么多章节,开始写这一篇,主要是正好要做这么个实验,就边做边记录下来!)
现在城市的小区大多都是封闭小区,业主需要刷卡才能进入。

一般我们使用的卡片有两种形式:
-
一种是这种纽扣卡
rfid1.png
-
一种就是这种卡片式的
rfid2.png
那么您有琢磨过没有,这么一张小小的卡片就能够进行身份的识别并打开小区的大门,这是怎么实现的呢 ?今天我们就来自己设计一套门禁系统,解除您的迷惑!
今天我们的项目就是设计一套门禁模拟系统,我们选用非接触式RFID卡作为小区门禁卡,用户使用这种卡在感应器上刷卡,系统能够读取卡ID数据,然后查询小区业主数据库,如果能够查询到,说明该用户为小区业主,系统液晶屏上显示该业主姓名和欢迎语,并通过继电器打开电磁锁,如果在业主数据库中无法查询到该卡信息,则说明该用户不是小区业主,系统液晶屏上提示该卡信息不存在。
1 本章您将学习到
在这个项目中,您将学习到以下几个方面的内容:
- RFID卡的使用
- ESP8266 WiFi模块的使用
- 怎么连接数据库并实现查询
2 工具和组件
2.1 工具列表
元器件 | 型号 | 数量 | 备注 |
---|---|---|---|
电烙铁 | 30W | 1 |
2.2 元器件列表
元器件 | 型号 | 数量 | 备注 |
---|---|---|---|
主控板 | arduino MEGA 2560 | 1 | |
WiFi模块 | ESP-12F | 1 | |
RFID感应模块 | RC 522 | 1 | |
RFID卡 | 纽扣式 | 1 | |
RFID卡 | 卡片式 | 1 | |
继电器 | SRD-5VDC-SL-C | 1 | |
面包板 | 1 | ||
杜邦线 | 若干 | ||
数据线 | Uno数据线 | 1 |
2.3 工具和元器件介绍
2.3.1 烙铁
2.3.2 ESP-12F WiFi模块
我们重点介绍一下这个模块。
ESP-12F是一款超低功耗的UART-WiFi 透传模块,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能。

这个模块使用之前需要焊接到转接板上,下图是转接板:

下面两张图是焊接完成后的样子:


ESP-12F模块引脚间距是2mm的,焊接起来比较费劲。本来想采用ESP-01模块的,这个模块不需要焊接,有引脚直接可以用,不过ESP-01模块对供电要求比较高,而且Flash才8Mbit,可用引脚也比较少,可玩性跟12F差太多,所以就不推荐大家使用了,不过如果是做一个实际项目,有成本控制且只做无线透传,ESP-01就相对合适一些(其实ESP8266模块本身就是一个MCU,跟Arduino的主控板一样,也能在Arduino IDE下编程)。
2.3.2.1 产品特性
- 支持无线802.11 b/g/n 标准
- 支持STA/AP/STA+AP 三种工作模式
- 内置TCP/IP协议栈,支持多路TCP Client连接
- 支持丰富的Socket AT指令
- 支持UART/GPIO数据通信接口
- 支持Smart Link 智能联网功能
- 支持远程固件升级(OTA)
- 内置32位MCU,可兼作应用处理器
- 超低能耗,适合电池供电应用
- 3.3V 单电源供电
重点注意:最后一条,3.3V供电。
2.3.3 RFID模块
2.3.4 继电器模块
3 所需软件或服务
3.1 MySQL server
4 电路设计
4.1 电路图
4.2 电路原理
5 程序设计
5.1 类库介绍
5.1.1 .h库介绍
5.1.1.1 .h库的下载
可以在Arduino IDE中, 项目->加载库->管理库中搜索,然后点击安装即可。
5.1.1.1 .h库的介绍
...
...
5.2 主程序设计
...
/********************************
Name: 用RFID+MySQL实现小区门禁系统
Module: UNO + ESP-12N + RFID522
Author: You xianke
Version: V1.0
Init: 2018-6-22
Modify:
*******************************/
#include <WiFiEspClient.h>
#include <WiFiEsp.h>
#include <SoftwareSerial.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <IPAddress.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define RST_PIN 5
#define SS_PIN 53
#define ssid "Alpha1"
#define pass "alphak12"
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
const int RXPin = 10;
const int TXPin = 11;
const int relayPin = 6;
LiquidCrystal_I2C lcd(0x3F,16,2);
IPAddress server_addr(*.*.*.*); // 数据库服务器IP地址
char dbUser[] = "user";
char dbPassword[] = "pass";
SoftwareSerial espSerial(RXPin,TXPin);
WiFiEspClient espClient;
// int status = WL_IDLE_STATUS;
MySQL_Connection conn((Client *)&espClient);
// Create an instance of the cursor passing in the connection
MySQL_Cursor cur = MySQL_Cursor(&conn);
const char QUERY_POP[] = "SELECT NAME FROM mysqltest.RFID_access_uid WHERE uid_1 = %d AND uid_2 = %d AND uid_3 = %d AND uid_4 = %d;";
char query[128];
String userName;
bool AccessCheck(byte *buffer);
void PrintWifiStatus();
void PrintUidHex(byte *buffer, byte bufferSize);
void PrintUidDec(byte *buffer, byte bufferSize);
void setup(){
Serial.begin(9600);
espSerial.begin(9600);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH);
lcd.clear();
WiFi.init(&espSerial);
lcd.init();
lcd.backlight();
SPI.begin();
mfrc522.PCD_Init(); // Init MFRC522 card
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD){
lcd.setCursor(0,0);
lcd.print("WiFi not present");
lcd.setCursor(0,1);
lcd.print("Please check...");
// don't continue:
while (true);
}
// attempt to connect to WiFi network
while ( WiFi.status() != WL_CONNECTED) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connect to SSID:");
lcd.setCursor(0,1);
lcd.print(ssid);
lcd.print("......");
// Connect to WPA/WPA2 network
WiFi.begin(ssid, pass);
}
delay(1000);
PrintWifiStatus();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Start connect to");
lcd.setCursor(0,1);
lcd.print("DB Server...");
if (conn.connect(server_addr,3306,dbUser,dbPassword)){
delay(1000);
// Serial.println("Connected to the DB");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connected to the");
lcd.setCursor(0,1);
lcd.print("DBServer...");
}
else{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("DBServer connect");
lcd.setCursor(0,1);
lcd.print("failed.");
}
SPI.begin();
mfrc522.PCD_Init(); // Init MFRC522 card
}
void loop() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ready for read!");
// 寻找新卡
if(!mfrc522.PICC_IsNewCardPresent()){
return;
}
else{
if(!mfrc522.PICC_ReadCardSerial()){
return;
}
else{
if(AccessCheck(mfrc522.uid.uidByte)){
Serial.println("Open the door");
delay(1000);
}
else{
Serial.println("Close the door");
delay(1000);
}
}
}
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
delay(500);
}
bool AccessCheck(byte *buffer){
bool accessCheck = false;
row_values *row = NULL;
// long head_count = 0;
byte tempUid[4];
Serial.println(" ");
Serial.println("Now print the tempUid:");
for (int i = 0; i < 4; i++) {
tempUid[i] = buffer[i];
Serial.println(tempUid[i]);
}
sprintf(query, QUERY_POP, tempUid[0],tempUid[1],tempUid[2],tempUid[3]);
Serial.println(query);
// char query1[] = "SELECT NAME FROM mysqltest.RFID_access_uid WHERE uid_1 = 25;";
while(WiFi.status() != WL_CONNECTED){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connect to SSID:");
lcd.setCursor(0,1);
lcd.print(ssid);
lcd.print("......");
// Connect to WPA/WPA2 network
// status = WiFi.begin(ssid, pass);
WiFi.begin(ssid, pass);
delay(1000);
}
Serial.print("WiFi status is:");
Serial.println(WiFi.status());
while(!conn.connected()){
if (conn.connect(server_addr,3306,dbUser,dbPassword)){
delay(1000);
}
else{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("DBServer connect");
lcd.setCursor(0,1);
lcd.print("failed.");
Serial.println("DBServer connect failed.");
delay(1000);
}
}
Serial.print("DB connecting status is:");
Serial.println(conn.connected());
cur.execute(query);
// Fetch the columns
cur.get_columns();
do {
row = cur.get_next_row();
if (row != NULL) {
userName = row->values[0];
accessCheck = true;
}
} while (row != NULL);
// // Now we close the cursor to free any memory
// cur.close();
if (accessCheck) {
Serial.print("UserName: ");
Serial.println(userName);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Welcome to HOME!");
lcd.setCursor(0,1);
lcd.print(userName);
digitalWrite(relayPin, LOW); //开门操作
delay(1000);
digitalWrite(relayPin, HIGH);
}
else{
Serial.println("The query result is NULL!");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Your card is");
lcd.setCursor(0,1);
lcd.print("invalid......");
delay(1000);
}
return accessCheck;
}
void PrintWifiStatus(){
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void PrintUidHex(byte *buffer, byte bufferSize){
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
* Helper routine to dump a byte array as dec values to Serial.
*/
void PrintUidDec(byte *buffer, byte bufferSize){
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], DEC);
}
}
...
6 安装调试




7 总结扩展
(持续更新中,敬请期待!)
如果您喜欢本文,您可以点击一下下面的喜欢按钮,您也可以关注我,谢谢您的支持!