Nano 33 BLE Senseをデータ入力に使う<BLE>①温湿度センサ<BLEペリフェラル>
今まで、MATLAB Support Package for Arduino を使ったデータ入力を行いました。ここから、Nano 33 BLE SenseボードをBLEペリフェラルにし、センサをつなぎます。matlabの動くPCでBLEセントラルのプログラムを作成し、各種センサの値を受信します。
Nano 33 BLE Senseは、MATLAB Support Package for Arduinoでもサポートされています。ただ、執筆時点、国内では扱っているところがないので、arduino.ccから購入します。
CPUはnRF52840で、モジュールはNINA-B306で、技適はあります。
●環境
- matlab home License R2021b
- Arduino IDE 1.8.16
- Arduino BLEライブラリ 1.2.1
- Windows 10 Pro 21H1 メモリ40Gバイト
●BLEの概略
Bluetoothの4.0でBLE(Bluetooth Low Energy)が規格化されました。現在、4.0->5.xといろいろな付加価値のある規格になっています。
Arduino BLEは、nRF52XXXとu-blox NINA-W102のBLE 4をサポートしています。
https://www.arduino.cc/en/Reference/ArduinoBLE
BLEは、一番外側がGATTで、その中に複数のServiceがあります。Serviceの中に複数のCharacteristicsがあるという構造をしています。Descriptorはあってもなくてもかまいません。ServiceとCharacteristicsにはユニークなUUIDが振られています。DescriptorのUUIDは登録された16ビットのUUIDを使うことが多いようです。
PCやタブレット機器が家庭内に入っているので、メーカの使っているUUIDを避けて、ユニークなUUIDを振り出してくれるサイトもあります。
スケッチの記述手順は、大まかには、次の流れになります。
- SERVICE UUIDを作成し、有効にする
- Characteristic UUIDを作成し、有効にする
- Descriptor UUIDを作成し、有効にする
- setup(){}でsetAdvertisedService()
- addCharacteristic()でCharacteristicを登録する
- addDescriptor()でDescriptorを登録する
- addService()でServiceを登録する
- (writeValue(xx)で初期値を書き込む)
- advertise()でアドバタイジングを実行し、セントラルからの接続を待つ
- loop(){}でセントラルからの接続があるまでループする
- 接続されたら、最新データをwriteValue(xx)で書き込む
●温湿度を扱う
Nano 33 BLE SenseをBLEペリフェラルにする事例は、次の連載にあります。
Nano 33 BLE Senseでマルチセンサ・ペリフェラルを作る (1) BLEとは
から
Nano 33 BLE Senseでマルチセンサ・ペリフェラルを作る (7) 9軸慣性センサ IMU LSM9DS1
マイコン・ボードNano 33 BLE Senseには、次のようにいろいろなセンサが搭載されています。
●温湿度センサHTS221のおもなスペック
- 電源電圧 1.7~3.6V
- 湿度 確度±3.5%RH、分解能0.004%RH
- 温度 確度±0.5℃、分解能0.016℃
- インターフェース I2C(0~400kHz)、SPI(最大10MHz)
- スレーブ・アドレス 0x5f(固定)
●接続
USBケーブルで、PCと接続します。
●スケッチ①
ライブラリ管理でHTS221を検索するとArduino_HTS221が見つかります。インストールします。サンプル例も一緒にインストールされているので、必要な部分だけ抜き出しました。
#include <Arduino_HTS221.h>
void setup() {
Serial.begin(9600);
while (!Serial);
if (!HTS.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
}
void loop() {
float temperature = HTS.readTemperature();
float humidity = HTS.readHumidity();
Serial.println(temperature);
Serial.println(humidity);
delay(1000);
}
実行中の様子です。
●スケッチ②
BLEペリフェラルのスケッチを追加します。
(2020/10/21)Serviceの名称を変更しました。
#include <Arduino_HTS221.h>
#include <ArduinoBLE.h>
// BLE Service
#define Nano33BLESense_Service1_UUID "F000AA30-0451-4000-B000-000000000000"
BLEService Nano33BLESense_Service1(Nano33BLESense_Service1_UUID);
// BLE Characteristic
#define HTS221_Temp_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000"
#define HTS221_Hum_Characteristic_UUID "F000AA32-0451-4000-B000-000000000000"
BLEFloatCharacteristic HTS221_Temperature(HTS221_Temp_Characteristic_UUID, BLERead | BLENotify);
BLEFloatCharacteristic HTS221_Humidity(HTS221_Hum_Characteristic_UUID, BLERead | BLENotify);
// BLE Descriptor
#define HTS221_Temp_Descriptor_UUID "2901"
#define HTS221_Hum_Descriptor_UUID "2901"
BLEDescriptor HTS221_Temp_Descriptor(HTS221_Temp_Descriptor_UUID, "Temperature ; `C");
BLEDescriptor HTS221_Hum_Descriptor(HTS221_Hum_Descriptor_UUID, "Humidity ; %");
#define localNAME "HTS221"
#define DeviceNAME "HTS221BLE"
float previousMillis = 0; // last time value was checked, in ms
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("HTS221 test");
if (!HTS.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
BLE.setLocalName(localNAME);
BLE.setDeviceName(DeviceNAME);
//// set the service1
BLE.setAdvertisedService(Nano33BLESense_Service1);
// add characteristic
Nano33BLESense_Service1.addCharacteristic(HTS221_Temperature);
Nano33BLESense_Service1.addCharacteristic(HTS221_Humidity);
// add descriptor
HTS221_Temperature.addDescriptor(HTS221_Temp_Descriptor);
HTS221_Humidity.addDescriptor(HTS221_Hum_Descriptor);
// add service
BLE.addService(Nano33BLESense_Service1);
// start advertising
BLE.advertise();
Serial.println("\nBluetooth device active, waiting for connections...");
}
void loop() {
// wait for a BLE central
BLEDevice central = BLE.central();
// if a central is connected to the peripheral:
if (central) {
delay(100);
Serial.print("\nConnected to central: ");
// print the central's BT address:
Serial.println(central.address());
// check data every 200ms
// while the central is connected:
while (central.connected()) {
long currentMillis = millis();
// if 200ms have passed, check value:
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updateValue();
delay(1000);
}
}
// when the central disconnects
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
void updateValue() {
float temperature = HTS.readTemperature();
float humidity = HTS.readHumidity();
Serial.println("");
Serial.println(temperature);
Serial.println(humidity);
float valueof_HTS221_Temperature = temperature;
float valueof_HTS221_Humidity = humidity;
// update characteristic
HTS221_Temperature.writeValue(valueof_HTS221_Temperature);
HTS221_Humidity.writeValue(valueof_HTS221_Humidity);
}
実行中の様子です。
●動作確認
RSL10のモニタで観測しました。
実数は、IEEE-754フォーマットで、単精度浮動小数点数の形式:binary32です。4バイトのバイト列でデータが送られます。
こちらのサイトで変換できます。今回は、リトル・エンディアンなので、逆順Swap endiannessにチェックを入れます。
温度 0x1498c341は24.4493、湿度 0xbe005e42は55.5007です。正しく送られていることが確認できました。