OLED+MQTT 实现土壤 温湿度 线上线下展示

本文为大家讲解基于MQTT协议和传感器的综合使用。希望对你的学习有所帮助。

实验目的

借助HA,实现随时随地的观看当前温度,湿度,以及土壤湿度。并借助OLED屏幕,实时显示,方便在现场检测数据。

实验设备

  • esp8266
  • dht11温湿传感器
  • 土壤传感器
  • homeassistant
  • 其他备用(后期会用到舵机、继电器)

线路连接


显示器线路
VCC -- 3V3(+)
GND -- GND(-)
SOA -- D1
SCL -- D2

DHT11线路
VCC -- 3V3(+)
GND -- GND(-)
DATA -- D5

土壤线路
VCC -- 3V3(+)
GND -- GND(-)
A0 -- A0

代码

在烧写代码之前,我们需要安装部分库。

  • U8g2 (用于显示汉字)
  • DHT11

示例代码

#include   
#include   
#include   
#include 
#include  
// 创建DHT传感器实例  
#define DHTPIN D5     // 连接DHT数据引脚到D1(GPIO5)  
#define DHTTYPE DHT11 // DHT 11  
int moistureSensorPin = A0; // 定义传感器连接的引脚
#ifdef U8X8_HAVE_HW_SPI
#include 
#endif
#ifdef U8X8_HAVE_HW_I2C
#include 
#endif  
DHT dht(DHTPIN, DHTTYPE);  
  
// OLED显示屏设置  
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D2, /* data=*/ D1, /* reset=*/ U8X8_PIN_NONE);  
/************ WIFI and MQTT 配置 ******************/
const char* ssid = "PDCN"//type your WIFI information inside the quotes
const char* password = "1234567890";
const char* mqtt_server = "192.168.123.88"; #改为你的mqtt服务器
const char* mqtt_username = "admin";
const char* mqtt_password = "admin";
const int mqtt_port = 1883;
const char* mqtt_sensor_topic = "dht11"; #订阅主题
unsigned long last_send = 0

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {  
  // 初始化串口通信,方便调试  
  Serial.begin(115200);  
    
  // 初始化DHT传感器  
  dht.begin();  
  
  // 初始化OLED显示屏  
  u8g2.begin();  
  u8g2.enableUTF8Print(); 
  setupWifi();
  client.setServer(mqtt_server, mqtt_port);
}  

// 连接 Wifi
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: ");
  Serial.println(WiFi.localIP());
}

void loop() {  

  if ( !client.connected() ) { // MQTT 是否连接成功
    reconnect();
  }
  if ( millis() - last_send > 5000 ) { // 每5秒发布一次温湿度数据
    handleTemperatureAndHumidity();
    last_send = millis();
  }
  client.loop();

  // 等待传感器稳定  
  delay(2000);  
  
  // 读取温度和湿度数据  
  float humidity = dht.readHumidity();  
  float temperature = dht.readTemperature();  
    
  // 检查是否读取失败,读取失败时返回NAN(不是一个数字)  
  if (isnan(humidity) || isnan(temperature)) {  
    Serial.println(F("Failed to read from DHT sensor!"));  
    return;  
  }  
  
  int moistureValue = analogRead(moistureSensorPin); // 读取传感器的模拟值
  // 将模拟值转换为土壤湿度百分比
  int moisturePercent = map(moistureValue, 102400100);
  // 清空显示缓冲区  
  u8g2.clearBuffer();  
  // 设置字体
  u8g2.setFont(u8g2_font_wqy12_t_gb2312);    
  // 设置文本颜色  
  u8g2.setDrawColor(1); // 白色    
  // 设置光标位置(注意:U8g2的坐标系统与Adafruit库可能不同)  
  u8g2.setCursor(015);  
  // 显示温度和湿度数据(使用中文)  
  u8g2.print("温度: ");  
  u8g2.print(humidity);  
  u8g2.print(" %   ");  
  u8g2.setCursor(030);  
  u8g2.print("温度: ");  
  u8g2.print(temperature);  
  u8g2.print(" ℃");  
  u8g2.setCursor(045);  
  u8g2.print("土壤: ");  
  u8g2.print(moisturePercent);  
  u8g2.print(" %");  
    
  // 更新显示  
  u8g2.sendBuffer();  
    
  // 等待2秒再读取一次  
  delay(2000);  
}
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");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(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(F("Failed to read from DHT sensor!"));
    return;
  }
  // 准备JSON Payload
  String payload = "{";
  payload += "\"temp\":"; payload += t; payload += ",";
  payload += "\"humi\":"; payload += h;payload += ",";
  payload += "\"turang\":"; payload += moisturePercent;
  payload += "}";

  // 发送温湿度数据
  char attributes[100];
  payload.toCharArray( attributes, 100 );
  client.publish( mqtt_sensor_topic, attributes );
  Serial.println( attributes );
}

上传代码后,我们利用MQTT客户端进行测试。

配置HA

在HA集成中添加MQTT

修改ha配置文件如下:

vim configuration.yaml

新增内容如下:

mqtt: 
 sensor: 
   - unique_id: Temperature 
     name: "Temp" 
     state_topic: "dht11" 
     suggested_display_precision: 1  
     unit_of_measurement: "℃ " 
     value_template: "{{ value_json.temp }}"
  - unique_id: Humidity 
     name: "Humi" 
     state_topic: "dht11" 
     suggested_display_precision: 1  
     unit_of_measurement: "% " 
     value_template: "{{ value_json.humi }}"

注意书写格式,空格一定要对齐。

完成配置后,重启HA

接下来,在实体中便可以看到当前设备了。

如果,想将数据入库。利用echar展示,我们可以参考下往期文章。

BREAK AWAY
往期推荐
01
一文玩转MQTT(基于esp8266 DHT11 MQTT Mysql实现)
02
物联网入门之MQTT协议(一)
03
Esp8266入门即是巅峰

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

请使用浏览器的分享功能分享到微信等