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");
}

 実行している様子です。左がペリフェラル、右がセントラルです。

前へ

CO2センサを使う④AdafruitのSCD-30ボードをArduino Nano RP2040 ConnectにつないでBLEペリフェラルに(3)

次へ

CO2センサを使う⑥Windows10でBLEセントラル