概要
元々スマートホームが好きで自作のスマートリモコンやドアの開閉センサーをHome Assistant上で動作できるようにしていました。
そこで今回はSPRESENSEにガスセンサーを取り付け,オープンソースでお馴染みのHome Assistant OS上で部屋の環境がわかるようにしました!
必要部品
- 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」で検索します。ヒットしたものをインストールすれば自動的に使えるようになります。よく使用する人はサイドバーに表示も有効にすると楽になります。
デバイスの追加方法
ESPHomeを開いてNEW DEVICEをクリックし任意の名前を付けて保存することでデバイスを追加できます。
そうして出力されたYAMLファイルをいじりながら好きなようにカスタマイズすることが可能です。
以下にBLEを使用する際のYAMLファイルを乗せときます。
自分はこれでドアの開閉状況を検知しています。
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
SPRENSENSE側の処理
- ガスセンサーの動作確認
Adafruit_BME680ライブラリーを用いて動作確認します。
https://github.com/adafruit/Adafruit_BME680/tree/master
基本的にはライブラリーのexampleを参考に書いただけです。
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);
}
-
BLEデバイスの動作確認
こちらはTomonobuHayakawa様が出してるBLE用exampleを使用して動作確認します。今回はESP32がセントラルのためSPRESENSE側はペリフェラルになります。
https://github.com/TomonobuHayakawa/BLE1507_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);
}
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
-
Takuo6712
さんが
2025/01/31
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する