超精密温度計の製作④BLEペリフェラルに
温度が測定できました。ESP32にはBLEの機能があります。ESP32のBLEは、
の記事で、スケッチの解説をしました。この中で、
初めてのBLE (15) ESP32でペリフェラル③浮動小数点形式
をベースに、修正します。
●温度測定部分の修正
前回のスケッチはTMP117.inoで保存しました。それを修正し、TMP117b.inoで保存しました。先頭のincludeなどはそのままです。read_tempdata() は実数で値を戻すようにしました。
setup()は削除し、内容の一部を次の項で説明するBLETMP117.inoのスケッチに移します。loop()は全部削除します。
#include <Wire.h> #define TMP117address 0x48 #define TemperatureRegiste 0x00 #define ConfigurationRegister 0x01 float read_tempdata() { Wire.beginTransmission(TMP117address); Wire.write((byte)TemperatureRegiste); Wire.endTransmission(); Wire.requestFrom(TMP117address, 2); //wait for response while(Wire.available() == 0); int T = Wire.read(); T = T << 8 | Wire.read() ; return ( -(T & 0b1000000000000000) | (T & 0b0111111111111111) ) * 7.8125 /1000.0; }
●BLE部分
TMP117bにタブを増やします。タブの右端に▼アイコンがあるのでクリックし、「新規タブ」を選びます。ファイル名はBLETMP117としました。
「初めてのBLE (15) ESP32でペリフェラル③浮動小数点形式」のスケッチをコピペし、修正します。
スペースと改行のコードがおかしくなるので、修正します。
createCharacteristic()ではread属性しかつけていませんが、loop()でpCharacteristic->notify();しているので、セントラル側は温度を定期的に受け取っています。
スケッチ中にもコメントがありますが、https://www.uuidgenerator.net/でUUIDを発行しています。
BLEDevice::init("ESP32-TMP117 peripheral");でlocal nameを設定しています。
/* Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp Ported to Arduino ESP32 by Evandro Copercini updates by chegewara */ #include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h> // See the following for generating UUIDs: // https://www.uuidgenerator.net/ #define SERVICE_UUID "1c3b07d0-7106-4114-add9-43bd176d104e" #define CHARACTERISTIC_UUID "e819baa6-6d98-4090-937b-88dd2ca0a7da" BLECharacteristic *pCharacteristic; void setup() { Wire.begin(); Wire.setClock(400000); Wire.beginTransmission(TMP117address); Wire.write((byte)ConfigurationRegister); Wire.write((byte)0x00); // high Wire.write(0x60); // low Wire.endTransmission(); Serial.begin(9600); Serial.println("Starting BLE work!"); BLEDevice::init("ESP32-TMP117 peripheral"); BLEServer *pServer = BLEDevice::createServer(); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ); int temp = temperatureRead(); Serial.println(temp); pCharacteristic->setValue((uint8_t*)&temp,1); pService->start(); // BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->setScanResponse(true); pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue pAdvertising->setMinPreferred(0x12); BLEDevice::startAdvertising(); } void loop() { // put your main code here, to run repeatedly: float temp = read_tempdata(); Serial.println(temp,4); pCharacteristic->setValue(temp); pCharacteristic->notify(); delay(2000); }
実行したときのシリアルモニタの様子です。
オン・セミコンダクターのRSL10モニタでconnectし、Discover Servicesを実行した様子です。
IEEE754(単精度浮動小数点数の形式)で温度のデータを送っています。リトル・エンディアンなので、後ろから読み取ってデコードします。
Floating Point to Hex Converterのサイトに行って、デコードします。Swap endiannessをチェックすると、逆順に解釈します。
「28.4375」なので、正しく温度が送られていることがわかります。