智慧家居·萬物互聯:我的智能花盆DIY之旅
- 0 寫在前面
- 1 架構怎么搭?
- 1.1 系統層次
- 1.2 MQTT是什么?
- 1.3 專案流程
- 2 云平臺怎么用?
- 2.1 創建設備
- 2.2 設備開發
- 2.3 設備管理
- 3 軟體怎么設計?
- 3.1 依賴庫配置
- 3.2 引腳定義與連接
- 3.3 WIFI配置
- 3.4 MQTT配置
- 3.5 連接云平臺
- 3.6 執行設備
- 4 更進一步
- 5 結語
0 寫在前面
🔥物聯網(Internet of things, IoT)就是物物相連的互聯網,在智能家居、智慧城市等方面有廣泛應用,這次,我從零開始搭建一個基于ESP32的智能花盆,相信讀完本文,你也可以親自實作一個物聯網應用,無論是參加創客大賽還是物聯網比賽,都先人一步!
首先,先看看最后的實物圖


1 架構怎么搭?

1.1 系統層次
整個系統分為3部分:
- 云端服務部分 使用任何云服務器即可,本專案使用涂鴉云平臺,官網放在這涂鴉云平臺
- 控制器部分 本專案使用ESP32控制器,也可以使用STM32、樹莓派等
- 外圍設備部分 即傳感器、執行器等,本專案主要采用光敏電阻、DHT11溫濕度傳感器、燈管、風扇,也可使用舵機(做水閥)以及各種感應設備,
1.2 MQTT是什么?
MQTT(Message Queuing Telemetry Transport),訊息佇列遙測傳輸協議),是一種基于發布/訂閱(publish/subscribe)模式的"輕量級"通訊協議,MQTT最大優點在于,可以以極少的代碼和有限的帶寬,為連接遠程設備提供實時可靠的訊息服務,作為一種低開銷、低帶寬占用的即時通訊協議,使其在物聯網、小型設備、移動應用等方面有較廣泛的應用,

1.3 專案流程
MQTT的訂閱方和發布方遵守同一種開發API格式,我們根據所選云平臺設計好的API進行功能設計,在專案運轉時,ESP32(或其他任何控制器)通過WIFI連接到互聯網,使得其能夠與云平臺通信,去訂閱云平臺發布的話題(即API),這樣就能把底層傳感器的資料收集并傳輸給平臺,也能獲得平臺的反饋,
更進一步,可將物聯網應用部署到移動端、Web等,
接下來就按系統層次一步步完成DIY,
2 云平臺怎么用?
2.1 創建設備
進入涂鴉云平臺選擇產品開發,開始創建設備,

按如下圖文步驟完成產品創建,
- 產品開發:創建產品
- 選擇產品:溫濕度傳感器
- 選擇智能化方式:設備接入
- 完善產品資訊:

添加自定義功能


下面是本次實驗設計的所有功能,

2.2 設備開發
領取免費激活碼并注冊一個設備,得到如下設備憑證,

記住這里的設備憑證,后續配置要用!!
2.3 設備管理
完成上述步驟后可以在設備管理中看到創建的設備,

3 軟體怎么設計?
3.1 依賴庫配置
本專案使用的DHT11驅動需要從下面兩個地址下載庫檔案,DHT11、Adafruit_Sensor
MQTT庫和JSON庫則可以在Arduin倉庫中自行下載,
安裝MQTT庫

安裝Json庫

3.2 引腳定義與連接
查看下面的ESP32引腳定義

我的定義如下所示,大家可以參考
#include "DHT.h"
#include "WiFi.h"
#include "PubSubClient.h"
#include "ArduinoJson.h"
GPIO///
#define DHTTYPE DHT11 // 定義溫濕度傳感器型別為DHT11
#define DHTPIN 15 // DHT11引腳
#define ADCPIN 32 // 光敏電阻引腳
#define LIGHTPIN 33 // 燈光控制引腳
#define FANPIN 13 // 風扇控制引腳
GPIO///
根據定義的實際接線圖如下:

3.3 WIFI配置
WIFI設定如下:
WIFI///
#define WIFI_SSID "Winter" // wifi名
#define WIFI_PASSWD "913982779" // wifi密碼
WIFI///
3.4 MQTT配置
參考大家選用云平臺的協議規范,我這里參考涂鴉云MQTT協議

需要配置ClientID、UserName、Password三個屬性,都與前面設備憑證的DeviceId有關,其中Password需要根據設備密碼用Hmac256演算法加密,
MQTT///
#define mqttServer "m1.tuyacn.com"
#define mqttPort 1883
#define ClientId "tuyalink_6c9a1bfe77510a9904vbva"
#define User "6c9a1bfe77510a9904vbva|signMethod=hmacSha256,timestamp=1639372190,securemode=1,accessType=1"
#define Pass "e3b024852f65fffabbf17ccfe97b8a599b134a81037976736288df58ec88e188"
#define TOPIC "tylink/6c9a1bfe77510a9904vbva/thing/property/set"
MQTT///
3.5 連接云平臺
連接WIFI
WiFiClient espClient; //創建網路連接客戶端
//連接WIFI相關函式
void setupWifi()
{
delay(10);
Serial.println("Connecting WIFI");
WiFi.begin(WIFI_SSID, WIFI_PASSWD);
while (!WiFi.isConnected())
{
Serial.print(".");
delay(500);
}
Serial.println("OK");
Serial.println("Wifi connected successfully!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
配置并連接MQTT
//鏈接mqtt
void setupMQTT()
{
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected())
{
Serial.println("Connecting MQTT");
if(client.connect(ClientId,User,Pass))
{
Serial.println("MQTT connected successfully!");
client.subscribe(TOPIC);
}
else
{
Serial.print("Failed with state ");
Serial.println(client.state());
delay(2000);
}
}
}
其中MQTT回呼函式的作用:若訂閱的主題有訊息則觸發回呼獲取訊息
// MQTT回呼函式
void callback(char * topic,byte * payload,unsigned int length){
DynamicJsonDocument doc(512);
char charbuffer[512];
Serial.print("Message arrived [");
Serial.print(topic);
Serial.println("]");
int i = 0;
for(;i<length;i++){
charbuffer[i] = (char)payload[i];
}
charbuffer[i] = '\0';
DeserializationError error = deserializeJson(doc,charbuffer);
if(error){
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
bool lightOn = doc["data"]["light_switch"];
bool dehumiOn = doc["data"]["fan_switch"];
if (lightOn){
digitalWrite(LIGHTPIN,HIGH);
}
else{
digitalWrite(LIGHTPIN,LOW);
}
if (dehumiOn){
digitalWrite(FANPIN,HIGH);
}
else{
digitalWrite(FANPIN,LOW);
}
}
Arduino的設定函式
void setup() {
// put your setup code here, to run once:
pinMode(LIGHTPIN,OUTPUT);
Serial.begin(115200);
setupWifi();
setupMQTT();
dht.begin();
}
Arduino的回圈函式
void loop() {
delay(5000);
// Read humidity data
int h = dht.readHumidity();
// Read temperature as Celsius (the default)
int t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Read illumination data
float l = analogRead(ADCPIN);
int percent = 100 - l / 4096.0 * 100.0;
// 串口列印
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("C "));
Serial.print(F("illumination: "));
Serial.print(percent);
Serial.println(F("% "));
// 封裝json
DynamicJsonDocument doc(512);
DynamicJsonDocument jsdata(256);
DynamicJsonDocument tempdata(32);
DynamicJsonDocument humidata(32);
DynamicJsonDocument light(32);
tempdata["value"] = t;
tempdata["time"] = 1639454915;
humidata["value"] = h;
humidata["time"] = 1639454915;
illudata["value"] = percent;
illudata["time"] = 1639454915;
jsdata["temp_current"] = tempdata;
jsdata["humidity_current"] = humidata;
jsdata["light_current"] = light;
doc["msgId"] = "45lkj3551234001";
doc["time"] = 1639454915;
doc["data"] = jsdata;
String str;
serializeJson(doc, str);
// Serial.println(str);
// Sending to MQTT
char *p = (char *)str.c_str();
if(client.publish("tylink/6c9a1bfe77510a9904vbva/thing/property/report",p) == true)
Serial.println("Success sending message.");
else Serial.println("Failed sending message.");
client.loop();
}
打開串口,成功收到連接訊息,

打開云平臺,成功看到設備在線,同時也能獲得設定的各個屬性資訊,

3.6 執行設備
由于我選擇了USB燈管,但ESP32無法驅動USB(除非轉接),不得不以一種不甚優雅的方式通過樹莓派間接驅動這些執行設備,大家只要選型選好就不存在這種兩個控制器的問題,這里把樹莓派理解成一種驅動器即可,它通過讀ESP32的信號來點燈和驅動風扇,下面代碼僅供參考
import RPi.GPIO as GPIO
#------------------------------------------------------#
# @breif: 執行設備
#-------------------------------------------------------#
class Exe:
def __init__(self):
self.light = 11 # 引腳11接燈
self.fan = 13 # 引腳13接風扇
self.esp = 15 # 引腳15接ESP32
GPIO.setmode(GPIO.BOARD)
GPIO.setup(self.light,GPIO.OUT)
GPIO.output(self.light,GPIO.LOW)
GPIO.setup(self.fan ,GPIO.OUT)
GPIO.output(self.fan ,GPIO.LOW)
# @breif:驅動
def run(self):
if GPIO.input(self.esp):
GPIO.output(self.light, GPIO.HIGH)
GPIO.output(self.fan , GPIO.HIGH)
else:
GPIO.output(self.light, GPIO.LOW)
GPIO.output(self.fan , GPIO.LOW)
4 更進一步
寫了個簡單的網頁來實時監測、可視化,

5 結語
終于完成了這個物聯網專案,程序中還是踩了很多坑的,
🔥歡迎關注博主,不定期更新機器人(ROS)、機器學習(深度學習)、計算機視覺、嵌入式系統(物聯網)等方面文章!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/384332.html
標籤:其他
上一篇:Chrome插件我只服你——10w人都在使用的瀏覽器插件
下一篇:jmeter--基礎實戰應用總結
