編集履歴一覧に戻る
Takuo6712のアイコン画像

Takuo6712 が 2025年01月31日21時18分46秒 に編集

初版

タイトルの変更

+

SPRESENSEとHome Assistantを使用したスマートガスセンサーの開発

タグの変更

+

IoT

+

スマートホーム

+

BLE

+

SPRESENSE

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

ライセンスの変更

+

(MIT) The MIT License

本文の変更

+

# 概要 元々スマートホームが好きで自作のスマートリモコンやドアの開閉センサーをHome Assistant上で動作できるようにしていました。 そこで今回はSPRESENSEにガスセンサーを取り付け,オープンソースでお馴染みのHome Assistant OS上で部屋の環境がわかるようにしました! ![自作スマートリモコン](https://camo.elchika.com/019fc955c6b338d5f42d86d4407864732a7d3f60/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f64616239323131662d353530302d346266352d383238612d663430333034393566316636/)![スマートリモコンのコントロールボード](https://camo.elchika.com/d986020b904bde81e802cc2305a16c861aacdfdd/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f39363037333330632d656264392d343933352d623335302d656137313139663836633166/) # 必要部品 - SPRESENSE本体 - BME680 - BLE1507 - Raspberry Pi5(Home Assistant OS用) - ESP32(ESPHome用) # Home Assistantとは Home Assistant OS以下(HAOS)は、スマートホームのデバイスを一元管理・自動化するためのオープンソースプラットフォーム「Home Assistant」を専用のオペレーティングシステム(OS)として提供するものです。Raspberry Piや眠っているデスクトップPCなどにインストールすることで、Home Assistantの全機能を簡単に利用できます。 主な特徴: ・オールインワンパッケージ: Home Assistant OSには、OS自体、Home Assistant本体、アドオン管理機能などがすべて含まれており、追加の設定なしで利用を開始できます。 ・簡単なセットアップ: 専用のハードウェアにインストールすることで、初めてのユーザーでも直感的にセットアップが可能です。 ・アドオン機能: Node-REDやMosquitto(MQTTブローカー)などのアドオンをGUI上で簡単に追加・管理できます。 # Home AssistantでBLEを使用する方法 残念ながらHAOSではデフォルトでBLEに対応していません。そのためESPHomeという追加アドオンを用いてESPとBLEデバイス間で通信を行います。 設定→アドオン→「ESPHome」で検索します。ヒットしたものをインストールすれば自動的に使えるようになります。よく使用する人はサイドバーに表示も有効にすると楽になります。 ![キャプションを入力できます](https://camo.elchika.com/2cacbbc0ec60cd058950a4b48647149f6f474d9e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f31313830643562372d643365322d346333312d396634372d663561656462333564623263/) # デバイスの追加方法 ESPHomeを開いてNEW DEVICEをクリックし任意の名前を付けて保存することでデバイスを追加できます。 そうして出力されたYAMLファイルをいじりながら好きなようにカスタマイズすることが可能です。 以下にBLEを使用する際のYAMLファイルを乗せときます。 自分はこれでドアの開閉状況を検知しています。 ```ESPHome BLE設定ファイル sensor: - platform: ble_client type: characteristic id: door_sensor name: "Door Sensor" ble_client_id: door_ble_client service_uuid: "123F" # ドアサービスUUID(16進数を文字列で指定) characteristic_uuid: "234F" # ドアキャラクタリスティックUUID notify: true icon: "mdi:door" - platform: ble_client type: characteristic id: battery_level name: "Battery Level" ble_client_id: door_ble_client service_uuid: "180F" # バッテリーサービスUUID characteristic_uuid: "2A19" # バッテリーレベルキャラクタリスティックUUID notify: true unit_of_measurement: "%" accuracy_decimals: 0 icon: "mdi:battery" binary_sensor: - platform: template name: "Door Status" lambda: |- if (id(door_sensor).state == 1) { return true; // ドアが閉まっている } else { return false; // ドアが開いている } device_class: door ble_client: - mac_address: "CE:A5:FD:BA:41:58" # BLEデバイスのMACアドレスを指定 id: door_ble_client ``` ![ドアセンサーコントロールボード](https://camo.elchika.com/a4c15daff3609f0cd5768f5d65b262ee67d6bcff/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f39663938643062342d643262622d343535652d623164342d643536313732646538346432/) # SPRENSENSE側の処理 1. **ガスセンサーの動作確認** Adafruit_BME680ライブラリーを用いて動作確認します。 [https://github.com/adafruit/Adafruit_BME680/tree/master](url) 基本的にはライブラリーのexampleを参考に書いただけです。 ```arduino:BME680テストプログラム #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME680.h> #define BME680_I2C_ADDR 0x77 Adafruit_BME680 bme; void setup() { Serial.begin(115200); while (!Serial); // シリアル通信が開くまで待機 Serial.println("BME680 センサーの初期化中..."); if (!bme.begin(BME680_I2C_ADDR)) { Serial.println("BME680の初期化に失敗しました。接続を確認してください!"); while (1); } // センサーの設定 bme.setTemperatureOversampling(BME680_OS_8X); bme.setHumidityOversampling(BME680_OS_2X); bme.setPressureOversampling(BME680_OS_4X); bme.setIIRFilterSize(BME680_FILTER_SIZE_3); bme.setGasHeater(320, 150); } void loop() { Serial.println("データ取得中..."); // 測定リクエスト if (!bme.performReading()) { Serial.println("センサーデータの取得に失敗しました!"); return; } // データ表示 Serial.print("温度: "); Serial.print(bme.temperature); Serial.println(" °C"); Serial.print("湿度: "); Serial.print(bme.humidity); Serial.println(" %"); Serial.print("気圧: "); Serial.print(bme.pressure / 100.0); Serial.println(" hPa"); Serial.print("ガス抵抗値: "); Serial.print(bme.gas_resistance / 1000.0); Serial.println(" kΩ"); Serial.println("------------------------------------"); delay(2000); } ``` 2. **実行結果** ![BME680実行結果](https://camo.elchika.com/73d5c0bf2e22c6a55f343cf9291f754ba8ea4c42/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f61393366376432322d356332312d343566362d613262642d336465613863646366333561/) 3. **BLEデバイスの動作確認** こちらはTomonobuHayakawa様が出してるBLE用exampleを使用して動作確認します。今回はESP32がセントラルのためSPRESENSE側はペリフェラルになります。 [https://github.com/TomonobuHayakawa/BLE1507_Arduino](url) ```arduino:SPRESENSE側のコード #include <Wire.h> #include "Adafruit_BME680.h" #include "BLE1507.h" #define UUID_SERVICE 0xFFF0 #define UUID_CHAR 0xFFF1 static BT_ADDR addr = {{0x19, 0x84, 0x06, 0x14, 0xAB, 0xCD}}; static char ble_name[BT_NAME_LEN] = "SPRESENSE-GAS-INT"; Adafruit_BME680 bme; BLE1507 *ble; void setup() { Wire.begin(); if (!bme.begin(0x77)) { // センサ初期化失敗時の処理 while (true) { sleep(1); } } // BME680設定 (必要に応じて) bme.setTemperatureOversampling(BME680_OS_8X); bme.setHumidityOversampling(BME680_OS_4X); bme.setPressureOversampling(BME680_OS_4X); bme.setIIRFilterSize(BME680_FILTER_SIZE_3); bme.setGasHeater(320, 150); // BLE初期化 ble = BLE1507::getInstance(); ble->begin(ble_name, addr, UUID_SERVICE, UUID_CHAR); } void loop() { // BME680計測 if (!bme.performReading()) { sleep(1); return; } // ガス抵抗[Ω] → kΩ float gas_kohm = bme.gas_resistance / 1000.0f; // 例: kΩを 0.1kΩ刻みにスケーリング (10.2kΩ → 102) // 16ビット(0~65535)に収める uint16_t gas_scaled = (uint16_t)(gas_kohm * 10.0f + 0.5f); // BLE1507は「writeNotify(uint8_t* data, uint32_t size)」のみ // 2バイトの整数を送る ble->writeNotify((uint8_t*)&gas_scaled, 2); printf("Gas=%.1f kΩ => scaled=%u\n", gas_kohm, gas_scaled); sleep(1); } ``` ```arduino:YAML sensor: - platform: ble_client type: characteristic id: door_sensor name: "Door Sensor" ble_client_id: door_ble_client service_uuid: "123F" # ドアサービスUUID characteristic_uuid: "234F" # ドアキャラクタリスティックUUID notify: true icon: "mdi:door" - platform: ble_client type: characteristic id: battery_level name: "Battery Level" ble_client_id: door_ble_client service_uuid: "180F" # バッテリーサービスUUID characteristic_uuid: "2A19" # バッテリーレベルキャラクタリスティックUUID notify: true unit_of_measurement: "%" accuracy_decimals: 0 icon: "mdi:battery" # ガス抵抗 (kΩ) を受け取る - platform: ble_client type: characteristic id: gas_level ble_client_id: spresense_ble_client service_uuid: "FFF0" characteristic_uuid: "FFF1" notify: true name: "Gas Value" unit_of_measurement: "kΩ" accuracy_decimals: 2 binary_sensor: - platform: template name: "Door Status" lambda: |- if (id(door_sensor).state == 1) { return true; // ドアが閉まっている } else { return false; // ドアが開いている } device_class: door ble_client: - mac_address: "CE:A5:FD:BA:41:58" # ドアセンサのMACアドレス id: door_ble_client - mac_address: "CD:AB:14:06:84:19" # SPRESENSEのMACアドレス(例) id: spresense_ble_client ``` # 実行結果 ![キャプションを入力できます](https://camo.elchika.com/57216a961fe1d9dbed20d44179c363a68f75384a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f32626165616239342d633864392d343033642d393966372d3437396331663539386238632f35343034346135322d643065662d346162372d383231312d346235646330653535666161/)