1. 前言
隨著智能家居的快速發展,智能門鎖作為家庭安全的重要組成部分,受到了越來越多用戶的關注和需求。為了滿足用戶對安全和便捷的需求,決定設計一款基于STM32的智能門鎖,并將其與華為云IOT平臺相結合。
傳統的門鎖存在一些弊端,比如使用鑰匙容易丟失、開鎖過程繁瑣等。而智能門鎖的出現,有效地解決了這些問題。我選擇使用STM32作為智能門鎖的核心控制器,因為STM32系列具有低功耗、高性能和豐富的外設接口等優點,非常適合嵌入式應用。
華為云IOT平臺作為一個強大的云服務平臺,提供了豐富的物聯網解決方案和強大的數據處理能力。將智能門鎖與華為云IOT平臺相結合,可以實現遠程控制、數據監測和智能化的功能,為用戶帶來更加便捷和安全的居家體驗。
智能門鎖設計具有以下主要特點和功能:
- 安全可靠:采用先進的加密算法和身份驗證機制,確保門鎖的安全性。用戶可以通過手機APP、指紋識別或密碼等方式進行開鎖,有效防止非法入侵。
- 遠程控制:通過與華為云IOT平臺的連接,用戶可以通過手機APP在任何地方實現對門鎖的遠程控制。比如,可以遠程開關門鎖、查看開鎖記錄等。
- 多種開鎖方式:除了傳統的鑰匙開鎖方式外,我們的智能門鎖還支持多種開鎖方式,如指紋識別、密碼輸入、手機APP控制等。用戶可以根據自己的需求選擇最方便的開鎖方式。
- 實時監測:智能門鎖可以實時監測門鎖狀態、開鎖記錄等信息,并將這些數據上傳到華為云IOT平臺進行存儲和分析。用戶可以通過手機APP查看相關數據,了解家庭安全狀況。
- 智能化功能:基于華為云IOT平臺的數據處理能力,我們的智能門鎖還可以實現一些智能化的功能。比如,可以設置自動開鎖時間、遠程授權開鎖等。
2. 設備硬件與功能介紹
這篇文章就介紹如何使用華為物聯網云平臺實現智能鎖的應用場景構建,硬件采用STM32F103ZET6 + ESP8266+步進電機實現。在華為云IOT物聯網平臺構建智能鎖項目,配置好云端,設備端通過ESP8266連接華為物聯網平臺,實現數據上報,交互,實現遠程開鎖、關鎖、獲取鎖的狀態等功能,不用擔心忘記出門關鎖,也不用擔心忘記帶鑰匙無法開門的情況。
ESP8266是物聯網解決方案里比較熱門的WIFI設備,支持串口+AT指令控制,任意支持串口的單片機都可以使用ESP8266快速實現聯網。
步進電機采用常規28BYJ-48來模擬當做門鎖的電機,驅動板采用ULN2003。
3. 創建云端設備
登錄官網: https://www.huaweicloud.com/
直接搜索物聯網,打開頁面。
選擇設備接入:
選擇免費試用:
在產品頁面,點擊右上角創建產品:
填上產品信息:
得到產品ID,保存好ID,點擊查看詳情:
產品ID為:61b9ba3a2b2aa20288c1e7f1.
點擊設備頁面,注冊設備:
填充信息進行注冊:
保存設備密匙和設備ID,點擊保存關閉會自動下載文件保存,后面生成密碼和登錄賬號需要使用
關閉后就看到創建好的設備了:
點擊產品頁面,選擇剛才創建的產品:
選擇自定義模型---創建數據模型服務:
選擇新增屬性,創建設備的屬性
4. 創建MQTT登錄賬號和密匙
設備創建完成接來下生成MQTT登錄賬號、密匙,方便設備登錄云端平臺。
官網工具地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打開剛才創建設備時,下載的密匙文件,把內容復制出來對應的填進去,生成即可。
5. 拼接主題訂閱與發布的格式
官方文檔介紹: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html
在產品頁面可以,看到主題的全部格式:
總結的格式如下:
格式: $oc/devices/{device_id}/sys/messages/down
//訂閱主題: 平臺下發消息給設備
$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down
?
?
格式: $oc/devices/{device_id}/sys/properties/report
//設備上報數據
$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report
?
上屬性的數據格式:
//上報的屬性消息 (一次可以上報多個屬性,在json里增加就行了)
{"services": [{"service_id": "lock","properties":{"門鎖":1}}]}
上面屬性里的服務ID和屬性里的名稱,在設備頁面,影子設備頁面查看。
6. MQTT客戶端模擬設備登錄云端
下面使用MQTT客戶端模擬設備登錄服務器測試,看設備創建的是否OK。
服務器的IP地址是: 121.36.42.100
端口號是: 1883
打開MQTT客戶端軟件,按照提示,輸入相關參數后,點擊連接,然后再點擊訂閱主題,發布主題即可:
查看云端服務器的情況: 可以看到設備已經在線了,并且收到上傳的數據。
修改一下鎖的狀態,上報屬性再查看:
發現云端的狀態也已經改變,現在設備上報已經OK。
接下來測試命令下發,實現遠程開鎖關鎖的功能:
打開產品頁面,新增加命令:
命令添加成功:
在設備頁面,選擇同步命令下發:
點擊確定后,查看MQTT客戶端,發現已經收到數據了:
$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497/sys/commands/request_id=88e2626f-290d-405e-962d-51554445a8fd{"paras":{"lock":1},"service_id":"lock","command_name":"lock"}
設備端解析收到的數據,就可以完成多步進電機的控制,完成開鎖關鎖。
7. STM32+ESP8266連接云端
工程是keil5工程
項目源碼:https://download.csdn.net/download/xiaolong1126626497/81993720
main函數代碼如下:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include < string.h >
#include "timer.h"
#include "bluetooth.h"
#include "esp8266.h"
#include "mqtt.h"
?
//華為物聯網服務器的設備信息
#define MQTT_ClientID "61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510"
#define MQTT_UserName "61b9ba3a2b2aa20288c1e7f1_QQ1126626497"
#define MQTT_PassWord "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242"
?
//訂閱與發布的主題
#define SET_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down" //訂閱
#define POST_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report" //發布
?
char mqtt_message[200];//上報數據緩存區
?
int main()
{
u32 time_cnt=0;
u32 i;
u8 key;
LED_Init();
BEEP_Init();
KEY_Init();
USART1_Init(115200);
TIMER1_Init(72,20000); //超時時間20ms
USART2_Init(9600);//串口-藍牙
TIMER2_Init(72,20000); //超時時間20ms
USART3_Init(115200);//串口-WIFI
TIMER3_Init(72,20000); //超時時間20ms
USART1_Printf("正在初始化WIFI請稍等.\\n");
if(ESP8266_Init())
{
USART1_Printf("ESP8266硬件檢測錯誤.\\n");
}
else
{
//非加密端口
USART1_Printf("WIFI:%d\\n",ESP8266_STA_TCP_Client_Mode("CMCC-Cqvn","99pu58cb","121.36.42.100",1883,1));
}
//2. MQTT協議初始化
MQTT_Init();
//3. 連接華為服務器
while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))
{
USART1_Printf("服務器連接失敗,正在重試...\\n");
delay_ms(500);
}
USART1_Printf("服務器連接成功.\\n");
//3. 訂閱主題
if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
{
USART1_Printf("主題訂閱失敗.\\n");
}
else
{
USART1_Printf("主題訂閱成功.\\n");
}
while(1)
{
key=KEY_Scan(0);
if(key==2)
{
time_cnt=0