xiao esp32c3 + sht41 + oledで電池運用の実験

今回のガジェットのハード構成。

開発ツールArduino IDE
CPUXIAO ESP32C3
表示器0.96” SSD1306 128×64 OLED
温湿度センサーSHT41

必要なライブラリのインストール

  • U8g2 (by oliver) – OLED制御用
  • Sensirion I2C SHT4x (by Sensirion) – センサー用

追加のボードマネージャーURLを登録(未実施の場合)

今回使うCPUボードはXIAO ESP32C3なのでボードマネージャーに下記URLを加える。

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  1. Arduino IDEのメニューから ファイル > 基本設定 (Preferences) を開きます。
  2. 「追加のボードマネージャーのURL」の欄に、以下のURLを貼り付けて「OK」を押します。

システムの概要

0.96インチの画面で視認性を確保するには、標準のライブラリ(Adafruit_GFXなど)のデフォルトフォントは拡大すると線がガタガタになりやすいため、今回は美しく、かつ大きなサイズが指定できる「U8g2」ライブラリを使うことにする。

電池運用を実現するためにディープスリープを用いて省電力化を行う。

Arduinoプログラム

// 電池運用のためにディープスリープを使った。
// 大きいサイズのフォントを使うため表示には"U8G2"ライブラリを使った。
// このプログラムはGeminiに作ってもらったが、提示されたプログラムを修正した。
// 表示のX位置を40ドット見具へずらした。
// スリープ時間を1分から15秒に修正した。
// Version 1.0

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <SensirionI2cSht4x.h>

// 測定・スリープの間隔(秒)
#define TIME_TO_SLEEP  15 

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
SensirionI2cSht4x sht4x;

void setup() {
  // スリープからの復帰時はここからスタートします
  Wire.begin(D4, D5);
  
  u8g2.begin();
  sht4x.begin(Wire, SHT40_I2C_ADDR_44);

  float temperature, humidity;
  uint16_t error;

  // 1. センサー値の読み取り
  error = sht4x.measureHighPrecision(temperature, humidity);

  // 2. OLEDへの表示
  u8g2.clearBuffer();
  if (error) {
    u8g2.setFont(u8g2_font_ncenB08_tr);
    u8g2.drawStr(0, 20, "Sensor Error");
  } else {
    u8g2.setFont(u8g2_font_logisoso24_tf); 
    //u8g2.setCursor(0, 28);
    u8g2.setCursor(40, 28);
    u8g2.print(temperature, 1);
    u8g2.setFont(u8g2_font_helvB12_tr);
    u8g2.print(" 'C");

    u8g2.drawHLine(0, 31, 128);

    u8g2.setFont(u8g2_font_logisoso24_tf);
    //u8g2.setCursor(0, 62);
    u8g2.setCursor(40, 62);
    u8g2.print(humidity, 1);
    u8g2.setFont(u8g2_font_helvB12_tr);
    u8g2.print(" %");
  }
  u8g2.sendBuffer();

  // 3. 次の起動タイマーを設定してディープスリープに入る
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 1000000ULL); // マイクロ秒単位
  esp_deep_sleep_start();
}

void loop() {
  // ディープスリープに入るため、ここは実行されません
}