ESP32-DevKitCと DS3231を使ったRTC時計& BME280を使った温湿度・気圧計を20文字x4行LCDに表示:環境モニタ(2)

ESP32-DevKitCとRTCモジュールDS3231を使ったNTP時刻合わせLCD時計に、BOSCH社のBME280センサを使った温湿度・気圧計モジュールをI2C接続して20文字X4行のLCDモジュールに追加表示しました。

あわせて読みたい
ESP32-DevKitCでNTPサーバと時刻同期して RTCモジュール DS3231SNの時刻合わせを行うLCD時計:環境モニ... ESP32-DevKitC ESP-WROOM-32開発ボード(以下、ESP32-DevKitC)を使ってインターネット上のNTP(Network Time Protocol)サーバと時刻同期してRTC(リアルタイムクロック)...
目次

追加で集めたパーツ、結線図と組み立て(2022/4/21訂正)

集めたパーツ

ESP32-DevKitCでNTPサーバと時刻同期して RTCモジュール DS3231の時刻合わせを行うLCD時計:環境モニタ(1)」に、セ氏零度以下の-40~+85℃の範囲を測定できる BME280温湿度・気圧センサモジュールを追加しました。

#今回、追加したパーツ個数
1BME280 温湿度・気圧センサーモジュール
Vin、I2Cレベル変換回路付き
1
2ジャンパーワイヤ適量
#環境モニタ(1)で準備したパーツ個数
1ESP32-DevKitC ESP-WROOM-32開発ボード1
2DS3231SN I2C RTCモジュール1
32004 LCDモジュール 20×4キャラクタ 青
I2C I/F モジュール、バックライト付き、
バックライト調整用半固定ボリューム付き
1
4I2Cバス用双方向電圧レベル変換モジュール
(PCA9306)
1
5XL4015 可変DC-DCステップダウンコンバータ
(3個入り)
1
(手持ち)
6DC-POWER-JACK基板1
7サンハヤト ニューブレッドボード SAD-011
8ジャンパーワイヤ適量
9USBケーブル(USB A オス to microB オス)1
(手持ち)
10コイン形リチウムイオン2次電池「LIR2032」
(4個入り)
1
11スイッチングACアダプター
9V 1.3A 100~240V
1

結線図

各モジュール間をジャンパーワイヤで接続した際の結線図です。BME280 温湿度・気圧センサーモジュール(右下)と4本のジャンパー線で結線します。
網掛け部分は屋外測定用の温湿度センサ、CO2センサ、microSDカードスロットなど拡張予定箇所です。

環境モニタ(2)の結線図

実装

ブレッドボードに各モジュール(ESP32-DevKitC、DS3231、I2Cレベル変換、BME280、LCD)を実装し、モジュール の4つの端子:SCL(緑)、SDA(白)、給電(5V or 3.3V、赤)、GND(黒)をジャンパーワイヤで結線しました。

20文字x4行のLCDに統合したRTC時計と温湿度・気圧計
20文字x4行のLCDに統合したRTC時計と温湿度・気圧計。右下がBME280 温湿度・気圧センサーモジュール。

各モジュールの電源電圧とI2C信号レベルの確認(2021/12/5追記)

電源電圧を5V、I2Cバスの信号レベルは5Vを基準としました。BME280モジュール基板にはVinとI2C信号のレベル変換チップが実装されています。

#モジュールモジュールの
電源電圧
I2C
信号レベル
I2C
SCL
I2C
SDA
1ESP32-DevKitC5V
LDO内蔵:5V → 3.3V
双方向電圧レベル変換
モジュールを利用
5V<—> 3.3V 
GPIO22GPIO21
2DS3231SN 
RTC
5V
仕様:3.3V~5.5V
5V
仕様:3.3V~5.5V
印字印字
32004 LCD
I2C I/F 
5V5V印字印字
4BME2805V
LDO内蔵:5V → 3.3V
5V
双方向電圧レベル変換内臓
印字印字

BME280モジュールのI2Cアドレスの確認とI2C信号波形の観察

BME280データシートからチップの電源電圧、I2C信号レベルともに3.3V。今回、Amazonで購入したBME280モジュール(4ピン基板)は、裏面にI2C(SCLとSDA)側に5Vと3.3VのI2Cバスレベル変換回路とVin(5V)に3.3Vへのレギュレータ回路(LDO:Low Drop Out)を搭載しています。レベル変換回路では10kΩでプルアップされています。

モジュール基板の表面
モジュール基板の表面。右下のチップ型番は「692 UP」。
モジュール基板の裏面
モジュール基板の裏面。I2C信号のレベル変換回路とVinに3.3Vのレギュレータ回路を実装。

ArduinoサイトにあるI2CアドレスをスキャンするスケッチArduino Playground – I2cScannerを実行するとBME280のI2Cアドレスは0x76でした。

デジタルオシロスコープでブレッドボード上のI2C(SCLとSDA)配線ワイヤの信号波形をモニタすると約4.6Vの矩形波でした。

I2C(SCLとSDA)信号のデジタルオシロスコープ波形
I2C(SCLとSDA)信号のデジタルオシロスコープ波形

開発ツールarduino-esp32をインストール

arduino-esp32のインストール手順を別ページに纏めました。

あわせて読みたい
ESP32-DevKitCの開発ツール arduino-esp32 のインストール手順 Arduino IDE上で動作する ESP32-DevKitC の開発ツール arduino-esp32(Arduino core for the ESP32)をインストールした際の手順メモです。 arduino-esp32は、Seeed Stu...

スケッチ1:BME280センサで測った温湿度・気圧データをシリアルモニタに出力

BME280センサ(0x76)から測定データを取得してシリアルモニタに出力します。ライブラリとしてGitHub掲載の adafruit/Adafruit_BME280_Library と adafruit/Adafruit_Sensor を利用させていただきました。

Adafruit_I2CDevice.hが無いとのエラーメッセージがでた場合はadafruit/Adafruit_BusIO(Adafruit_BusIO-master.zip)をインクルードします。

ESP32_BME280_com.ino
※ここをクリックするとコード表示を開閉できます。
#include <Wire.h>
#include <Adafruit_Sensor.h>  // https://github.com/adafruit/Adafruit_Sensor
#include <Adafruit_BME280.h>  // https://github.com/adafruit/Adafruit_BME280_Library

Adafruit_BME280 bme;
float temp;
float pressure;
float humid;

void setup() {
Serial.begin(115200);
bool status;
status = bme.begin(0x76);
while (!status) {
Serial.println("BME280 sensorが使えません");
delay(1000);
}
}

void loop() {
temp=bme.readTemperature();
pressure=bme.readPressure() / 100.0F;
humid=bme.readHumidity();
Serial.print(temp);
Serial.print(" *C  ");
Serial.print(pressure);
Serial.print(" hPa  ");
Serial.print(humid);
Serial.println(" %");
delay(1000);
}

スケッチ2:RTC時計とBME280センサで測った温湿度・気圧データをLCD表示(2021/12/5修正)

NTP時刻合わせのRTC時計のスケッチとBME280温湿度・気圧センサのスケッチ1を統合して20文字 x 4行のLCDに表示するスケッチです。1行目に年月日週、2行目に時刻、3行目に気圧、4行目に温度、湿度を表示します。

ESP32_DS3232RTC_BME280_LCD.ino
※ここをクリックするとコード表示を開閉できます。
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
#include <LiquidCrystal_I2C.h> // https://github.com/johnrickman/LiquidCrystal_I2C
#include <DS3232RTC.h>         // https://github.com/JChristensen/DS3232RTC
#include <esp_sntp.h>
#include <Adafruit_Sensor.h>   // https://github.com/adafruit/Adafruit_Sensor
#include <Adafruit_BME280.h>   // https://github.com/adafruit/Adafruit_BME280_Library

DS3232RTC myRTC(false);
LiquidCrystal_I2C lcd(0x27, 20, 4);    // DS3231時計、屋内BME280表示
Adafruit_BME280 bme;   // 屋内センサ
float temp;
float pressure;
float humid;
// 2022/03/27:曜日の文字数を9文字固定に変更
const char* weekStr[7] = {"Sunday   ","Monday   ","Tuesday  ","Wednesday","Thursday ","Friday   ","Saturday "};
const char* ssid      = "your ssid";
const char* password  = "your password";
const char* ntpServer = "ntp.nict.jp";
const long  gmtOffset_sec = 32400;
const int   daylightOffset_sec = 0;

void setup() {
  struct tm timeInfo;
  Serial.begin(115200);
  myRTC.begin();
  lcd.init();
  lcd.backlight();
// ----- DS3231時計 -----
//WiFi接続
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
  lcd.print("."); // 進捗表示
  delay(500);
  }
// WiFi接続の表示
  lcd.clear();
  lcd.print("WiFi connected");
  delay(2000);
  lcd.clear();
// NTPサーバからJST取得
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  lcd.clear();
  lcd.print("JST synchro.");
  delay(2000);
  lcd.clear();
// 内蔵RTCの時刻がNTP時刻に合うまで待機
  while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET) {
    lcd.print(">"); // 進捗表示
    delay(1000);
  }
//内蔵RTC時刻 = NTP時刻の表示
  lcd.clear();
  lcd.print("Time matched");
  delay(2000);
  lcd.clear();
// 内蔵RTCの時刻の取得
  getLocalTime(&timeInfo);
// 内蔵RTCの時刻をDS3231に時刻設定
  setTime(timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec, timeInfo.tm_mday, timeInfo.tm_mon + 1, timeInfo.tm_year + 1900);
  myRTC.set(now());
//WiFi切断
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
// ----- BME280温湿度・圧力計 -----
  bool status;
  status = bme.begin(0x76);  
  while (!status) {
    Serial.println("屋内BME280 sensorが使えません");
    delay(1000);
  }
}

void loop(void) {
dispLCD();
delay(1000);
}

void dispLCD(void) {
// ----- DS3231時計 -----
// RTCから時刻取得
  tmElements_t tm;
  myRTC.read(tm);
// 時計LCD表示
    lcd.setCursor(0,0);
      lcd.print(tm.Year + 1970);
      lcd.print("/");
      lcdzeroSup(tm.Month);
      lcd.print("/");
      lcdzeroSup(tm.Day);
      lcd.print(" ");
      lcd.setCursor(11,0);
      lcd.print(weekStr[tm.Wday - 1]);
      lcd.setCursor(0,1);
      lcdzeroSup(tm.Hour);
      lcd.print(":");
      lcdzeroSup(tm.Minute);
      lcd.print(":");
      lcdzeroSup(tm.Second);
// ----- BME280温湿度・圧力計 -----
// 屋内センサ
  temp=bme.readTemperature();
  pressure=bme.readPressure() / 100.0F;
  humid=bme.readHumidity();
    lcd.setCursor(0,2);
      lcd.print("PRESS1:");
      lcd.print(pressure,1);
      lcd.print("hPa");
    lcd.setCursor(0,3);
      lcd.print("T:");
      lcd.print(temp,1);
      lcd.print("'C / H:");
      lcd.print(humid,1);
      lcd.print("%");  
}

// ----- DS3231時計 -----
// 先頭のゼロ(0)を空白に置換
void lcdzeroSup(int digit) {
if(digit < 10)
lcd.print(' '); // 空白
lcd.print(digit);
}
よかったらシェアしてね!
  • URLをコピーしました!
目次