CO2センサを使う②AdafruitのSCD-30ボードをArduino Nano RP2040 ConnectにつないでBLEペリフェラルに(1)
Arduino Nano RP2040 Connectは、ラズパイPicoを搭載してArduino IDEで利用できるようにしたボードです。
前回利用したCO2センサAdafruitのSCD-30ボードをつなぎます。そして、BLEペリフェラルにします。
●Arduino Nano RP2040 Connectのおもなスペック
- 電源電圧 3.3V
- CPU Raspberry Pi RP2040(Cortex-M0+ ×2)
- メモリ SRAM;264Kバイト、フラッシュROM;16Mバイト
- Built-in LED 13番
- I/O ディジタル;20本、アナログ;8本、PWM対応;20本、割り込み可能;20本 、電流4mA
- RF Wi-Fi、Bluetooth(BLE5.2)
- マイク MP34DT05
- IMUセンサ LSM6DSOXTR(6軸)
- I2Cピン A4;SDA、A5;SCL
- SPIピン クロック;SCK、MOSI;D11?、MISO;D12?
●環境
- Arduino UNO R3
- Arduino IDE 1.8.15
- Windows10 21H1
●接続
Nano RP2040 Connect | SCD-30ボードのSTEMMA QTコネクタ |
---|---|
+3V3 | 赤色 |
GND | 黒色 |
A4(SDA) | 白色(黄色) |
A5(SCL) | 緑色 |
●サンプル・スケッチの動作確認
Adafruit SCD30から、adafruit_scd30_testを選択します。CO2の出力のみにします。
実行している様子です。センサは机の上に置いています。人がいないと500ppmくらいまで下がります。
●BLEのスケッチ
SCD-30から読み出したCO2の値は、文字列で送ります。ServiceとCharacteristicのUUIDは、ユニークな値を発行してくれるところの出力を利用しています。
CO2の数値は、adafruit_scd30_testスケッチから必要な部分を抜き出しました。
oldValue は200msごとにCO2の値を比較するために、ひとつ前の値が入っています。updateValue()関数でNotifyの更新を行っています。
#include <ArduinoBLE.h>
#define SCD30_SERVICE_UUID "F000AA30-0451-4000-B000-000000000000"
// BLE Service
BLEService Sensor_SCD30_Service(SCD30_SERVICE_UUID);
#define SCD30_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000"
// BLE Characteristic
BLEStringCharacteristic SCD30_CO2(SCD30_Characteristic_UUID, BLERead | BLENotify, 24);
#include <Adafruit_SCD30.h>
Adafruit_SCD30 scd30;
float CO2 = 0;
void readSCD30() {
if (scd30.dataReady()){
if (!scd30.read()){ Serial.println("Error reading sensor data"); return; }
CO2 = scd30.CO2;
}
}
#define localNAME "RP2060_SCD30"
#define DeviceNAME "RP2060_CO2_BLE"
float oldValue = 0; // last value
float previousMillis = 0; // last time value was checked, in ms
void setup() {
Serial.begin(9600); // initialize serial communication
while (!Serial);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
if (!scd30.begin()) {
Serial.println("Failed to find SCD30 chip");
while (1) { delay(10); }
}
BLE.setLocalName(localNAME);
BLE.setDeviceName(DeviceNAME);
// add the service UUID
BLE.setAdvertisedService(Sensor_SCD30_Service);
// add characteristic
Sensor_SCD30_Service.addCharacteristic(SCD30_CO2);
// Add service
BLE.addService(Sensor_SCD30_Service);
// set initial value for this characteristic
SCD30_CO2.writeValue(String(oldValue));
// start advertising
BLE.advertise();
Serial.println("Bluetooth 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("Connected to central: ");
// print the central's BT address:
Serial.println(central.address());
// check 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() {
readSCD30();
// if value has changed
if (CO2 != oldValue) {
Serial.print(String(CO2,2));
Serial.println("ppm");
// update characteristic
SCD30_CO2.writeValue(String(CO2,2));
oldValue = CO2; // save the level for next comparison
}
}
実行中のシリアルモニタです。
RSL10のモニタで観測しました。CO2の値は正しく送られています。