diff --git a/firmware/SensorLogger.cpp b/firmware/SensorLogger.cpp index ee9f35d..9f388ce 100644 --- a/firmware/SensorLogger.cpp +++ b/firmware/SensorLogger.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace { @@ -24,6 +25,11 @@ BH1750 bh1750; bool aht20Ready = false; bool bh1750Ready = false; +bool isI2cDevicePresent(uint8_t address) { + Wire.beginTransmission(address); + return Wire.endTransmission() == 0; +} + bool isLeapYear(int year) { // 4年ごと。ただし100年ごとは除き、400年ごとはうるう年です。 return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; @@ -72,9 +78,14 @@ void SensorLogger::begin(uint8_t soilPin) { pinMode(soilPin_, INPUT); analogReadResolution(12); - // センサーの初期化に成功したかを保存します。 - aht20Ready = aht20.begin(); - bh1750Ready = bh1750.begin(BH1750::CONTINUOUS_HIGH_RES_MODE); + // センサーが接続されているときだけ初期化します。 + // 未接続時にライブラリへアクセスすると、不要なI2Cエラーや待ち時間が発生します。 + if (isI2cDevicePresent(0x38)) { + aht20Ready = aht20.begin(); + } + if (isI2cDevicePresent(0x23)) { + bh1750Ready = bh1750.begin(BH1750::CONTINUOUS_HIGH_RES_MODE); + } // ESP32固有の番号を名前に加え、同じ名前の機器と区別します。 uint64_t mac = ESP.getEfuseMac(); diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 0ca1e35..7ecb8c1 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -23,6 +23,12 @@ int currentVolumePercent = 0; // 音量(0〜100%) bool bluetoothConnected = false; bool musicPlaying = false; unsigned long lastDisplayUpdate = 0; +bool oledReady = false; + +bool isI2cDevicePresent(uint8_t address) { + Wire.beginTransmission(address); + return Wire.endTransmission() == 0; +} // UTF-8の文字列を1文字ずつ描画します。 // フォントにない文字は、フォントに頼らず四角形を直接描きます。 @@ -93,6 +99,10 @@ void drawUtf8WithTofu(uint8_t x, uint8_t y, const String& text) { // OLEDの内容を現在の状態に合わせて描き直します。 void updateDisplay() { + if (!oledReady) { + return; + } + u8g2.clearBuffer(); // 音楽を再生していないときは、センサーの情報を表示します。 @@ -213,11 +223,21 @@ void setup() { // I2Cの配線を設定します。Wire.begin(SDA, SCL)の順です。 // Wire.begin(21, 22); Wire.begin(19, 5); // SDA=19, SCL=5 開発用ボードの配線 + Wire.setTimeOut(50); - - // OLEDを使える状態にします。 - u8g2.begin(); - u8g2.enableUTF8Print(); // UTF-8(日本語)描画を有効化 + // OLEDが接続されているときだけ初期化と描画を行います。 + uint8_t oledAddress = 0; + if (isI2cDevicePresent(0x3C)) { + oledAddress = 0x3C; + } else if (isI2cDevicePresent(0x3D)) { + oledAddress = 0x3D; + } + if (oledAddress != 0) { + u8g2.setI2CAddress(oledAddress << 1); + u8g2.begin(); + u8g2.enableUTF8Print(); // UTF-8(日本語)描画を有効化 + oledReady = true; + } sensorLogger.begin(32); updateDisplay();