首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于MQTT协议的物联网小基站

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

作者头像
逍遥子大表哥
发布2025-07-28 20:04:42
发布2025-07-28 20:04:42
2550
举报
文章被收录于专栏:kali blogkali blog

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

线路连接说明

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

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

关于主题

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

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

配置小程序

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

同理,可接入HA

#完整代码

代码语言:javascript
复制
#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] = '\0';

  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");
    }
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 kali笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线路连接说明
  • 关于主题
  • 配置小程序
  • 同理,可接入HA
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档