來看看單片機學生有多卷,基於esp32的簡易宿舍開門神器
相信很多人都有忘帶鑰匙的經歷,我也經常看到有同學因為忘帶鑰匙而不得不在宿舍門口當門神。在入門了esp32後,自然而然地就想利用這款集成了wifi和藍牙還便宜的晶片解決這個生活中的痛點~
這個應該很多人都做過,我看過有用arduino開發板結合射頻模塊做的,有用stm32做指紋的,甚至還有做人臉識別的。可以說八仙過海,各顯神通了。
我的方案就沒啥技術了(太菜了~)
開門具體方案是用esp32控制一個12V減速電機拉動扶手(試過舵機,拉不動~)
一.所需材料:
1.esp32-Wroom開發板(20元左右)
2.12v雙路繼電器(6塊錢)
3.升壓模塊(3塊錢)
4.麵包板(3元)
5.12v直流減速電機(13元)
6.充電寶(容量越大越好)
(杜邦線若干,電烙鐵等常見工具)
二.原理
一開始我是想用esp32跑個web區域網頁開門和RC522刷卡開門,但是功耗和穩定性感人~
於是把wifi改用藍牙了,發現傳統藍牙功耗感人~
改用BLE低功耗藍牙,發現功耗依舊感人,於是把刷卡開門功能閹了~
esp32作為主控,通訊方式為BLE低功耗藍牙,手機端連接至服務端並向服務端發送信息,服務端接收到信息後執行開門代碼,控制電機開門。
完整的原理圖
需要注意的是我這裡是用充電寶供電,所以儘可能降低功耗來增加續航。
關於電機控制,我試過用L298n來控制,失敗了(理論上是可以的,不知為什麼),後來用雙路繼電器來控制正反轉原理如下圖
關於電機我採用的是25GA370直流減速電機(12v60轉每分鐘),淘寶上一搜就能看到。實測下來扭力說是夠了但缺點是轉的太慢了~電機長這個樣子~
三.代碼:開發環境是arduino
[code]
int Buzzer = 5; //GPIO5蜂鳴器,提示音
long int ww = 0;
/**********************舵機***************************************************/
void servo(){
digitalWrite(2,HIGH);
delay(12500);
digitalWrite(2,LOW);
digitalWrite(Buzzer, 1);
delay(1000);
digitalWrite(Buzzer, 0);
delay(2000);
digitalWrite(4,HIGH);
delay(8000);
digitalWrite(4,LOW);
}
/***********************藍牙配置********************/
#include
#include
#include
#include
#include
#define SERVICE_UUID "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
#define CHARACTERISTIC_UUID_RX "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
#define CHARACTERISTIC_UUID_TX "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
bool deviceConnected = false;
BLECharacteristic *pCharact_TX;
class ServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
Serial.println("連線中斷");
BLEDevice::startAdvertising(); //重新發出廣告
}
};
class RXCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharact) {
std::string rxVal = pCharact->getValue();
Serial.printf("收到輸入值:%s\n", rxVal.c_str());
if (rxVal == "on") {
Serial.println("開門");
servo();
} else if (rxVal == "off") {
Serial.println("重啟");
ESP.restart();
}
}
};
class TXCallbacks: public BLECharacteristicCallbacks {
void onStatus(BLECharacteristic *pCharact, Status s, uint32_t code) {
Serial.printf("狀態碼:%d\n", s);
Serial.printf("code:%d\n", code);
}
};
void printDeviceAddress() {
const uint8_t* point = esp_bt_dev_get_address();
for (int i = 0; i < 6; i++) {
char str[3];
sprintf(str, "%02X", (int)point[i]);
Serial.print(str);
if (i < 5){
Serial.print(":");
}
}
}
void setup() {
// put your setup code here, to run once:
/******************串口初始化*******************/
Serial.begin(9600);
/*********************藍牙初始化************************/
BLEDevice::init("ESP32藍牙LED開關");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new ServerCallbacks());
//建立服務
BLEService *pService = pServer->createService(SERVICE_UUID);
//建立特徵
pCharact_TX = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_READ
);
pCharact_TX->addDescriptor(new BLE2902());
pCharact_TX->setCallbacks(new TXCallbacks());
BLECharacteristic *pCharact_RX = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharact_RX->setCallbacks(new RXCallbacks());
BLEDescriptor *pDesc = new BLEDescriptor((uint16_t)0x2901);
pDesc->setValue("控制板內建LED的開關");
pCharact_RX->addDescriptor(pDesc);
//啟動服務
pService->start();
//開始廣播
pServer->getAdvertising()->start();
Serial.println("等待用戶端連線…");
printDeviceAddress();
/*****************引腳初始化***********************************************/
pinMode(Buzzer, OUTPUT);
pinMode(2,OUTPUT);//此引腳高電平正轉
pinMode(4,OUTPUT);//此引腳高電平反轉S
}
/********************************蜂鳴器音效***********************************/
void Di(int a)
{
for (int i = 0; i < a; i++)
{
digitalWrite(Buzzer, 1);
delay(250);
digitalWrite(Buzzer, 0);
delay(50);
}
}
void loop() {
// put your main code here, to run repeatedly:
/*******************************定時重啟********************************/
ww = millis(); //給開機時間賦值
if (ww >= 240*1000)//定時重啟函數
{
ESP.restart();
return;
}
/*******************藍牙開門**************************/
if (deviceConnected) {
int hallVal = hallRead();
char buffer[5];
itoa(hallVal, buffer, 10);
pCharact_TX->setValue(buffer);
pCharact_TX->notify();
Serial.printf("送出: %d\n", hallVal);
}
delay(500);
}
[/code]
BLE低功耗藍牙代碼比傳統藍牙要複雜太多了~
我的室友再也不用擔心我沒帶鑰匙了~
///插播一條:我自己在今年年初錄製了一套還比較系統的入門單片機教程,想要的同學找我拿就行了免費的,私信我就可以哦~點我頭像黑色字體加我也能領取哦。最近比較閒,帶做畢設,帶學生參加省級或以上比賽///