文章首发及后续更新:https://mwhls.top/4066.html,无图/无目录/格式错误/更多相关请至首发页查看。
新的更新内容请到mwhls.top查看。
欢迎提出任何疑问及批评,非常感谢!
带联网功能的RFID宿舍门禁
两年后又来了次总结,为什么总结?因为有门课能拿它来扯
| ESP8266 |
|---|
| WiFi 模块 |
![]() |
#include // 本程序使用 ESP8266WiFi库
#include // ESP8266WebServer库ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server// 括号中的数字是网路服务器响应http请求的端口号// 网络服务器标准http端口号为80,因此这里使用80为端口号
#define WIFISSID "ESP8266Web" //设定ESP8266 wifi名称
#define WIFIPSSD "123456789" //设定wifi密码void setup(void){Serial.begin(115200); // 启动串口通讯setAP(); // 设定AP模式,并建立热点。//--------"启动网络服务功能"程序部分开始-------- // 此部分为程序为本示例程序重点1esp8266_server.begin(); // 详细讲解请参见太极创客网站《零基础入门学用物联网》esp8266_server.on("/", handleRoot); // 第3章-第2节 ESP8266-NodeMCU网络服务器-1esp8266_server.onNotFound(handleNotFound);
//--------"启动网络服务功能"程序部分结束--------Serial.println("HTTP esp8266_server started");// 告知用户ESP8266网络服务功能已经启动
}void loop(void){esp8266_server.handleClient(); // 处理http服务器访问
}void setAP(){WiFi.mode(WIFI_AP); // AP模式设定WiFi.softAP(WIFISSID,WIFIPSSD); // WIFI热点建立Serial.printf("Success!\nWIFISSID: %s \nWIFIPSSD: %s \nControlWeb: ", WIFISSID, WIFIPSSD); // 输出相关信息Serial.println(WiFi.softAPIP()); // 输出网站地址
}void handleRoot() { //处理网站根目录“/”的访问请求 esp8266_server.send(200, "text/plain", "ESP8266 WEB CONTROL PAGE.\n -mwhls.top"); // NodeMCU将调用此函数。
}// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){ // 当浏览器请求的网络资源无法在服务器找到时,esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。
}
| SG90 9克舵机 | MFRC522 | Arduino Nano V3 CH340G |
|---|---|---|
| 拉动门锁 | RFID 模块 | 开发板 |
| [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6caYNNGM-1668948818342)(https://s2.loli.net/2022/11/19/dY6JlMwk4hFr5SC.jpg)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVdDid9L-1668948818343)(https://s2.loli.net/2022/11/19/nhprZLk5HwyXsue.jpg)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aW3eCrI7-1668948818343)(https://s2.loli.net/2022/11/19/Je8Y61B3zwfNPp9.jpg)] |
| Arduino Nano V3 CH340G | SG90(颜色) | RC522(顺序) |
|---|---|---|
| GND | GND (棕) | |
| 5V | 5V (红) | |
| D8 | PWM信号 (黄) | |
| D9 | RST (2) | |
| D10 | SDA (8) | |
| D11 | MOSI (6) | |
| D12 | MISO (5) | |
| D13 | SCK (7) | |
| 3V3 | 3.3V (1) | |
| GND | GND (3) |
#include
#include #define SS_PIN 10
#define RST_PIN 9
#define SERVO_PIN 8
#define USER_NUM 3byte servoRun = 0; // 舵机是否运行。
MFRC522 rfid(SS_PIN, RST_PIN); // 实例化类
byte userCard[USER_NUM][4] = { // 通行卡存储数组。{28, 184, 119, 33},{249, 231, 71, 179},{109, 242, 234, 235}
};void setup() { Serial.begin(9600); // 波特率设置SPI.begin(); // 初始化SPI总线rfid.PCD_Init(); // 初始化 MFRC522 pinMode(SERVO_PIN, OUTPUT); // 舵机控制端口
}void loop() {if(servoRun == 1){ // 舵机运行变量若为1,则运行。servoControl(); // 舵机控制函数。}if ( ! rfid.PICC_IsNewCardPresent()) return; // 找卡if ( ! rfid.PICC_ReadCardSerial()) return; // 验证NUID是否可读MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && // 检查是否MIFARE卡类型piccType != MFRC522::PICC_TYPE_MIFARE_1K &&piccType != MFRC522::PICC_TYPE_MIFARE_4K) {Serial.println("Can identify this card!");return;}byte i;for (i=0; i // 判断卡是否为通行卡。byte i2;for(i2=0; i2<4; i2++){ // 遍历userCard中所有卡。if(rfid.uid.uidByte[i2] != userCard[i][i2]) break; // break时,表示此卡不是通行卡。}if(i2 == 4){ // i2为4,表示此卡的四位值都验证通过。Serial.println("Find an accessful card."); // 输出成功信息。servoRun = 1; // 将开门变量置1。break; // 已找到通行卡,跳出循环。}}if(i==USER_NUM){ // 若i等于通行用户数量,则上层循环未找到通行卡。Serial.print("Find a unknown card, its uid:");for(i=0; i<4; i++){ // 输出此卡UID。Serial.print(rfid.uid.uidByte[i], DEC);Serial.print(" ");}Serial.println();}rfid.PICC_HaltA(); // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡rfid.PCD_StopCrypto1(); // 停止读卡模块编码}void servoControl(){ // 舵机控制函数。Serial.println("Servo run!"); // 函数运行输出标识。servoPulse(0); // 舵机转至0度。delay(1000); // 等待舵机运转。servoPulse(180); // 舵机转至180度。servoRun = 0; // 舵机运行变量置零。
}void servoPulse(int myangle) // 定义一个脉冲函数,作者:https://blog.csdn.net/sss_369/article/details/52894347
{int pulseWidth=(myangle*11)+500;// 将角度转化为500-2480 的脉宽值digitalWrite(SERVO_PIN,HIGH); // 将舵机接口电平至高delayMicroseconds(pulseWidth); // 延时脉宽值的微秒数weimiaodigitalWrite(SERVO_PIN,LOW); // 将舵机接口电平至低delay(20-pulseWidth/1000);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1EDh35rl-1668948818343)(https://s2.loli.net/2022/11/19/F78BNYIXUZ6Wcmr.jpg)]
| 名称 | 用途 | 数量 |
|---|---|---|
| Arduino Nano V3 CH340G 及配套数据线 | 开发板 | 1 |
| MFRC522 | RFID 模块 | 1 |
| NodeMCU(ESP8266 CH340串口) 及配套数据线 | WiFi 模块 | 1 |
| SG90 | 舵机 | 1 |
| 母对母杜邦线 | 导线 | 13 |
| 公对公杜邦线 | 导线 | 3 |
| 支持微电流的两万毫安小米充电宝 | 电源 | 1 |
| Arduino Nano V3 CH340G(引脚) | NodeMCU(引脚) | RC522(顺序) | SG90(颜色) |
|---|---|---|---|
| GND | GND | ||
| A4 | D1 | ||
| A5 | D2 | ||
| D9 | RST (2) | ||
| D10 | SDA (8) | ||
| D11 | MOSI (6) | ||
| D12 | MISO (5) | ||
| D13 | SCK (7) | ||
| 3V3 | 3.3V (1) | ||
| GND | GND (3) | ||
| 5V | 5V(红) | ||
| D8 | PWM信号(黄) | ||
| GND | GND (棕) |
/* 作者:MWHLS,主页MWHLS.TOP* 链接:http://mwhls.top/?p=659* 因为使用的不是SERVO.H库,舵机的PWM控制端口并不局限于9/10两个端口,且也不局限于仅控制两个舵机。* 通行卡的存储使用二维数组,将卡的UID转为十进制保存。* 卡的对比使用for函数遍历二维数组,对比UID是否相同。* 舵机启动由舵机控制变量servoRun控制,若值为1,则启动,其余不运行。* 接受到NodeMCU传来的信号时,舵机控制变量置1。* 发现通行卡时,舵机控制变量置1。* 参考文章:* 网页控制:https://blog.csdn.net/qq_46292418/article/details/106605366* I2C通信:https://blog.csdn.net/qq_44506730/article/details/90578507* RC522读卡:https://blog.csdn.net/leytton/article/details/73480974* 舵机控制:https://blog.csdn.net/sss_369/article/details/52894347*/ #include
#include
#include //使用Wire.h进行I2C通信#define SS_PIN 10
#define RST_PIN 9
#define SERVO_PIN 8
#define USER_NUM 3byte servoRun = 0; // 舵机控制变量。
MFRC522 rfid(SS_PIN, RST_PIN); // 实例化类
byte userCard[USER_NUM][4] = { // 通行卡存储数组。{28, 184, 119, 33},{249, 231, 71, 179},{109, 242, 234, 235}
};void setup() { Serial.begin(9600); // 波特率设置SPI.begin(); // 初始化SPI总线rfid.PCD_Init(); // 初始化 MFRC522 pinMode(SERVO_PIN, OUTPUT); // 舵机控制端口。Wire.begin(8); // 设置与NodeMCU的通信I2C端口。Wire.onReceive(receiveEvent); // 信号接受处理。
}void loop() {if(servoRun == 1){ // 舵机运行变量若为1,则运行。servoControl(); // 舵机控制函数。}if ( ! rfid.PICC_IsNewCardPresent()) return; // 找卡if ( ! rfid.PICC_ReadCardSerial()) return; // 验证NUID是否可读MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && // 检查是否MIFARE卡类型piccType != MFRC522::PICC_TYPE_MIFARE_1K &&piccType != MFRC522::PICC_TYPE_MIFARE_4K) {Serial.println("Can identify this card!");return;}byte i;for (i=0; i // 判断卡是否为通行卡。byte i2;for(i2=0; i2<4; i2++){ // 遍历userCard中所有卡。if(rfid.uid.uidByte[i2] != userCard[i][i2]) break; } // break时,表示此卡不是通行卡。if(i2 == 4){ // i2为4,表示此卡的四位值都验证通过。Serial.println("Find an accessful card."); // 输出成功信息。servoRun = 1; // 将开门变量置1。break; // 已找到通行卡,跳出循环。}}if(i==USER_NUM){ // 若i等于通行用户数量,则上层循环未找到通行卡。Serial.print("Find a unknown card, its uid:");for(i=0; i<4; i++){ // 输出此卡UID,便于后期新增通行卡。Serial.print(rfid.uid.uidByte[i], DEC);Serial.print(" ");}Serial.println();}rfid.PICC_HaltA(); // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡rfid.PCD_StopCrypto1(); // 停止读卡模块编码}void servoControl(){ // 舵机控制函数。Serial.println("Servo run!"); // 函数运行输出标识。servoPulse(0); // 舵机转至0度。delay(1000); // 等待舵机运转。servoPulse(180); // 舵机转至180度。servoRun = 0; // 舵机运行变量置零。
}void servoPulse(int myangle) // 定义一个脉冲函数,作者:https://blog.csdn.net/sss_369/article/details/52894347
{int pulseWidth=(myangle*11)+500;// 将角度转化为500-2480 的脉宽值digitalWrite(SERVO_PIN,HIGH); // 将舵机接口电平至高delayMicroseconds(pulseWidth); // 延时脉宽值的微秒数weimiaodigitalWrite(SERVO_PIN,LOW); // 将舵机接口电平至低delay(20-pulseWidth/1000);
}void receiveEvent(int howMany){ // 定义接受联网信息函数,参考:https://blog.csdn.net/qq_44506730/article/details/90578507while(0 char c = Wire.read();if (c == '1') servoRun = 1; // 如果传入数据为1,则舵机运行变量置1。Serial.println("Receive an access sign from ESP8266."); }
}
/* 作者:MWHLS,主页MWHLS.TOP* 链接:http://mwhls.top/?p=659* 通过主机连接上ESP8266热点,进入通信网址,点击CLICK按钮后,* 一个消息会使用I2C通信传输给Arduino,这个消息会触发舵机转动。* 参考文章:* I2C通信:https://blog.csdn.net/qq_44506730/article/details/90578507* 网页控制:https://blog.csdn.net/qq_46292418/article/details/106605366*/
#include // 本程序使用 ESP8266WiFi库
#include // ESP8266WebServer库
#include // 使用Wire.h进行I2C通信ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server// 括号中的数字是网路服务器响应http请求的端口号// 网络服务器标准http端口号为80,因此这里使用80为端口号
#define WIFISSID "ESP8266Web" // 设定ESP8266 wifi名称
#define WIFIPSSD "123456789" // 设定wifi密码void setup(void){Serial.begin(9600); // 启动串口通讯Wire.begin(D1,D2); // I2C通信端口setAP(); // 设定AP模式,并建立热点。//--------"启动网络服务功能"程序部分开始-------- // 此部分为程序为本示例程序重点1esp8266_server.begin(); // 详细讲解请参见太极创客网站《零基础入门学用物联网》esp8266_server.on("/", HTTP_GET, handleRoot); // 第3章-第2节 ESP8266-NodeMCU网络服务器-1esp8266_server.on("/CLICK", HTTP_POST, handleClick);// 处理用户点击消息。esp8266_server.onNotFound(handleNotFound); // 404处理。
//--------"启动网络服务功能"程序部分结束--------Serial.println("HTTP esp8266_server started"); // 告知用户ESP8266网络服务功能已经启动
}void loop(void){esp8266_server.handleClient(); // 处理http服务器访问
}void setAP(){WiFi.mode(WIFI_AP); // 设定ESP8266的AP模式WiFi.softAP(WIFISSID,WIFIPSSD); // 设定ESP8266热点Serial.printf("Success!\nWIFISSID: %s \nWIFIPSSD: %s \nControlWeb: ", WIFISSID, WIFIPSSD);Serial.println(WiFi.softAPIP()); // 接上行,输出WIFI信息与通信网址。
}void handleRoot() { // 处理网站根目录“/”的访问请求 esp8266_server.send(200, "text/html", "");
}void handleClick(){ // 点击消息处理函数Serial.println("Click."); clickTransmission(); // 传输点击消息到Arduino板。esp8266_server.sendHeader("Location","/"); // 跳转回页面根目录esp8266_server.send(303); // 发送Http相应代码303 跳转
}void clickTransmission(){ // 点击消息传输函数Wire.beginTransmission(8); // 开始传输Wire.write('1'); // 传 1 至Arduino版Wire.endTransmission(); // 结束传输Serial.println("Click transmiss success."); // 输出成功信息
}// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){ // 当浏览器请求的网络资源无法在服务器找到时,esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。
}
192.168.4.1 ,点击 Click 以触发舵机转动。| 材料 | 用途 | 数量 | 价格 |
|---|---|---|---|
| RC522 | RFID 模块 | 2 | 4.8 * 2 |
| 公对公杜邦线 (10cm) | 导线 | 1 | 1.9 |
| 母对母杜邦线 (30cm) | 导线 | 1 | 1.65 |
| NodeMCU(ESP8266 CH340串口) 及配套数据线 | WiFi 模块 | 1 | 14.8 |
| SG90 9克舵机 | 舵机 | 1 | 5.1 |
| Arduino Nano V3 CH340G 及配套数据线 | 开发板 | 1 | 16.7 |
上一篇:asp核酸检测预登记系统源码
下一篇:乐什么什么三字词语