基于MQTT协议的物联网小基站

admin 2025-12-22 03:55:35 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了一个基于MQTT协议的物联网小基站项目,通过ESP8266微控制器连接DHT11温湿度传感器、LED灯和OLED显示屏等硬件,实现温湿度监测和远程控制功能。文章详细说明了硬件连接方式、MQTT主题订阅发布机制,并提供了完整的Arduino代码实现,同时展示了如何将设备接入微信小程序和HomeAssistant系统,实现远程监控和控制。 综合评分: 75 文章分类: IoT安全,应用安全,安全开发,网络安全,终端安全


cover_image

基于MQTT协议的物联网小基站

原创

大表哥吆

kali笔记

2025年1月20日 19:44 甘肃

本文为大家分析基于MQTT协议的物联网基站。通过mqtt实现接入微信小程序和HA。

线路连接说明

  • D5–>DHT11接口
  • D6–>1号灯
  • D6–>2号灯
  • A0–>土壤传感器
  • D1–>显示器SDA
  • D2–>显示器SCL

注意,本示例中,因没有添加土壤传感器,在代码中进行了注释。需要开启,去掉注释就行了。

关于主题

订阅主题为homedht11用于接收温湿度数据。格式为json类型。

发布主题为myhome/leds 01空控制1号灯。onoff控制2号灯。

配置小程序

可以移步之前的文章《基于MQTT协议的微信小程序 上手指南》

同理,可接入HA

#完整代码

#include&nbsp;<Arduino.h>
#include&nbsp;<U8g2lib.h>
#include&nbsp;<DHT.h>
#include&nbsp;<ESP8266WiFi.h>
#include&nbsp;<ArduinoJson.h>
#include&nbsp;<PubSubClient.h>

//&nbsp;定义引脚和传感器类型
#define&nbsp;DHTPIN&nbsp;D5
#define&nbsp;DHTTYPE&nbsp;DHT11
int&nbsp;moistureSensorPin&nbsp;=&nbsp;A0;
const&nbsp;int&nbsp;ledPin1&nbsp;=&nbsp;D6;
const&nbsp;int&nbsp;ledPin2&nbsp;=&nbsp;D7;

DHT&nbsp;dht(DHTPIN,&nbsp;DHTTYPE);

//&nbsp;OLED显示屏设置
U8G2_SSD1306_128X64_NONAME_F_SW_I2C&nbsp;u8g2(U8G2_R0,&nbsp;D2,&nbsp;D1,&nbsp;U8X8_PIN_NONE);

//&nbsp;WIFI&nbsp;and&nbsp;MQTT&nbsp;配置
const&nbsp;char*&nbsp;ssid&nbsp;=&nbsp;"你的WiFi";
const&nbsp;char*&nbsp;password&nbsp;=&nbsp;"WiFi密码";
const&nbsp;char*&nbsp;mqtt_server&nbsp;=&nbsp;"mqtt服务器IP";
const&nbsp;char*&nbsp;mqtt_username&nbsp;=&nbsp;"mqtt账号";
const&nbsp;char*&nbsp;mqtt_password&nbsp;=&nbsp;"mqtt密码@";
const&nbsp;int&nbsp;mqtt_port&nbsp;=&nbsp;1883;
const&nbsp;char*&nbsp;clientId&nbsp;=&nbsp;"esp8266Client01";
const&nbsp;char*&nbsp;mqtt_sensor_topic&nbsp;=&nbsp;"homedht11";
const&nbsp;char*&nbsp;topic&nbsp;=&nbsp;"myhome/leds";

unsigned&nbsp;long&nbsp;last_send&nbsp;=&nbsp;0;
bool&nbsp;led1State&nbsp;=&nbsp;false;
bool&nbsp;led2State&nbsp;=&nbsp;false;

WiFiClient&nbsp;espClient;
PubSubClient&nbsp;client(espClient);

void&nbsp;setup()&nbsp;{
&nbsp;&nbsp;Serial.begin(115200);
&nbsp;&nbsp;dht.begin();
&nbsp;&nbsp;if&nbsp;(!u8g2.begin())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("OLED&nbsp;initialization&nbsp;failed");
&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(1);
&nbsp;&nbsp;}
&nbsp;&nbsp;u8g2.enableUTF8Print();
&nbsp;&nbsp;pinMode(ledPin1,&nbsp;OUTPUT);
&nbsp;&nbsp;pinMode(ledPin2,&nbsp;OUTPUT);
&nbsp;&nbsp;setupWifi();
&nbsp;&nbsp;client.setServer(mqtt_server,&nbsp;mqtt_port);
&nbsp;&nbsp;client.setCallback(callback);
}

void&nbsp;setupWifi()&nbsp;{
&nbsp;&nbsp;WiFi.mode(WIFI_STA);
&nbsp;&nbsp;WiFi.begin(ssid,&nbsp;password);

&nbsp;&nbsp;while&nbsp;(WiFi.status()&nbsp;!=&nbsp;WL_CONNECTED)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;delay(500);
&nbsp;&nbsp;&nbsp;&nbsp;Serial.print(".");
&nbsp;&nbsp;}
&nbsp;&nbsp;Serial.println("WiFi&nbsp;connected");
&nbsp;&nbsp;Serial.println("IP&nbsp;address:&nbsp;"&nbsp;+&nbsp;WiFi.localIP().toString());
}

void&nbsp;loop()&nbsp;{
&nbsp;&nbsp;if&nbsp;(!client.connected())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;reconnect();
&nbsp;&nbsp;}
&nbsp;&nbsp;client.loop();
&nbsp;&nbsp;if&nbsp;(millis()&nbsp;-&nbsp;last_send&nbsp;>&nbsp;15000)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;handleTemperatureAndHumidity();
&nbsp;&nbsp;&nbsp;&nbsp;last_send&nbsp;=&nbsp;millis();
&nbsp;&nbsp;}
&nbsp;&nbsp;displayTemperatureAndHumidity();
}

void&nbsp;reconnect()&nbsp;{
&nbsp;&nbsp;//&nbsp;Loop&nbsp;until&nbsp;we're&nbsp;reconnected
&nbsp;&nbsp;while&nbsp;(!client.connected())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Serial.print("Attempting&nbsp;MQTT&nbsp;connection...");
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Attempt&nbsp;to&nbsp;connect
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(client.connect(mqtt_sensor_topic,&nbsp;mqtt_username,&nbsp;mqtt_password))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("connected");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.subscribe(topic);
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.print("failed,&nbsp;rc=");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.print(client.state());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("&nbsp;try&nbsp;again&nbsp;in&nbsp;5&nbsp;seconds");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay(5000);&nbsp;//&nbsp;Changed&nbsp;from&nbsp;15000&nbsp;to&nbsp;5000
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}

void&nbsp;handleTemperatureAndHumidity()&nbsp;{
&nbsp;&nbsp;float&nbsp;h&nbsp;=&nbsp;dht.readHumidity();
&nbsp;&nbsp;float&nbsp;t&nbsp;=&nbsp;dht.readTemperature();
&nbsp;&nbsp;int&nbsp;moistureValue&nbsp;=&nbsp;analogRead(moistureSensorPin);
&nbsp;&nbsp;int&nbsp;moisturePercent&nbsp;=&nbsp;map(moistureValue,&nbsp;1024,&nbsp;0,&nbsp;0,&nbsp;100);
&nbsp;&nbsp;if&nbsp;(isnan(h)&nbsp;||&nbsp;isnan(t))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("Failed&nbsp;to&nbsp;read&nbsp;from&nbsp;DHT&nbsp;sensor!");
&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;}
&nbsp;&nbsp;publishSensorData(h,&nbsp;t,&nbsp;moisturePercent);
}

void&nbsp;publishSensorData(float&nbsp;humidity,&nbsp;float&nbsp;temperature,&nbsp;int&nbsp;moisturePercent)&nbsp;{
&nbsp;&nbsp;String&nbsp;payload&nbsp;=&nbsp;"{";
&nbsp;&nbsp;payload&nbsp;+=&nbsp;"\"temp\":"&nbsp;+&nbsp;String(temperature)&nbsp;+&nbsp;",";
&nbsp;&nbsp;payload&nbsp;+=&nbsp;"\"humi\":"&nbsp;+&nbsp;String(humidity)&nbsp;+&nbsp;",";
&nbsp;&nbsp;payload&nbsp;+=&nbsp;"\"moisture\":"&nbsp;+&nbsp;String(moisturePercent);
&nbsp;&nbsp;payload&nbsp;+=&nbsp;"}";
&nbsp;&nbsp;char&nbsp;attributes[100];
&nbsp;&nbsp;payload.toCharArray(attributes,&nbsp;100);
&nbsp;&nbsp;client.publish(mqtt_sensor_topic,&nbsp;attributes);
&nbsp;&nbsp;Serial.println(attributes);
}

void&nbsp;displayTemperatureAndHumidity()&nbsp;{
&nbsp;&nbsp;float&nbsp;humidity&nbsp;=&nbsp;dht.readHumidity();
&nbsp;&nbsp;float&nbsp;temperature&nbsp;=&nbsp;dht.readTemperature();
&nbsp;&nbsp;int&nbsp;moistureValue&nbsp;=&nbsp;analogRead(moistureSensorPin);
&nbsp;&nbsp;int&nbsp;moisturePercent&nbsp;=&nbsp;map(moistureValue,&nbsp;1024,&nbsp;0,&nbsp;0,&nbsp;100);
&nbsp;&nbsp;if&nbsp;(isnan(humidity)&nbsp;||&nbsp;isnan(temperature))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("Failed&nbsp;to&nbsp;read&nbsp;from&nbsp;DHT&nbsp;sensor!");
&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;}
&nbsp;&nbsp;u8g2.clearBuffer();
&nbsp;&nbsp;u8g2.setFont(u8g2_font_wqy12_t_gb2312);
&nbsp;&nbsp;u8g2.setDrawColor(1);
&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;15);
&nbsp;&nbsp;u8g2.print("湿度:&nbsp;");
&nbsp;&nbsp;u8g2.print(humidity);
&nbsp;&nbsp;u8g2.print("&nbsp;%&nbsp;&nbsp;");
&nbsp;&nbsp;if(humidity&nbsp;>=&nbsp;80){
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("潮湿");
&nbsp;&nbsp;}else&nbsp;if(humidity&nbsp;<&nbsp;79&nbsp;&&&nbsp;humidity&nbsp;>=&nbsp;50&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("舒适");
&nbsp;&nbsp;}else{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("干燥");
&nbsp;&nbsp;}
&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;30);
&nbsp;&nbsp;u8g2.print("温度:&nbsp;");
&nbsp;&nbsp;u8g2.print(temperature);
&nbsp;&nbsp;u8g2.print("&nbsp;℃&nbsp;");
&nbsp;&nbsp;if(temperature&nbsp;>=&nbsp;26){
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("好热");
&nbsp;&nbsp;}else&nbsp;if(18&nbsp;<&nbsp;temperature&nbsp;&&&nbsp;temperature&nbsp;<=&nbsp;25){
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("舒适");
&nbsp;&nbsp;}else{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("好冷");
&nbsp;&nbsp;}
&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;45);
&nbsp;&nbsp;//&nbsp;获取WiFi网络信息
&nbsp;&nbsp;u8g2.print("WiFi:&nbsp;");
&nbsp;&nbsp;u8g2.print(WiFi.SSID());
&nbsp;&nbsp;u8g2.print(WiFi.RSSI());
&nbsp;&nbsp;u8g2.print("&nbsp;dBm");

&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;60);
&nbsp;&nbsp;if&nbsp;(led1State)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("灯1:&nbsp;开");
&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("灯1:&nbsp;关");
&nbsp;&nbsp;}
&nbsp;&nbsp;if&nbsp;(led2State)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("&nbsp;灯2:&nbsp;开");
&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("&nbsp;灯2:&nbsp;关");
&nbsp;&nbsp;}
&nbsp;&nbsp;u8g2.sendBuffer();
}

void&nbsp;callback(char*&nbsp;topic,&nbsp;byte*&nbsp;payload,&nbsp;unsigned&nbsp;int&nbsp;length)&nbsp;{
&nbsp;&nbsp;Serial.print("Message&nbsp;arrived&nbsp;[");
&nbsp;&nbsp;Serial.print(topic);
&nbsp;&nbsp;Serial.print("]&nbsp;");
&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;length;&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Serial.print((char)payload[i]);
&nbsp;&nbsp;}
&nbsp;&nbsp;Serial.println();

&nbsp;&nbsp;char&nbsp;payloadStr[length&nbsp;+&nbsp;1];
&nbsp;&nbsp;memcpy(payloadStr,&nbsp;payload,&nbsp;length);
&nbsp;&nbsp;payloadStr[length]&nbsp;=&nbsp;'\0';

&nbsp;&nbsp;if&nbsp;(strcmp(topic,&nbsp;"myhome/leds")&nbsp;==&nbsp;0)&nbsp;{&nbsp;//&nbsp;确保主题匹配
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.clearBuffer();&nbsp;//&nbsp;清除缓冲区
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.setFont(u8g2_font_wqy12_t_gb2312);
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.setDrawColor(1);
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;15);
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("湿度:&nbsp;");
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print(dht.readHumidity());
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("&nbsp;%&nbsp;&nbsp;&nbsp;");
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;30);
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("温度:&nbsp;");
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print(dht.readTemperature());
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("&nbsp;℃");
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.setCursor(0,&nbsp;45);
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("土壤:&nbsp;");
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print(analogRead(moistureSensorPin));
&nbsp;&nbsp;&nbsp;&nbsp;u8g2.print("&nbsp;%");

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;使用ArduinoJson解析JSON数据
&nbsp;&nbsp;&nbsp;&nbsp;StaticJsonDocument<200>&nbsp;jsonDoc;
&nbsp;&nbsp;&nbsp;&nbsp;DeserializationError&nbsp;error&nbsp;=&nbsp;deserializeJson(jsonDoc,&nbsp;payloadStr);
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!error)&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(jsonDoc.containsKey("led1")&nbsp;&&&nbsp;jsonDoc["led1"].is<bool>())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;led1StateFromJson&nbsp;=&nbsp;jsonDoc["led1"];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(led1StateFromJson)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin1,&nbsp;HIGH);&nbsp;//&nbsp;打开LED
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led1State&nbsp;=&nbsp;true;&nbsp;//&nbsp;更新led1State状态
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin1,&nbsp;LOW);&nbsp;//&nbsp;关闭LED
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led1State&nbsp;=&nbsp;false;&nbsp;//&nbsp;更新led1State状态
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(jsonDoc.containsKey("led2")&nbsp;&&&nbsp;jsonDoc["led2"].is<bool>())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;led1StateFromJson&nbsp;=&nbsp;jsonDoc["led2"];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(led1StateFromJson)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin2,&nbsp;HIGH);&nbsp;//&nbsp;打开LED
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led2State&nbsp;=&nbsp;true;&nbsp;//&nbsp;更新led1State状态
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin2,&nbsp;LOW);&nbsp;//&nbsp;关闭LED
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led2State&nbsp;=&nbsp;false;&nbsp;//&nbsp;更新led1State状态
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.print("deserializeJson()&nbsp;failed&nbsp;with&nbsp;code&nbsp;");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.println(error.c_str());
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;//原有控制代码

&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(strcmp(payloadStr,&nbsp;"on")&nbsp;==&nbsp;0)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin1,&nbsp;HIGH);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led1State&nbsp;=&nbsp;true;
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(strcmp(payloadStr,&nbsp;"off")&nbsp;==&nbsp;0)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin1,&nbsp;LOW);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led1State&nbsp;=&nbsp;false;
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(strcmp(payloadStr,&nbsp;"1")&nbsp;==&nbsp;0)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin2,&nbsp;HIGH);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led2State&nbsp;=&nbsp;true;
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(strcmp(payloadStr,&nbsp;"0")&nbsp;==&nbsp;0)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;digitalWrite(ledPin2,&nbsp;LOW);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;led2State&nbsp;=&nbsp;false;
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial.println("Unknown&nbsp;command");
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}

更多精彩文章 欢迎关注我们


查看原文:《基于MQTT协议的物联网小基站》

评论:0   参与:  2