esp8266+RC522模块+DFPlay Mini Mp3模块实现宿舍智能门锁//NFC//物联网
提示:
提示:
文章目录
- esp8266+RC522模块+DFPlay Mini Mp3模块实现宿舍智能门锁//NFC//物联网
- 前言
- 一、实现的具体功能
- 二、硬件材料
- 1、材料清单
- 2、线路连接
- 三、软件代码
- 1、arduino安装和环境配置
- 2、环境配置
- 结语
前言
每天下课回宿舍本来就挺累的,到门口还要到处翻找钥匙,还有插钥匙,还要再拧钥匙,这是多么得不人性,这得浪费多少时间精力,难道开门就不能有点仪式感吗,就不能在开门后听到“噢,xx主人,欢迎回家噢50”这样温暖的女声吗?---------这些都是瞎扯,主要是因为人太懒了,想方便点~,成本50块左右就可以拥有仪式和便利。
直接上演示
视频演示
视频演示
更多视频请前往抖音
一、实现的具体功能
1、实现刷校园卡或手机NFC开宿舍门。
2、利用点灯科技物联网实现手机控制打开宿舍门和宿舍灯。
3、开门开灯都有语音提示。
二、硬件材料
1、材料清单
1、esp8266开发板(均价13R);
2、RC522 RFID射频模块(均价5R);
3.DFPlay Mini Mp3模块 (均价5R);
4、喇叭一个(均价3R);
5、杜邦线:20CM母对母线 (5R);
6、MG90s金属舵机 * 2 (17R);
7、其他
2、线路连接
1、 esp8266和射频模块连接
2、esp8266和MP3模块连接
3、esp8266和舵机连接
舵机有三条线,橙红黑,分别对应的是信号线,正极,负极。在这里8266开发板不给舵机供电,采用外置电源供电,所以Gnd负极要共地。
三、软件代码
1、arduino安装和环境配置
1)arduino安装包
官网下载https://www.arduino.cc/en/software
下载好后解压安装,一定要记住安装在哪个目录下
网盘下载:
恭喜,文件超500M,我没有网盘会员,上传不了,haha,自个网上找
2、环境配置
环境配置步骤不难,但很有可能就是配置不了,自从我几个月前重置电脑后,就一直配置不好那环境,直到最近一次在心理课上搞了两节课才配置成功T-T;
第一步:
打开arduino IDE,
点 文件—>首选项
添加开发板,复制这个地址到红线上的框:http://arduino.esp8266.com/stable/package_esp8266com_index.json
然后点击 好
第二步:
点击 —>工具—>开发板—>开发板管理器
输入esp8266
然后安装开发板,然后退出
就是这里很可能安装不了,如果安装不了就再自个儿去找别的开发板地址重新搞一遍;
以上的操作是添加esp8266开发板到arduino IDE里;接下来是添加各种库
添加mfrc522库
、打开IDE;点击 工具—>管理库—>然后按图片里指示安装库;
、添加mp3模块的库
链接:https://pan.baidu.com/s/1rtu9XAY9tEQM4wm0oee-yQ
提取码:1234
下载ZIP压缩文件
点击–>项目—>鼠标光标移到加载库—>点击添加ZIP库
然后找到刚才下载的ZIP文件,添加进去,然后完事
、添加点灯科技的库
点灯科技
https://www.diandeng.tech/doc/getting-start-8266
按点灯科技里的开发文档配置,官方已经讲得很详细了
OK,到现在就可试试上传代码了;上传代码前一定要确认选择的开发板是ESP8266,不会可按图操作:
这是电灯科技的实列代码,可以编译上传测试下看看点灯科技的环境配置好了没;
后面还有个代码,可以测试整体环境是是否配置好;
//*****点灯科技Blinker*****//
#define BLINKER_PRINT Serial
#define BLINKER_WIFI#include <Blinker.h>char auth[] = "Your Device Secret Key";
char ssid[] = "Your WiFi network SSID or name";
char pswd[] = "Your WiFi network WPA password or WEP key";// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");int counter = 0;// 按下按键即会执行该函数
void button1_callback(const String & state) {BLINKER_LOG("get button state: ", state);digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{BLINKER_LOG("Blinker readString: ", data);counter++;Number1.print(counter);
}void setup() {// 初始化串口Serial.begin(115200);#if defined(BLINKER_PRINT)BLINKER_DEBUG.stream(BLINKER_PRINT);#endif// 初始化有LED的IOpinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, HIGH);// 初始化blinkerBlinker.begin(auth, ssid, pswd);Blinker.attachData(dataRead);Button1.attach(button1_callback);
}void loop() {Blinker.run();
}
该代码来自 https://blog.csdn.net/yaolei5/article/details/118583092
后面我的代码也是参考此改的,该代码对应的接线图和我的有点不一样,具体的再去看原博主的。
//不带手机控制功能
#include <EEPROM.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>Servo myservo; //创建电机对象int ser_num ;int ser_max ;#define RST_PIN 5 // 配置针脚
#define SS_PIN 4
MFRC522 mfrc522(SS_PIN, RST_PIN); // 创建新的RFID实例
//RC模块使用了D1.D2.D5.D6.D7
/*************************IO配置**************************/
int Buzzer = 16; //D0(io16)蜂鸣器,提示音,也可以用led
int btn = 15; //D8(io15)按钮,保存门禁卡ID到EEPROM
/*************************数据**************************/
//使用union结构,合并4个byte数据,转换为1个long
union long_byte
{long long_data;byte byte_data[4];
};
long_byte lb;
long EEPROM_RFID1 = -1;//EEPROM中保存的门禁卡ID1
long EEPROM_RFID2 = -1;
long EEPROM_RFID3 = -1;
long EEPROM_RFID4 = -1;
long EEPROM_RFID5 = -1;
long EEPROM_RFID6 = -1;
long EEPROM_RFID7 = -1;
long read_RFID = -1; //当前读取到的门禁卡ID
int num ;
void setup()
{Serial.begin(115200);Serial.println("");EEPROM.begin(1024);myservo.attach(0); //servo.attach():设置舵机数据引脚myservo.write(10); //servo.write():设置转动角度ser_num = 100;ser_max = 100;//读取EEPROM索引的值 我这里设置了七张卡,不够也可以再加for (int i = 0; i < 4; i++){lb.byte_data[i] = EEPROM.read(i); //卡1}EEPROM_RFID1 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+4); //卡2}EEPROM_RFID2 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+8); //卡3}EEPROM_RFID3 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+12); //卡4}EEPROM_RFID4 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+16); //卡5}EEPROM_RFID5 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+20); //卡6}EEPROM_RFID6 = lb.long_data;for (int i = 0 ; i<4 ; i++ ){lb.byte_data[i] = EEPROM.read(i+24); //卡7}EEPROM_RFID7 = lb.long_data;num = EEPROM.read(30);IO_init(); RFID_init();
}void loop()
{Btn_Event();RFID_read(); //读卡并做分析处理
}
void opendoor(void){read_RFID = -1;int fromPos;int toPos;fromPos = myservo.read();toPos = 10;if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”for (int i=fromPos; i<=toPos; i++){myservo.write(i);delay (5);}} else { //否则“起始角度值”大于“目标角度值”for (int i=fromPos; i>=toPos; i--){myservo.write(i);delay (5);}}int i;for(i =10 ; i<= ser_max ; i++){myservo.write(i);delay(5); }delay(1000);for(i = ser_max ; i>=10 ; i--){ myservo.write(i);delay(5); }}//监听按钮状态,更换显示状态和值
void Btn_Event()
{EEPROM.begin(1024);//io15默认的有下拉,所以要判断是否为高电平if (digitalRead(btn) == 1){delay(200);if (read_RFID == -1){Serial.println("当前未读卡");Di(3);}else{switch(num){case 0 : lb.long_data = read_RFID;EEPROM_RFID1 = lb.long_data;for (int i = 0; i < 4; i++){EEPROM.write(i, lb.byte_data[i]);}num = 1;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID1已保存");Di(1);break;case 1 :lb.long_data = read_RFID;EEPROM_RFID2 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+4, lb.byte_data[i]);}num=2;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID2已保存");Di(1);break;case 2 :lb.long_data = read_RFID;EEPROM_RFID3 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+8, lb.byte_data[i]);}num=3;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID3已保存");Di(1);break;case 3 :lb.long_data = read_RFID;EEPROM_RFID4 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+12, lb.byte_data[i]);}num=4;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID4已保存");Di(1);break;case 4 :lb.long_data = read_RFID;EEPROM_RFID5 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+16, lb.byte_data[i]);}num=5;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID5已保存");Di(1);break;case 5 :lb.long_data = read_RFID;EEPROM_RFID6 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+20, lb.byte_data[i]);}num=6;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID6已保存");Di(1);break;case 6 :lb.long_data = read_RFID;EEPROM_RFID7 = lb.long_data;for (int i = 0 ; i < 4; i++ ){EEPROM.write(i+24, lb.byte_data[i]);}num=0;EEPROM.write(30, num);EEPROM.commit();//执行保存EEPROMSerial.println("门禁卡ID7已保存");Di(1);break;}}}
}//初始化IO
void IO_init()
{//io15默认有硬件下拉,不要使用软件上拉模式pinMode(btn, INPUT);pinMode(Buzzer, OUTPUT);digitalWrite(Buzzer, 0);
}//蜂鸣器音效
void Di(int a)
{for (int i = 0; i < a; i++){digitalWrite(Buzzer, 1);delay(500);digitalWrite(Buzzer, 0);delay(100);}
}/***********************RFID读卡自定义函数***********************/
//初始化读卡
void RFID_init()
{SPI.begin(); // SPI开始mfrc522.PCD_Init(); // 初始化Serial.println("初始化读卡");
}//运行读卡
void RFID_read()
{if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()){return;}else{read_RFID = RFID_toLong(mfrc522.uid.uidByte);RFID_Handler(read_RFID);mfrc522.PICC_HaltA();//停止 PICCmfrc522.PCD_StopCrypto1(); //停止加密PCDreturn;}
}//用户ID转换类型
long RFID_toLong(byte *by)
{long data;for (int i = 0; i < 4; i++){lb.byte_data[i] = by[i];}data = lb.long_data;return data;
}//把当前读到卡的ID,对比EEPROM中的ID
void RFID_Handler(long data)
{Serial.println(data);if (data == EEPROM_RFID1) {Serial.println("ID1正确,验证通过");Di(1);opendoor(); //开门函数}else if(data == EEPROM_RFID2){Serial.println("ID2正确,验证通过");Di(1);opendoor();}else if(data == EEPROM_RFID3){Serial.println("ID3正确,验证通过");Di(1);opendoor();}else if(data == EEPROM_RFID4){Serial.println("ID4正确,验证通过");Di(1);opendoor();}else if(data == EEPROM_RFID5){Serial.println("ID5正确,验证通过");Di(1);opendoor();}else if(data == EEPROM_RFID6){Serial.println("ID6正确,验证通过");Di(1);opendoor();}else if(data == EEPROM_RFID7){Serial.println("ID7正确,验证通过");Di(1);opendoor();} else{Di(2);Serial.println("ID错误,验证失败");}}
如果上传不成功,有几种原因,一是你配置环境没成;二是可能库重复了,我之前就是那个舵机的库有两个,最后得删了一个才可以;如果是其他情况再另说了;
OK,现在到了我的代码了,由于代码有点多,编译的时间有点长,而且没有多余的硬件,所以整理调试了好几次后就不想在搞了,毕竟断断续续搞了右边一个多星期了,而且已经投入使用了,就更不想搞了,所以现在可能会觉得有点乱,那就将就看吧,不行再一起讨论咯;
#include <EEPROM.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#include "DFPlayer_Mini_Mp3.h"SoftwareSerial mySerial(3, 1); // RX, TX/*****点灯。h*****/
#define BLINKER_PRINT Serial
#define BLINKER_WIFI
#include <Blinker.h>
#define offled 90
#define onled 180
char auth[] = "设备的密钥";//不懂看点灯科技的开发文档
char ssid[] = "123456";//wifi账号
char pswd[] = "12345678";//wifi密码int counter = 0;
int cc=0;// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerButton Button2("btn-loc");
BlinkerNumber Number1("num-abc");// 按下按键即会执行该函数
void button1_callback(const String & state) {BLINKER_LOG("get button state: ", state);if(state=="press"){counter++;Number1.print(counter);digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));Di(1);mp3_play (1);opendoor();}
}
void button2_callback(const String & state) { //****openled****//BLINKER_LOG("get button state: ", state);if(state=="press"){digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));Di(6);if(cc==180)openled_1();if(cc==0)openled_2();}
}
//void button2_callback(const String & state) {
// BLINKER_LOG("get button state: ", state);
// int loc=0;
// loc=!loc;
// BlinkerNumber.print(loc);
//
//}Servo myservo; //创建电机对象
Servo myservo_2;
int ser_num ;
int ser_max ;//gjgh#define RST_PIN 5 // 配置针脚
#define SS_PIN 4
MFRC522 mfrc522(SS_PIN, RST_PIN); // 创建新的RFID实例
//RC模块使用了D1.D2.D5.D6.D7
/*************************IO配置**************************/int Buzzer = 2; //D4(io16)蜂鸣器,提示音,也可以用led
int btn = 10; //D8(io15)按钮,保存门禁卡ID到EEPROM
/*************************数据**************************/
//使用union结构,合并4个byte数据,转换为1个long
union long_byte
{long long_data;byte byte_data[4];
};
long_byte lb;//*********保存卡号********//
long EEPROM_RFID1 = -438780863;//
long EEPROM_RFID2 = -438811967;//haozhong
long EEPROM_RFID3 = -438747535;//zhijing
long EEPROM_RFID4 = -438762815;//zhiwei
long EEPROM_RFID5 = -1901206631;
long EEPROM_RFID6 = -2114835350;
long EEPROM_RFID7 = 1901206631;
long EEPROM_RFID8 = 2114835350;
long read_RFID = -1; //当前读取到的门禁卡ID
int num ;void setup()
{Serial.begin(115200);mySerial.begin (9600);mp3_set_serial (mySerial); //set Serial for DFPlayer-mini mp3 modulemp3_set_volume (600);BLINKER_DEBUG.stream(Serial);Blinker.begin(auth, ssid, pswd);pinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, LOW);//Button2.attach(button2_callback);Button1.attach(button1_callback); //手机开门
Button2.attach(button2_callback);Serial.println("");EEPROM.begin(1024);//******开关动作,舵机转动的角度,具体的角度看实际情况*****//myservo.attach(0); //servo.attach():设置开门舵机数据引脚myservo.write(180); //servo.write():设置转动角度myservo_2.attach(15); //servo.attach():设置舵机数据引脚myservo_2.write(90); //servo.write():设置led转动角度ser_num = 100;ser_max = 100;IO_init();RFID_init();openMCU();//******开机提示灯******//digitalWrite(LED_BUILTIN, 0);}void loop()
{RFID_read(); //读卡并做分析处理//btn_on();//*****机械按键开灯******//Blinker.run();//Btn_Event();}
void btn_on(){if (digitalRead(btn) == 1){mp3_play (7);//*******开宿舍灯提示音,第0007******// Di(2);if(cc==180)openled_1();if(cc==0)openled_2();}
}
void openMCU()//*****开机提示灯******//
{mp3_play (5);//*******开机提示音,第0005******//digitalWrite(LED_BUILTIN, 1);delay(200);digitalWrite(LED_BUILTIN, 0);delay(200);digitalWrite(LED_BUILTIN, 1);delay(200);digitalWrite(LED_BUILTIN, 0);}
void opendoor(void) { /***************开门*************/myservo.write(120);delay(1800);myservo.write(180);}void openled_1(void) { /***************开led*************/myservo_2.write(180);cc=0;delay(1800);myservo_2.write(90);}
void openled_2(void) { /***************off led*************/myservo_2.write(0);cc=180;delay(1800);myservo_2.write(90);}//初始化IO
void IO_init()
{//io15默认有硬件下拉,不要使用软件上拉模式// pinMode(btn, INPUT);pinMode(Buzzer, OUTPUT);digitalWrite(Buzzer, 0);
}//蜂鸣器音效
void Di(int a)
{for (int i = 0; i < a; i++){digitalWrite(Buzzer, 1);delay(500);digitalWrite(Buzzer, 0);delay(500);}
}/***********************RFID读卡自定义函数***********************/
//初始化读卡
void RFID_init()
{SPI.begin(); // SPI开始mfrc522.PCD_Init(); // 初始化Serial.println("初始化读卡");
}//运行读卡
void RFID_read()
{if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()){return;}else{read_RFID = RFID_toLong(mfrc522.uid.uidByte);Serial.println(read_RFID);RFID_Handler(read_RFID);mfrc522.PICC_HaltA();//停止 PICCmfrc522.PCD_StopCrypto1(); //停止加密PCDreturn;}
}//用户ID转换类型
long RFID_toLong(byte *by)
{long data;for (int i = 0; i < 4; i++){lb.byte_data[i] = by[i];}data = lb.long_data;return data;
}//把当前读到卡的ID,对比EEPROM中的ID
void RFID_Handler(long data)
{// Serial.println(data);// if (EEPROM_RFID1 == 0&&EEPROM_RFID2 == -1&&EEPROM_RFID3 == -1&&EEPROM_RFID4 == -1&&// EEPROM_RFID5 == -1&&EEPROM_RFID6 == -1&&EEPROM_RFID7 == -1)// {// Serial.println("当前未设置卡");// Di(3);// }// else// {if (data == EEPROM_RFID1) {Serial.println("ID1正确,验证通过");mp3_play (1);opendoor(); //开门函数Di(2);// mp3_play (1);}else if (data == EEPROM_RFID2) {Serial.println("ID2正确,验证通过");mp3_play (2);opendoor();Di(2);}else if (data == EEPROM_RFID3) {Serial.println("ID3正确,验证通过");mp3_play (3);opendoor();Di(2);}else if (data == EEPROM_RFID4) {Serial.println("ID4正确,验证通过");opendoor();mp3_play (4);opendoor();Di(2);}else if (data == EEPROM_RFID5) {Serial.println("ID5正确,验证通过");opendoor();Di(5);}else if (data == EEPROM_RFID6) {Serial.println("ID6正确,验证通过");opendoor();Di(6);}else if (data == EEPROM_RFID7) {Serial.println("ID7正确,验证通过");opendoor();Di(7);}else if (data == EEPROM_RFID8) {Serial.println("ID7正确,验证通过");opendoor();Di(8);}else{mp3_play (6);//*********读卡错误提示音,0006*********//Di(4);Serial.println("ID错误,验证失败");}// }
}
里面有些代码可以不用理,像按键(btn on这个函数)开宿舍灯这个
最后是点灯科技app的页面设置
结语
这是第一次把自己做的项目整理成博客,本来是想搞个保姆教程的,但发现工作量有点大,而且最近时间也比较紧,就只能大概地整理了;哎,也就只能这样了。。。。。还有供电问题,后期有空再更新了,交流可jia;