CO2センサを使う⑤nano 33 BLE senseでBLEセントラル
前回、Nano RP2040 Connect+SCD-30をBLEのペリフェラルにしました。ここでは、ArduinoBLEライブラリを使って、BLEのセントラルを作ります。ハードは、nano 33 BLE senseです。
●環境
- Arduino UNO R3
- Arduino IDE 1.8.15
- Windows10 21H1
●接続
nano 33 BLE senseは、USBケーブルでPCとつなぐだけで、特に何も配線しません。
●スケッチ
local Nameの一致で接続します。BLEペリフェラルはCO2、温度、湿度を送ってきます。それぞれのデータは、IEEE-754のフォーマットで、単精度浮動小数点数の形式:binary32です。4バイトのバイト列でデータが送られます。
リトル・エンディアンなので、4バイト目から取り出します。
uint32_t data = ((uint8_t)*(SCD30_Temperature_Characteristic.value()+3) << 24) + ((uint8_t)*(SCD30_Temperature_Characteristic.value()+2) << 16) + ((uint8_t)*(SCD30_Temperature_Characteristic.value()+1) << 8) + ((uint8_t)*SCD30_Temperature_Characteristic.value());
符号を取り出します。
int32_t f = pow(-1, int(bitRead(data,31)));
仮数を取り出します。
double k =1 + ((((data<<1)<<8)>>9))/pow(2,23);
指数を取り出します。
int32_t s = pow(2,((((data<<1)>>24))-127));
三つをかけると、実数に戻ります。
#include <ArduinoBLE.h>
#define localNAME "RP2060_SCD30_float"
#define SCD30_SERVICE_UUID "F000AA30-0451-4000-B000-000000000000"
#define SCD30_C_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000"
#define SCD30_T_Characteristic_UUID "F000AA32-0451-4000-B000-000000000000"
#define SCD30_H_Characteristic_UUID "F000AA33-0451-4000-B000-000000000000"
void setup() {
Serial.begin(9600);
while (!Serial);
BLE.begin();
Serial.println("\n start BLE Central - CO2/Temperature/Humidity");
// start scanning for peripherals
BLE.scanForName(localNAME);
}
void loop() {
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != localNAME) {
return;
}
// stop scanning
BLE.stopScan();
readSCD30data(peripheral);
// peripheral disconnected, start scanning again
BLE.scanForName(localNAME);
}
}
void readSCD30data(BLEDevice peripheral) {
// connect to the peripheral
Serial.print("\nConnecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.print("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered\n");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// retrieve the SCD30characteristic
BLECharacteristic SCD30_CO2_Characteristic = peripheral.characteristic(SCD30_C_Characteristic_UUID);
BLECharacteristic SCD30_Temperature_Characteristic = peripheral.characteristic(SCD30_T_Characteristic_UUID);
BLECharacteristic SCD30_Humidity_Characteristic = peripheral.characteristic(SCD30_H_Characteristic_UUID);
if (!SCD30_Temperature_Characteristic) {
Serial.println("Peripheral does not have Temp characteristic!");
peripheral.disconnect();
return;
} // else if (!ledCharacteristic.canWrite()) {
// Serial.println("Peripheral does not have a writable LED characteristic!");
// peripheral.disconnect();
// return;
// }
Serial.println("---Found CHARACTERISTIC_UUID");
while (peripheral.connected()) {
if (SCD30_Temperature_Characteristic.canRead()) {
// read the characteristic value
SCD30_Temperature_Characteristic.read();
if (SCD30_Temperature_Characteristic.valueLength() > 0) {
uint32_t data = ((uint8_t)*(SCD30_Temperature_Characteristic.value()+3) << 24) + ((uint8_t)*(SCD30_Temperature_Characteristic.value()+2) << 16) + ((uint8_t)*(SCD30_Temperature_Characteristic.value()+1) << 8) + ((uint8_t)*SCD30_Temperature_Characteristic.value());
int32_t f = pow(-1, int(bitRead(data,31)));
double k =1 + ((((data<<1)<<8)>>9))/pow(2,23);
int32_t s = pow(2,((((data<<1)>>24))-127));
Serial.print("\ntemp =");
Serial.println(f*k*s);
SCD30_CO2_Characteristic.read();
data = ((uint8_t)*(SCD30_CO2_Characteristic.value()+3) << 24) + ((uint8_t)*(SCD30_CO2_Characteristic.value()+2) << 16) + ((uint8_t)*(SCD30_CO2_Characteristic.value()+1) << 8) + ((uint8_t)*SCD30_CO2_Characteristic.value());
f = pow(-1, int(bitRead(data,31)));
k =1 + ((((data<<1)<<8)>>9))/pow(2,23);
s = pow(2,((((data<<1)>>24))-127));
Serial.print("CO2 =");
Serial.println(f*k*s);
SCD30_Humidity_Characteristic.read();
data = ((uint8_t)*(SCD30_Humidity_Characteristic.value()+3) << 24) + ((uint8_t)*(SCD30_Humidity_Characteristic.value()+2) << 16) + ((uint8_t)*(SCD30_Humidity_Characteristic.value()+1) << 8) + ((uint8_t)*SCD30_Humidity_Characteristic.value());
f = pow(-1, int(bitRead(data,31)));
k =1 + ((((data<<1)<<8)>>9))/pow(2,23);
s = pow(2,((((data<<1)>>24))-127));
Serial.print("humi =");
Serial.println(f*k*s);
delay(5000);
}
}
}
Serial.println("Peripheral disconnected");
}
実行している様子です。左がペリフェラル、右がセントラルです。