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的IO
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// 初始化blinker
Blinker.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//執行保存EEPROM
Serial.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();//停止 PICC
mfrc522.PCD_StopCrypto1(); //停止加密PCD
return;
}
}
//用戶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 module
mp3_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();//停止 PICC
mfrc522.PCD_StopCrypto1(); //停止加密PCD
return;
}
}
//用戶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;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/330426.html
標籤:其他

