初めてのBLE (18) CircuitPythonでペリフェラル② Nano 33 BLE senseでセントラル

 前回AdafruitのFeather nRF52840 Expressを用い、CircuitPythonでペリフェラルが動きました。送っているのはCPUの温度値です。ここでは、マイコン・ボードNano 33 BLE senseを使ってArduino IDEでセントラルを作ります。

セントラルのスケッチ

 第16回で作成したセントラルのスケッチをベースに修正します。

 CircuitPythonでペリフェラルは、3秒おきにデータを送ってきます。ソースを読むと、NotifyはONになっています。前回、オン・セミコンダクターのBLEであるRSL10 Bluetooth Low Enaergy Exploerを使って情報をやり取りしたときも、Notificationをチェックしたら、データを受信始めました。しかし、ArduinoBLEにstart notifyに相当する関数が見つかりません。実験をしていると、

   if (UARTCharacteristic.canRead()) {

canRead()関数でエラーになったときに、start notifyが発行されているようです。

 前回作ったCircuitPythonのプログラムでは、binary32 のデータをビッグ・エンディアンで送ってきますから、readしたデータを1バイトずつ順に読み出し、順に上位にシフトし、合成し、32ビットのバイト列を作ります。
 連載の第15回でも利用しましたが、その32ビットのデータの先頭1ビットを符号(f)で取り出し、次の8ビットを指数(s)、残りの22ビットの先頭に1を加えて仮数(k)とします。三つの結果をかけあわせると浮動小数点の値に戻ります。

#include <ArduinoBLE.h>

#define SERVICE_UUID        "6e400001-b5a3-f393-e0a9-e50e24dcca9e"  // UART 
#define characteristicTxUUID "6e400002-b5a3-f393-e0a9-e50e24dcca9e"  // Tx
#define characteristicRxUUID "6e400003-b5a3-f393-e0a9-e50e24dcca9e"  // Rx
#define localNAME "Feather nRF52840 Express"

void setup() {
  Serial.begin(9600);
  while (!Serial);

  BLE.begin();
  Serial.println("\nstart BLE Central - temp");
  // 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();

    readUARTdata(peripheral);

    // peripheral disconnected, start scanning again
    BLE.scanForName(localNAME);
  }
}

void readUARTdata(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.print("Connecting ...");

  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 LED characteristic
  BLECharacteristic UARTCharacteristic  = peripheral.characteristic(characteristicRxUUID);

  if (!UARTCharacteristic) {
    Serial.println("Peripheral does not have UART characteristic!");
    peripheral.disconnect();
    return;
  } 
 
  Serial.println("---Found CHARACTERISTIC_UUID");
  while (peripheral.connected()) {
  //  Serial.println("connected");
  if (UARTCharacteristic.canRead()) {
    Serial.println("canread");
  } else {
  //  Serial.println("error reading characteristic value");
  
    // read the characteristic value
    UARTCharacteristic.read();
    Serial.println("read");
    if (UARTCharacteristic.valueLength() > 0) {
      uint32_t  data = ((uint8_t)*(UARTCharacteristic.value()) << 24) + ((uint8_t)*(UARTCharacteristic.value()+1) << 16) + ((uint8_t)*(UARTCharacteristic.value()+2) << 8)  +  ((uint8_t)*UARTCharacteristic.value()+3);
      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);
  
      delay(5000);
    }
  }
}

  Serial.println("Peripheral disconnected");
}

 実行した様子です。ペリフェラルが動いているFeather nRF52840 Expressボード上のモジュールを指でつまむと、温度が上がってくるので、正常に動いているようです。

前へ

初めてのBLE (17) CircuitPythonでペリフェラル① 5.1.0の準備

次へ

初めてのBLE (19) CircuitPythonでペリフェラル③ BME280