Arduino UNO R4 WiFiでBLE ⑥ BME280のBLEペリフェラルと接続するセントラル

 前回、Arduino UNO R4 WiFiに気圧センサBME280をつないで、BLEペリフェラルを作成しました。PCで動くオン・セミコンダクターのBLEであるRSL10 Bluetooth Low Enaergy Exploerで、connectして、気圧と温度データを受け取りました。

 このマイコン・ボードArduino UNO R4 WiFiをPCのUSBから切り離し、電源をつないで単独で動作させます。そして、RSL10 Bluetooth Low Enaergy Exploerでconnectできることを確認しました。

2台目のマイコン・ボードArduino UNO R4 WiFiを用意

 もう一台マイコン・ボードArduino UNO R4 WiFiを用意してPCにつなぎ、BLEセントラルのスケッチを作ります。

 BLEの各種定義

 BLEペリフェラルとはlocalNAMEで選択します。

  #define localNAME "BME280_int"

 接続できたら、キャラクタリスティックを指定して読み出します。

#define BME280_Temp_Characteristic_UUID    "F000AA31-0452-4000-B000-000000000000"  // BLE  Characteristic
#define BME280_Press_Characteristic_UUID   "F000AA32-0452-4000-B000-000000000000"
#define BME280_Humidity_Characteristic_UUID   "F000AA33-0452-4000-B000-000000000000"

●setupーBLE

 最初に初期化します。

BLE.begin();


 localNAMEで探します。

  // start scanning for peripherals
  BLE.scanForName(localNAME);
 
 

loopーBLE

 ペリフェラルが見つかったらアドレス、localNAME、サービスUUIDを印字します

  // 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();
 
 
 スキャンを止めます。
 
 
    // stop scanning
    BLE.stopScan();
 
 

 読み出し関数を実行します。

    readData(peripheral);
 
 
 読み出し関数では、最初にconnectします。
 
 
  
  if (peripheral.connect()) {
 
 
 
 次にdiscoverします。
 
  
  if (peripheral.discoverAttributes()) {
 
 
 温度と気圧、湿度のUUIDでデータを取得します。
 
 
  // retrieve the characteristic
  BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID);
  BLECharacteristic Pressure_Characteristic  = peripheral.characteristic(BME280_Press_Characteristic_UUID);
  BLECharacteristic Humidity_Characteristic  = peripheral.characteristic(BME280_Humidity_Characteristic_UUID);
 
 
 温度のデータを2バイト読み出します。2バイト目(上位)と1バイト目(下位)に整数データが入っているので、16ビットのデータに直します。
 
 
 
      Temperature_Characteristic.readValue(buffer,2);
      uint16_t temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
 
 
 測定した実数を100倍して整数で送ってきているので、100で割ります。
 
 
  Serial.println(temperature / 100.0);
 
 
 気圧と湿度のデータも同様に読み出して実数に変換して印字します。気圧と湿度は10倍です。
 
 
 
  全体のスケッチです。
 
#include <ArduinoBLE.h>

#define localNAME "BME280_int"
#define BME280_Temp_Characteristic_UUID    "F000AA31-0452-4000-B000-000000000000"  // BLE  Characteristic
#define BME280_Press_Characteristic_UUID   "F000AA32-0452-4000-B000-000000000000"
#define BME280_Humidity_Characteristic_UUID   "F000AA33-0452-4000-B000-000000000000"

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10); 
  BLE.begin();
  Serial.println("\n start BLE peripherals - Temperature/Pressure/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();

    readData(peripheral);

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

void readData(BLEDevice peripheral) {
  byte buffer[2] ;
  // 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 characteristic
  BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID);
  BLECharacteristic Pressure_Characteristic  = peripheral.characteristic(BME280_Press_Characteristic_UUID);
  BLECharacteristic Humidity_Characteristic  = peripheral.characteristic(BME280_Humidity_Characteristic_UUID);

  if (!Temperature_Characteristic) {
    Serial.println("Peripheral does not have Temp characteristic!");
    peripheral.disconnect();
    return;
  } 

  Serial.println("---Found CHARACTERISTIC_UUID");
  while (peripheral.connected()) {
  if (Temperature_Characteristic.canRead()) {
      Serial.print("\ntemp = ");
      Temperature_Characteristic.readValue(buffer,2);
      uint16_t temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
      Serial.println(temperature / 100.0); 

  }

  if (Pressure_Characteristic.canRead()) {
      Serial.print("Pressure = ");
      Pressure_Characteristic.readValue(buffer,2);
      uint16_t pressure = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
      Serial.println((pressure / 10.0),1);
  }

  if (Humidity_Characteristic.canRead()) {
      Serial.print("Humidity = ");
      Humidity_Characteristic.readValue(buffer,2);
      uint16_t humidity = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
      Serial.println((humidity / 10.0),1);
  }

  delay(1000);
  }
 
  Serial.println("Peripheral disconnected");
}

 実行例です。

グラフィック・ディスプレイに受信したデータを表示

 LPS22のときのようにマイコン・ボード上のLEDマトリクスにテキストを表示しようとしましたが、温度、気圧、湿度の表示をするには狭すぎて、スクロールすると、とても見にくかったです。

  Arduino UNO R4 WiFiでBLE ③ LPS22のBLEペリフェラルと接続するセントラル

 そこで、BLEペリフェラルと同様に、OLEDグラフィック・ディスプレイを使いました。アマゾンで購入できるI2C接続タイプです。このマイコン・ボードには、Qwiic専用コネクタが用意されていますが、OLEDグラフィック・ディスプレイは認識されませんでした。

  SpresenseでLチカから始める (5) Wireライブラリ グラフィック・ディスプレイ

 スケッチです。製造元が不明なOLEDグラフィック・ディスプレイですが、ドライバは、Adafruitのssd1306用を使いました。スレーブ・アドレスは0x3cです。


#include <ArduinoBLE.h>
#include <Adafruit_SSD1306.h> Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire); #define localNAME "BME280_int" #define BME280_Temp_Characteristic_UUID "F000AA31-0452-4000-B000-000000000000" // BLE Characteristic #define BME280_Press_Characteristic_UUID "F000AA32-0452-4000-B000-000000000000" #define BME280_Humidity_Characteristic_UUID "F000AA33-0452-4000-B000-000000000000" void setup() { Serial.begin(115200); while (!Serial) delay(10); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) { // Address 0x3C for 128x32 Serial.println(F("SSD1306 allocation failed")); for (;;) ; // Don't proceed, loop forever } display.display(); delay(500); // Pause for 2 seconds display.setTextSize(1); display.setTextColor(WHITE); display.setRotation(0); display.clearDisplay(); BLE.begin(); Serial.println("\n start BLE peripherals - Temperature/Pressure/Humidity + ssd1306"); // start scanning for peripherals BLE.scanForName(localNAME); } void loop() { display.clearDisplay(); display.setCursor(0, 0); // 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(); readData(peripheral); // peripheral disconnected, start scanning again BLE.scanForName(localNAME); } } void readData(BLEDevice peripheral) { uint16_t temperature; uint16_t pressure; uint16_t humidity; byte buffer[2] ; // 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 characteristic BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID); BLECharacteristic Pressure_Characteristic = peripheral.characteristic(BME280_Press_Characteristic_UUID); BLECharacteristic Humidity_Characteristic = peripheral.characteristic(BME280_Humidity_Characteristic_UUID); if (!Temperature_Characteristic) { Serial.println("Peripheral does not have Temp characteristic!"); peripheral.disconnect(); return; } Serial.println("---Found CHARACTERISTIC_UUID"); while (peripheral.connected()) { if (Temperature_Characteristic.canRead()) { Serial.print("\ntemp = "); Temperature_Characteristic.readValue(buffer,2); temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0]; Serial.println(temperature / 100.0); } if (Pressure_Characteristic.canRead()) { Serial.print("Pressure = "); Pressure_Characteristic.readValue(buffer,2); pressure = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0]; Serial.println((pressure / 10.0),1); } if (Humidity_Characteristic.canRead()) { Serial.print("Humidity = "); Humidity_Characteristic.readValue(buffer,2); humidity = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0]; Serial.println((humidity / 10.0),1); } display.clearDisplay(); display.setCursor(0, 0); display.println("Temperature - `C"); display.print(temperature / 100.0, 2); display.println(""); display.println(""); display.println("Pressure - hPa"); display.print(pressure / 10.0, 1); display.println(""); display.println(""); display.println("Humidity - %"); display.print(humidity / 10.0, 1); display.println(""); display.display(); delay(1000); } Serial.println("Peripheral disconnected"); }

 実行例です。

 左側のBLEセントラルを実行しているマイコン・ボードです。

前へ

Arduino UNO R4 WiFiでBLE ⑤ BME280のBLEペリフェラル