超精密温度計の製作④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」なので、正しく温度が送られていることがわかります。