This text has been translated, so it may be poorly written.
Hello, I am trying to use M5stack to get the acceleration and ECG of my Polar OH1+, but the notifyCallback is not working.
I found some code in Python that did something similar, so I followed the same procedure to make the connection.
https://github.com/pareeknikhil/biofeedback/blob/master/Polar%20Device%20Data%20Stream/Accelerometer/main.py
According to this, I found out that this is the procedure to follow.
- Read the value of pmd control uuid
- Write to the pmd control uuid
- Read the pmd data uuid
The following program tries to achieve that with M5stack.
//===== header file & define & global variable =====
#include"BLEDevice.h"
boolean doConnect = false;
volatile boolean isConnected = false;
boolean doScan = false;
BLEUUID pmd_serviceUUID ("FB005C80-02E7-F387-1CAD-8ACD2D8DF0C8");
BLEUUID pmd_dataUUID ("FB005C82-02E7-F387-1CAD-8ACD2D8DF0C8");
BLEUUID pmd_ctrlUUID ("FB005C81-02E7-F387-1CAD-8ACD2D8DF0C8");
BLEAdvertisedDevice* myDevice;
BLEClient* pClient;
String SensorName = "Polar OH1 87C4C425"; // SDから読み取る
//===========================================
//===== class & function ====================
class MyClientCallback: public BLEClientCallbacks{
void onConnect(BLEClient* pclient){ }
void onDisconnect(BLEClient* pclient){
isConnected = false;
Serial.println("onDisconnetct");
}
};
// BLEデバイスを検索する
class MyAdvertisedDeviceCallback: public BLEAdvertisedDeviceCallbacks{
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.println(advertisedDevice.toString().c_str());
// 指定デバイスなら接続する
if(SensorName.equals(advertisedDevice.getName().c_str())){
Serial.print("Connect BLE device : ");
Serial.println(advertisedDevice.toString().c_str());
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
}
}
};
void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
Serial.print("Notify callback for characteristic ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
for (int i = 0; i <= length - 1; i++) {
Serial.print(String(*(pData + i), HEX));
Serial.print(" ");
}
Serial.println();
}
bool connectToServer(){
Serial.print("connection to : ");
Serial.println(myDevice->getAddress().toString().c_str());
pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback() );
pClient->connect(myDevice);
Serial.println(" - Created to server");
BLERemoteService* pRemoteService = pClient->getService(pmd_serviceUUID);
if (pRemoteService == nullptr) {
Serial.println("Failed to find our service UUID: ");
Serial.println(pmd_serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.print(" - Found service ( ");
Serial.print(pmd_serviceUUID.toString().c_str());
Serial.println(" )");
static BLERemoteCharacteristic* pControlCharacteristic;
pControlCharacteristic = pRemoteService->getCharacteristic(pmd_ctrlUUID);
if( pControlCharacteristic == nullptr ){
Serial.print("Failed to find out characteristic UUID : ");
Serial.println(pmd_ctrlUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println("characteristics");
std::map<uint16_t, BLERemoteCharacteristic*>* mapCharacteristics = pRemoteService->getCharacteristicsByHandle();
for (std::map<uint16_t, BLERemoteCharacteristic*>::iterator i = mapCharacteristics->begin(); i != mapCharacteristics->end(); ++i) {
Serial.print(" - characteristic UUID : ");
Serial.print(i->second->getUUID().toString().c_str());
Serial.print(" Broadcast:");
Serial.print(i->second->canBroadcast()?'O':'X');
Serial.print(" Read:");
Serial.print(i->second->canRead()?'O':'X');
Serial.print(" WriteNoResponse:");
Serial.print(i->second->canWriteNoResponse()?'O':'X');
Serial.print(" Write:");
Serial.print(i->second->canWrite()?'O':'X');
Serial.print(" Notify:");
Serial.print(i->second->canNotify()?'O':'X');
Serial.print(" Indicate:");
Serial.print(i->second->canIndicate()?'O':'X');
Serial.println();
}
static BLERemoteCharacteristic* pDataCharacteristic;
pDataCharacteristic = pRemoteService->getCharacteristic(pmd_dataUUID);
if( pDataCharacteristic == nullptr ){
Serial.print("Failed to find out characteristic UUID : ");
Serial.println(pmd_dataUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.print(" - Add Notify ( ");
Serial.print(pmd_dataUUID.toString().c_str());
Serial.println(" )");
if(pDataCharacteristic->canNotify()){
std::string value = pControlCharacteristic->readValue();
uint8_t data[14] = {0x02,
0x02,
0x00,
0x01,
0xC8,
0x00,
0x01,
0x01,
0x10,
0x00,
0x02,
0x01,
0x08,
0x00,};
pControlCharacteristic->writeValue(data,14,false);
Serial.println(" - Set value");
Serial.println(" - Can Notify");
pDataCharacteristic->registerForNotify(notifyCallback);
}
isConnected = true;
return true;
}
//===========================================
//===== setting =============================
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
static BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallback());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
}
//===========================================
//===== main ================================
void loop(){
if(doConnect==true){
if(connectToServer()){
Serial.println("now connected to BLE Server.");
}else{
Serial.println("faild to connect to the server.");
}
doConnect = false;
}
if( isConnected == false && doScan == true ) BLEDevice::getScan()->start(0);
delay(1000);
}
//===========================================
When this was done, the serial monitor display looked like the following.
Starting Arduino BLE Client application...
Name: , Address: 5a:f3:e5:97:72:be, manufacturer data: 060001092006319b0f7cab7c18b3ad1f11d4f6475cf638678bd51cf02d
Name: , Address: 33:20:7d:41:97:52, serviceUUID: 0000fd6f-0000-1000-8000-00805f9b34fb
Name: , Address: 11:27:f2:c5:92:98, manufacturer data: 0600010920029ac7ae5b723ad210a6450c28780429ca56a82bae79a076
Name: Polar OH1 87C4C425, Address: a0:9e:1a:87:c4:c4, manufacturer data: 6b00720851a77b02000000007a01053b005d, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb, serviceUUID: 0000feee-0000-1000-8000-00805f9b34fb
Connect BLE device : Name: Polar OH1 87C4C425, Address: a0:9e:1a:87:c4:c4, manufacturer data: 6b00720851a77b02000000007a01053b005d, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb, serviceUUID: 0000feee-0000-1000-8000-00805f9b34fb
connection to : a0:9e:1a:87:c4:c4
- Created client
- Created to server
- Found service ( fb005c80-02e7-f387-1cad-8acd2d8df0c8 )
characteristics
- characteristic UUID : fb005c81-02e7-f387-1cad-8acd2d8df0c8 Broadcast:X Read:O WriteNoResponse:X Write:O Notify:X Indicate:O
- characteristic UUID : fb005c82-02e7-f387-1cad-8acd2d8df0c8 Broadcast:X Read:X WriteNoResponse:X Write:X Notify:O Indicate:X
- Add Notify ( fb005c82-02e7-f387-1cad-8acd2d8df0c8 )
- Set value
- Can Notify
now connected to BLE Server.
It even shows Can Notify, but notyfiCallback does not work. Can you please tell me why it is not working?
Also, the byte sequence that is written to pmd control is supposed to be based on this page.