今から始める電子工作 ㉒ I2Cバス その3-3 温湿度センサSHT45 BLEセントラル

 ここでは、前回製作した「温湿度センサSHT45のデータを利用したBLEペリフェラル」に対応するBLEセントラルを作ります。

環境

  • Arduino IDE;2.3.4
  • Windows11;24H2
  • Arduino UNO R4 WiFi 
  • ArduinoBLEライブラリ1.3.7

前回作成したBLEペリフェラル

 スケッチは、コンソールへの出力を全部コメントアウトしました。

 12Vの電源をDCジャックに入れ、動作させます。

 RSL10で、動作を確認します。

BLEセントラルの構成

 もう一台マイコン・ボードArduino UNO R4 WiFiを用意します。PCとはUSBケーブルで接続します。QWIICケーブルで、OLEDグラフィック・ディスプレイを接続します。

BLEscanする

 BLEで接続できる機器を探します。

  ArduinoBLE/examples/Central/Scan/Scan.ino

を新規スケッチでコピペして動かします。保存名はBLEscanにしました。

 コンパイルして実行すると、SHT45がつながったBLEペリフェラルを探してきました。RSSIは信号の強さです。

BLEの各種定義

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

#define localNAME "SHT45_float"

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

#define SHT45_Temp_Characteristic_UUID    "F000AA31-0451-4000-B000-000000000000"  // BLE  Characteristic
#define SHT45_Humidity_Characteristic_UUID   "F000AA32-0451-4000-B000-000000000000"

setupーBLE

 最初に初期化します。

  BLE.begin();


 localNAMEで探します。

  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();

 
 
 スキャンを止めます。
 

    BLE.stopScan();


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

    readData(peripheral);


 
 
 読み出し関数 readData() では、最初にconnectします。
 
 
  

  if (peripheral.connect()) {


 
 
 
 次にdiscoverします。
 
  

  if (peripheral.discoverAttributes()) {


 
 
 温度と湿度のUUIDでデータを取得します。
 
 

  BLECharacteristic Temperature_Characteristic = peripheral.characteristic(SHT45_Temp_Characteristic_UUID);
  BLECharacteristic Humidity_Characteristic  = peripheral.characteristic(SHT45_Humidity_Characteristic_UUID);


 
 
  温度のバイナリ・データを読み出し、IEEE-754 フォーマット(単精度浮動小数点数)を実数に変換して印字します。
 
  参考;IEEE754 単精度浮動小数点数の形式:binary32 の変換
 
 
 

    Temperature_Characteristic.read();
    if (Temperature_Characteristic.valueLength() > 0) {
      uint32_t  data = ((uint8_t)*(Temperature_Characteristic.value()+3) << 24) + ((uint8_t)*(Temperature_Characteristic.value()+2) << 16) + ((uint8_t)*(Temperature_Characteristic.value()+1) << 8)  +  ((uint8_t)*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);


 
 
 湿度のデータも同様に読み出して実数に変換して印字します。

 スケッチです。

#include <ArduinoBLE.h>

#define localNAME "SHT45_float"
#define SHT45_Temp_Characteristic_UUID    "F000AA31-0451-4000-B000-000000000000"  // BLE  Characteristic
#define SHT45_Humidity_Characteristic_UUID   "F000AA32-0451-4000-B000-000000000000"

void setup() {
  Serial.begin(9600);
  delay(1000); 
  BLE.begin();
  Serial.println("\n start BLE peripherals - 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();

    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(SHT45_Temp_Characteristic_UUID);
  BLECharacteristic Humidity_Characteristic  = peripheral.characteristic(SHT45_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()) {
    // read the characteristic value
    Temperature_Characteristic.read();
    if (Temperature_Characteristic.valueLength() > 0) {
      uint32_t  data = ((uint8_t)*(Temperature_Characteristic.value()+3) << 24) + ((uint8_t)*(Temperature_Characteristic.value()+2) << 16) + ((uint8_t)*(Temperature_Characteristic.value()+1) << 8)  +  ((uint8_t)*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);

      Humidity_Characteristic.read();
      data = ((uint8_t)*(Humidity_Characteristic.value()+3) << 24) + ((uint8_t)*(Humidity_Characteristic.value()+2) << 16) + ((uint8_t)*(Humidity_Characteristic.value()+1) << 8)  +  ((uint8_t)*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(1000);
    }
  }
}
 
  Serial.println("Peripheral disconnected");
}

 実行します。

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

 AdafruitのOLEDライブラリ、グラフィック・ライブラリ類の記述を追加します。

#include <ArduinoBLE.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_SH110X.h>
#include <Fonts/FreeSans9pt7b.h> #define localNAME "SHT45_float" #define SHT45_Temp_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000" // BLE Characteristic #define SHT45_Humidity_Characteristic_UUID "F000AA32-0451-4000-B000-000000000000" Adafruit_SSD1306 display(128, 64, &Wire1); void setup() { Serial.begin(9600); delay(1000); BLE.begin(); Serial.println("\n start BLE central - Temperature/Humidity"); BLE.scanForName(localNAME); Wire1.begin(); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } Serial.println("OLED begun"); display.clearDisplay(); display.display(); display.setRotation(0); display.setFont(&FreeSans9pt7b); display.setTextColor(SH110X_WHITE); } 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(SHT45_Temp_Characteristic_UUID); BLECharacteristic Humidity_Characteristic = peripheral.characteristic(SHT45_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()) { // read the characteristic value Temperature_Characteristic.read(); if (Temperature_Characteristic.valueLength() > 0) { uint32_t data = ((uint8_t)*(Temperature_Characteristic.value()+3) << 24) + ((uint8_t)*(Temperature_Characteristic.value()+2) << 16) + ((uint8_t)*(Temperature_Characteristic.value()+1) << 8) + ((uint8_t)*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)); float aTemperature = f*k*s; Serial.print("\ntemp = ") ; Serial.println(aTemperature); Humidity_Characteristic.read(); data = ((uint8_t)*(Humidity_Characteristic.value()+3) << 24) + ((uint8_t)*(Humidity_Characteristic.value()+2) << 16) + ((uint8_t)*(Humidity_Characteristic.value()+1) << 8) + ((uint8_t)*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)); float aHumidity = f*k*s; Serial.print("Humi = "); Serial.println(aHumidity); display.clearDisplay(); display.setCursor(0, 20); display.println("SHT45 /w BLE"); display.setCursor(0, 40); display.print("Temp: "); display.print(aTemperature,1); display.println(" 'C"); display.print("Hum: "); display.print(aHumidity,1); display.println(" %"); display.display(); delay(1000); } } } Serial.println("Peripheral disconnected"); }

 実行中の様子です。

前へ

今から始める電子工作 ㉑ I2Cバス その3-2 温湿度センサSHT45 BLEペリフェラル

次へ

今から始める電子工作 Step2 ① I/Oポートの状態と消費電流