気の向くままに辿るIT/ICT/IoT
IoT・電子工作

ESP32で温湿度センサ値をMQTT Publish

ホーム前へ次へ
ESP8266って?

ESP32で温湿度センサ値をMQTT Publish

ESP32で温湿度センサ値をMQTT Publish

2025/10/06

 ESP32とAHT20+BMP280モジュールやDHT11モジュールを使って温度、湿度、大気圧等をMQTT Publishしてみた話。

 とりあえず、測定間隔(タイマー)は20分、測定後はディープスリープ。

 当該デバイスは、必要数だけ配線、何らかの筐体に入れ、スケッチアップ後、各所に設置するだけ。

 以後は、今回、MQTTブローカーをMosquittoとしたラズパイサーバ上での作業になります。

目的

  1. 居室や屋外など複数の場所に一定間隔で計測する当該温湿度センサーを設置、計測都度、計測値を無線でMQTTブローカーとしたラズパイサーバにパブリッシュ
  2. ラズパイサーバ上でNode.js+JavaScriptによるデーモンで受けて各MQTT受信データをRDBにINSERT
  3. 同じくNode.js+JavaScriptのデーモンによるWebサーバにアクセスするたびに指定したMQTTのTOPICに対応する各所の最新データを1件ずつ取得しつつ、当該データはもとより、これらを基にCSSでグラフ化

 結果、当該デバイスを配置した各所の温湿度(や大気圧)一覧をブラウザに表示し可視化、モニタリングするため。

 尚、ファイアウォールが有効でLAN内の他デバイスからアクセスしたい場合は、MQTTサーバ、Webサーバなど、必要な通信ポートを許可(、必要なら再起動)しておく必要があります。

材料

 モジュール、センサー、ワイヤをAliExpressで調達したとしても最近の物価だと1セット1000円ちょい超えるくらいですかね。

 たくさん設置しただけに、改めて計算してみたら、意外と衝撃的...と一瞬思ったけど外と家中の温湿度環境モニタ全体としての満足度といい、相応以上の価値はあるかと納得。

 電池駆動にしたいと思うことは度々ある中、今回は、間欠動作+ディープスリープで良いとは言え、数もあり、それでできる以上に電池交換間隔を長くしたい...、ならばボード上のLEDを切るしかないのか...、いや、それができたとしても、もっとと思うと尚更大変そうなので、やむなくUSB電源としました。

配線・スケッチ

ESP32AHT20+BMP280
3.3VVDD
GPIO 21SDA
GPIO 22SCK
GNDGND
ESP32DHT11
3.3VVCC
GPIO 13DATA
GNDGND

 ESP32とAHT20/BMP280、DHT11の配線は上記、スケッチは下記の通りです。

 Wi-FiやMQTT含む各種パラメータは、必要に応じ、要変更。

#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_AHTX0.h>
#include "EspMQTTClient.h"
 
#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP  1200
//#define TIME_TO_SLEEP  5
 
#define WIFI_SSID "ANY_SSID"
#define WIFI_PASSWORD "ANY_PASSPHRASE"
 
 
#define MQTT_CLIENT_NAME "Balcony_Temp_Humi"
#define MQTT_TOPICS_TEMPHUMI "temp_humi/outer/balc"
 
//#define MQTT_CLIENT_NAME "Kitchen_Room_Temp_Humi"
//#define MQTT_TOPICS_TEMPHUMI "temp_humi/room/kitc"
 
//#define MQTT_CLIENT_NAME "Living_Dining_Room_Temp_Humi"
//#define MQTT_TOPICS_TEMPHUMI "temp_humi/room/ld"
 
const char  TOPICS[] = MQTT_TOPICS_TEMPHUMI;
 
//#define MQTT_HOST_IP IPAddress(***, ***, ***, ***)
#define MQTT_HOST_IP "***.***.***.***"
#define MQTT_HOST_PORT 1883  // MQTTデフォルトポート
#define  MQTT_USER_NAME ""  // 省略可
#define  MQTT_PASSWORD ""  // 省略可
 
Adafruit_BMP280 bmp;
 
Adafruit_AHTX0 myAHT20;
 
EspMQTTClient client(
  WIFI_SSID,
  WIFI_PASSWORD,
  MQTT_HOST_IP,
  MQTT_USER_NAME,
  MQTT_PASSWORD,
  MQTT_CLIENT_NAME,
  MQTT_HOST_PORT
);
 
uint8_t qos = 1;
 
void setup() {
  Serial.begin(115200);
  Serial.println(F("AHT20+BMP280 test"));
 
  while (myAHT20.begin() != true) {
    Serial.println(F("AHT20 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
    delay(5000);
  }
  Serial.println(F("AHT20 OK"));
  
  if (!bmp.begin()) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    while (1);
  }
 
  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
}
 
void onMessageReceived(const String& msg) {
  Serial.print("Message Received & deep sleep");
  //Serial.println(msg);
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}
 
void onConnectionEstablished() {
  Serial.println("Connection Established.");
  Serial.println("publish.");
 
  sensors_event_t humidity, temp;
  myAHT20.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  Serial.print("Temp BMP280: "); Serial.print(bmp.readTemperature()); Serial.println(" degrees C");
  Serial.print("Temp AHT20: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
  //Serial.print("Pressure: "); Serial.print(bmp.readPressure()); Serial.println(" Pa");
 
  String message = (String)bmp.readTemperature() + " " + (String)humidity.relative_humidity + " " + (String)bmp.readPressure();
  Serial.print("TOPICS : " + (String)TOPICS + " | ");
  Serial.println("message : " + message);
  
  Serial.println("Receiving Message ....");
  //client.subscribe(TOPICS, [] (const String &payload)  {
  //  Serial.println(payload);
  //});
  client.subscribe(TOPICS, onMessageReceived, qos);
 
  client.publish(TOPICS, message);
}
 
void loop() {
  client.loop();
}

 ESP32 + AHT20/BMP280モジュールのスケッチがこちら、ライブラリは、Adafruit AHTX0 LibraryAdafruit BMP280 Libraryplapointe6/EspMQTTClient Libraryを使用。

#include <Wire.h>
#include <DHT11.h>
#include "EspMQTTClient.h"
 
#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP  1200
//#define TIME_TO_SLEEP  5
 
#define WIFI_SSID "ANY_SSID"
#define WIFI_PASSWORD "ANY_PASSPHRASE"
 
 
#define MQTT_CLIENT_NAME "ABC_Room_Temp_Humi"
#define MQTT_TOPICS_TEMPHUMI "temp_humi/room/abc"
 
const char  TOPICS[] = MQTT_TOPICS_TEMPHUMI;
 
//#define MQTT_HOST_IP IPAddress(***, ***, ***, ***)
#define MQTT_HOST_IP "***.***.***.***"
#define MQTT_HOST_PORT 1883
 
#define DHTPIN 13
 
DHT11 dht(DHTPIN);
 
EspMQTTClient client(
  WIFI_SSID,
  WIFI_PASSWORD,
  MQTT_HOST_IP,
  "",   // MQTT Username 省略可
  "",   // MQTT Password 省略可
  MQTT_CLIENT_NAME,
  MQTT_HOST_PORT
);
 
uint8_t qos = 1; // なぜか2だとその後publishされず止まる
 
void setup() {
  Serial.begin(115200);
  Serial.println(F("DHT11 test"));
}
 
void onMessageReceived(const String& msg) {
  Serial.print("Message Received & deep sleep");
  //Serial.println(msg);
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}
 
void onConnectionEstablished() {
  delay(2000);
 
  int temperature = 0;
  int humidity = 0;
 
  int result = dht.readTemperatureHumidity(temperature, humidity);
 
  if (result == 0) {
      Serial.print("Temperature: ");
      Serial.print(temperature);
      Serial.print(" °C\tHumidity: ");
      Serial.print(humidity);
      Serial.println(" %");
  } else {
      Serial.println(DHT11::getErrorString(result));
  }
 
  String message = (String)temperature + ".00 " + (String)humidity + ".00";
  Serial.print("TOPICS : " + (String)TOPICS + " | ");
  Serial.println("message : " + message);
  
  Serial.println("Receiving Message ....");
  //client.subscribe(TOPICS, [] (const String &payload)  {
  //  Serial.println(payload);
  //});
  client.subscribe(TOPICS, onMessageReceived, qos);
 
  client.publish(TOPICS, message);
}
 
void loop() {
  client.loop();
}

 ESP32 + DHT11のスケッチがこちら、ライブラリは、dhrubasaha08/DHT11plapointe6/EspMQTTClient Libraryを使用。

ホーム前へ次へ