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

admin 2025年1月20日19:51:12评论9 views字数 6673阅读22分14秒阅读模式

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

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

线路连接说明

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

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

关于主题

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

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

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

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

配置小程序

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

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

同理,可接入HA

基于MQTT协议的物联网小基站#完整代码

#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, 102400100);
  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, 102400100);
  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(015);
  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(030);
  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(045);
  // 获取WiFi网络信息
  u8g2.print("WiFi: ");
  u8g2.print(WiFi.SSID());
  u8g2.print(WiFi.RSSI());
  u8g2.print(" dBm");
 
  u8g2.setCursor(060);
  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(015);
    u8g2.print("湿度: ");
    u8g2.print(dht.readHumidity());
    u8g2.print(" %   ");
    u8g2.setCursor(030);
    u8g2.print("温度: ");
    u8g2.print(dht.readTemperature());
    u8g2.print(" ℃");
    u8g2.setCursor(045);
    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协议的物联网小基站

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月20日19:51:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   基于MQTT协议的物联网小基站https://cn-sec.com/archives/3652125.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息