初めてのBLE (19) CircuitPythonでペリフェラル③ BME280
この連載の一連の実験と同様に、MEMSセンサのBME280をマイコン・ボードFeather nRF52840 Expressに取り付けて、温度、気圧、湿度を送れるようにします。CircuitPythonのプログラムではUARTサービスを利用しているので、テキストで、三つのデータを送ることにします。
●BME280をつなぐ
今までと同様にI2Cでつなぎます。入手したボードでは、スレーブ・アドレスが0x76に設定されています。
BME280 | Feather nRF52840 Express |
---|---|
Vcc | 3V(3.3V) |
GND | GND |
SCL | SCL |
SDA | SDA |
●BME280の動作確認
examplesに入っているbme280_simpletest.pyを読み込みます。1か所スレーブ・アドレスを変更します。
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,0x76)
保存して実行します。
必要な場所だけ残します。
import time import board import busio import adafruit_bme280 i2c = busio.I2C(board.SCL, board.SDA) bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,0x76) while True: print(bme280.temperature, bme280.pressure, bme280.humidity) time.sleep(2)
●ペリフェラル
ペリフェラルは、Feather nRF52840 Expressで作ります。
第17回の温度のプログラムと上記のプログラムを合体します。write()内で'xxxx'のような文字なら長くても送れるのですが、三つの測定値をstr()で変換して送ろうとすると、エラーが出たり、送られたデータが意味不明だったりしました。
温度は小数点第一位、気圧と湿度は整数にしました。センサの確度から言えば、適正だと思います。三つの数値はカンマで区切りましたが、コロンでも、あとで分離しやすい文字であればよいです。
import time from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService import board import busio import adafruit_bme280 ble = BLERadio() ble.name = "Feather nRF52840 Express" uart = UARTService() advertisement = ProvideServicesAdvertisement(uart) i2c = busio.I2C(board.SCL, board.SDA) bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76) while True: ble.start_advertising(advertisement) while not ble.connected: pass while ble.connected: print('connected ') s0 = str(round(bme280.temperature,1)) + ',' s1 = str(int(bme280.pressure)) + ',' s2 = str(int(bme280.humidity)) print(s0+s1+s2) uart.write(s0+s1+s2) time.sleep(3)
RSL10 Bluetooth Low Enaergy Exploerからつなぎました。想定通りのセンサ値が送られていることが確認できました。
●セントラル
NANO 33 BLE senseでセントラルを動かします。第16回のスケッチをベースに修正します。
93行で、変数dataにキャラUART(RX)から文字データを取り込みます。97~104行では、最初のカンマを見つけ、そこまでの文字(温度)を取り出します。106~113行では、温度の文字を削り、カンマを見つけ、気圧の文字を取り出します。最後の115~117行は、気圧の文字を削れば、残った文字が湿度になります。
#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 - BME280-UART"); // 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(" 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()) { // start Notify? Serial.println("canread"); } else { // Serial.println("error reading characteristic value"); // read the characteristic value UARTCharacteristic.read(); Serial.print("\nread "); if (UARTCharacteristic.valueLength() > 0) { // Serial.print("length= ");Serial.println(UARTCharacteristic.valueLength()); String data = ""; int i =0; int l = UARTCharacteristic.valueLength(); while (l > 0) { l = l -1; data.concat(((char)*(UARTCharacteristic.value()+i))); // Serial.print("i= ");Serial.print(i);Serial.print(" ");Serial.println((char)data); i += 1; } byte buf[]=""; Serial.println(data); //Serial.println(data.indexOf(",")); data.getBytes(buf, data.indexOf(",")+1); Serial.print("\ntemp="); for (int k=0; k<=(data.indexOf(",")) ; k++){ Serial.print((char)buf[k]); } Serial.println(); data = data.substring(data.indexOf(",")+1); //Serial.println(data); byte buf2[]=""; data.getBytes(buf2, data.indexOf(",")+1); Serial.print("\npress="); for (int k=0; k<=(data.indexOf(",")) ; k++){ Serial.print((char)buf2[k]); } Serial.println(); data = data.substring(data.indexOf(",")+1); Serial.print("\nhumi="); Serial.println(data); delay(5000); } } } Serial.println("Peripheral disconnected"); }
実行している様子です。送ったデータが、そのまま表示できました。