本文为大家分析基于MQTT协议的物联网基站。通过mqtt实现接入微信小程序和HA。
线路连接说明
-
D5
-->DHT11接口 -
D6
-->1号灯 -
D6
-->2号灯 -
A0
-->土壤传感器 -
D1
-->显示器SDA -
D2
-->显示器SCL
注意,本示例中,因没有添加土壤传感器,在代码中进行了注释。需要开启,去掉注释就行了。
关于主题
订阅主题为homedht11
用于接收温湿度数据。格式为json类型。
发布主题为myhome/leds
0
和1
空控制1号灯。on
和off
控制2号灯。
配置小程序
可以移步之前的文章《基于MQTT协议的微信小程序 上手指南》
同理,可接入HA
#完整代码
#include <Arduino.h>
#include <U8g2lib.h>
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
// 定义引脚和传感器类型
#define DHTPIN D5
#define DHTTYPE DHT11
int moistureSensorPin = A0;
const int ledPin1 = D6;
const int ledPin2 = D7;
DHT dht(DHTPIN, DHTTYPE);
// OLED显示屏设置
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, D2, D1, U8X8_PIN_NONE);
// WIFI and MQTT 配置
const char* ssid = "你的WiFi";
const char* password = "WiFi密码";
const char* mqtt_server = "mqtt服务器IP";
const char* mqtt_username = "mqtt账号";
const char* mqtt_password = "mqtt密码@";
const int mqtt_port = 1883;
const char* clientId = "esp8266Client01";
const char* mqtt_sensor_topic = "homedht11";
const char* topic = "myhome/leds";
unsigned long last_send = 0;
bool led1State = false;
bool led2State = false;
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
dht.begin();
if (!u8g2.begin()) {
Serial.println("OLED initialization failed");
while (1);
}
u8g2.enableUTF8Print();
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
setupWifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void setupWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (millis() - last_send > 15000) {
handleTemperatureAndHumidity();
last_send = millis();
}
displayTemperatureAndHumidity();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(mqtt_sensor_topic, mqtt_username, mqtt_password)) {
Serial.println("connected");
client.subscribe(topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000); // Changed from 15000 to 5000
}
}
}
void handleTemperatureAndHumidity() {
float h = dht.readHumidity();
float t = dht.readTemperature();
int moistureValue = analogRead(moistureSensorPin);
int moisturePercent = map(moistureValue, 1024, 0, 0, 100);
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
publishSensorData(h, t, moisturePercent);
}
void publishSensorData(float humidity, float temperature, int moisturePercent) {
String payload = "{";
payload += ""temp":" + String(temperature) + ",";
payload += ""humi":" + String(humidity) + ",";
payload += ""moisture":" + String(moisturePercent);
payload += "}";
char attributes[100];
payload.toCharArray(attributes, 100);
client.publish(mqtt_sensor_topic, attributes);
Serial.println(attributes);
}
void displayTemperatureAndHumidity() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
int moistureValue = analogRead(moistureSensorPin);
int moisturePercent = map(moistureValue, 1024, 0, 0, 100);
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy12_t_gb2312);
u8g2.setDrawColor(1);
u8g2.setCursor(0, 15);
u8g2.print("湿度: ");
u8g2.print(humidity);
u8g2.print(" % ");
if(humidity >= 80){
u8g2.print("潮湿");
}else if(humidity < 79 && humidity >= 50 ){
u8g2.print("舒适");
}else{
u8g2.print("干燥");
}
u8g2.setCursor(0, 30);
u8g2.print("温度: ");
u8g2.print(temperature);
u8g2.print(" ℃ ");
if(temperature >= 26){
u8g2.print("好热");
}else if(18 < temperature && temperature <= 25){
u8g2.print("舒适");
}else{
u8g2.print("好冷");
}
u8g2.setCursor(0, 45);
// 获取WiFi网络信息
u8g2.print("WiFi: ");
u8g2.print(WiFi.SSID());
u8g2.print(WiFi.RSSI());
u8g2.print(" dBm");
u8g2.setCursor(0, 60);
if (led1State) {
u8g2.print("灯1: 开");
} else {
u8g2.print("灯1: 关");
}
if (led2State) {
u8g2.print(" 灯2: 开");
} else {
u8g2.print(" 灯2: 关");
}
u8g2.sendBuffer();
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
char payloadStr[length + 1];
memcpy(payloadStr, payload, length);
payloadStr[length] = ' ';
if (strcmp(topic, "myhome/leds") == 0) { // 确保主题匹配
u8g2.clearBuffer(); // 清除缓冲区
u8g2.setFont(u8g2_font_wqy12_t_gb2312);
u8g2.setDrawColor(1);
u8g2.setCursor(0, 15);
u8g2.print("湿度: ");
u8g2.print(dht.readHumidity());
u8g2.print(" % ");
u8g2.setCursor(0, 30);
u8g2.print("温度: ");
u8g2.print(dht.readTemperature());
u8g2.print(" ℃");
u8g2.setCursor(0, 45);
u8g2.print("土壤: ");
u8g2.print(analogRead(moistureSensorPin));
u8g2.print(" %");
// 使用ArduinoJson解析JSON数据
StaticJsonDocument<200> jsonDoc;
DeserializationError error = deserializeJson(jsonDoc, payloadStr);
if (!error) {
if (jsonDoc.containsKey("led1") && jsonDoc["led1"].is<bool>()) {
bool led1StateFromJson = jsonDoc["led1"];
if (led1StateFromJson) {
digitalWrite(ledPin1, HIGH); // 打开LED
led1State = true; // 更新led1State状态
} else {
digitalWrite(ledPin1, LOW); // 关闭LED
led1State = false; // 更新led1State状态
}
}
if (jsonDoc.containsKey("led2") && jsonDoc["led2"].is<bool>()) {
bool led1StateFromJson = jsonDoc["led2"];
if (led1StateFromJson) {
digitalWrite(ledPin2, HIGH); // 打开LED
led2State = true; // 更新led1State状态
} else {
digitalWrite(ledPin2, LOW); // 关闭LED
led2State = false; // 更新led1State状态
}
}
} else {
Serial.print("deserializeJson() failed with code ");
Serial.println(error.c_str());
}
//原有控制代码
if (strcmp(payloadStr, "on") == 0) {
digitalWrite(ledPin1, HIGH);
led1State = true;
} else if (strcmp(payloadStr, "off") == 0) {
digitalWrite(ledPin1, LOW);
led1State = false;
} else if (strcmp(payloadStr, "1") == 0) {
digitalWrite(ledPin2, HIGH);
led2State = true;
} else if (strcmp(payloadStr, "0") == 0) {
digitalWrite(ledPin2, LOW);
led2State = false;
} else {
Serial.println("Unknown command");
}
}
}
更多精彩文章 欢迎关注我们
原文始发于微信公众号(kali笔记):基于MQTT协议的物联网小基站
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论