Arduino UNO R4 WiFiでBLE ③ LPS22のBLEペリフェラルと接続するセントラル
前回、Arduino UNO R4 WiFiに気圧センサLPS22HBをつないで、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 "LPS22_float"
接続できたら、キャラクタリスティックを指定して読み出します。
#define LPS22_Temp_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000" // BLE Characteristic
#define LPS22_Press_Characteristic_UUID "F000AA32-0451-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(LPS22_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(LPS22_Press_Characteristic_UUID);
温度のデータを読み出し、IEEE-754 フォーマット(単精度浮動小数点数)を実数に変換して印字します。
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 "LPS22_float"
#define LPS22_Temp_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000" // BLE Characteristic
#define LPS22_Press_Characteristic_UUID "F000AA32-0451-4000-B000-000000000000"
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
BLE.begin();
Serial.println("\n start BLE peripherals - Temperature/Pressure");
// 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) {
// 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(LPS22_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(LPS22_Press_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);
Pressure_Characteristic.read();
data = ((uint8_t)*(Pressure_Characteristic.value()+3) << 24) + ((uint8_t)*(Pressure_Characteristic.value()+2) << 16) + ((uint8_t)*(Pressure_Characteristic.value()+1) << 8) + ((uint8_t)*Pressure_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("Pressure = ");
Serial.println(f*k*s);
delay(1000);
}
}
}
Serial.println("Peripheral disconnected");
}
実行例です。
●LEDマトリクスに気圧を表示
こちらの解説からLEDマトリクスにテキストを表示します。
Arduino UNO R4 WiFi LED マトリックスの使用
スケッチです。
#include <ArduinoBLE.h>
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
#define localNAME "LPS22_float"
#define LPS22_Temp_Characteristic_UUID "F000AA31-0451-4000-B000-000000000000" // BLE Characteristic
#define LPS22_Press_Characteristic_UUID "F000AA32-0451-4000-B000-000000000000"
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
matrix.begin();
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
// add some static text
// will only show "UNO" (not enough space on the display)
const char text[] = "UNO r4";
matrix.textFont(Font_4x6);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText();
matrix.endDraw();
BLE.begin();
Serial.println("\n start BLE peripherals - Temperature/Pressure");
// 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) {
// 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(LPS22_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(LPS22_Press_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);
Pressure_Characteristic.read();
data = ((uint8_t)*(Pressure_Characteristic.value()+3) << 24) + ((uint8_t)*(Pressure_Characteristic.value()+2) << 16) + ((uint8_t)*(Pressure_Characteristic.value()+1) << 8) + ((uint8_t)*Pressure_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("Pressure = ");
Serial.println(f*k*s);
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(90);
String text=String(f*k*s,1);
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(" " + text + " ");
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
delay(1000);
}
}
}
Serial.println("Peripheral disconnected");
}
実行例です。左側のマイコン・ボードです。