我使用ArduinoBLE.h库连接Polar H10并参考此文档获取心电图数据。
我已成功开始流式传输并从自定义特征 UUID“FB005C82-02E7-F387-1CAD-8ACD2D8DF0C8”获取信息。
这是获得的信息:
(0x) 00-14-D1-22
这代表心电图吗?我应该如何提取它?
另外,如何修改
sampling_rate
?它没有显示在文档中。
下面是我的代码:
#include <ArduinoBLE.h>
#define BLE_ARDUINO_NAME "Arduino"
// Polar Gatt Service and Characteristics
#define PMD_SERVICE_UUID "FB005C80-02E7-F387-1CAD-8ACD2D8DF0C8"
#define PMD_CONTROL_CHARACTERISTIC_UUID "FB005C81-02E7-F387-1CAD-8ACD2D8DF0C8"
#define PMD_DATA_CHARACTERISTIC_UUID "FB005C82-02E7-F387-1CAD-8ACD2D8DF0C8"
#define POLAR_HR_SERVICE_UUID "180D"
#define POLAR_HR_CHARACTERISTIC_UUID "2A37"
// Polar H10 Sampling Frequency
#define POLAR_SAMPLE_RATE 130
// POLAR_HR_CHARACTERISTIC_UUID FLAG VALIDATE
#define ENERGY_EXPENDED_PRESENT_BIT 3
#define RR_INTERVAL_PRESENT_BIT 4
#define HEART_RATE_FORMAT_BIT 0
// Unit Measurement Convert Parameter
#define RR_INTERVAL_UNIT 1024
// Control Parameters
bool scanRequried = true;
bool requestStreamRequired = true;
BLEDevice POLAR_Peripheral;
BLEService HR_Service;
BLECharacteristic HR_Characteristic;
BLEService PMD_Service;
BLECharacteristic PMD_Control;
BLECharacteristic PMD_Data;
void polarPMD() {
PMD_Service = POLAR_Peripheral.service(PMD_SERVICE_UUID);
if (!PMD_Service.hasCharacteristic(PMD_CONTROL_CHARACTERISTIC_UUID))
Serial.println("PMD_CONTROL_CHARACTERISTIC_UUID Not Found");
else if (!PMD_Service.hasCharacteristic(PMD_DATA_CHARACTERISTIC_UUID))
Serial.println("PMD_DATA_CHARACTERISTIC_UUID Not Found");
PMD_Control = PMD_Service.characteristic(PMD_CONTROL_CHARACTERISTIC_UUID);
PMD_Data = PMD_Service.characteristic(PMD_DATA_CHARACTERISTIC_UUID);
PMD_Control.subscribe();
PMD_Data.subscribe();
}
void requestECGStream() {
if (requestStreamRequired) {
// Request Stream Setting
const uint8_t REQUEST_STREAM[] = {0x01,0x02};
const uint8_t REQUEST_ECG[] = {0x01,0x00};
if (PMD_Control.writeValue(REQUEST_STREAM, 2))
Serial.println("Success 0x01,0x02");
if (PMD_Control.writeValue(REQUEST_ECG, 2))
Serial.println("Success 0x01,0x00");
requestStreamRequired = false;
}
}
void startStream() {
const uint8_t REQUEST_STREAM[] = {0x02, 0x00, 0x00, 0x01, 0x82, 0x00, 0x01, 0x01, 0x0E, 0x00};
PMD_Control.writeValue(REQUEST_STREAM, 10);
while (POLAR_Peripheral.connected()) {
if (PMD_Data.valueUpdated()) {
PMD_Data.read();
readData(PMD_Data.value());
Serial.println();
}
}
polarDisconnect();
scanRequried = true;
requestStreamRequired = true;
}
void readData(const uint8_t *data) {
int size = sizeof(data) / sizeof(data[0]);
for (int i = 0; i < size; i++) {
unsigned char c = data[i];
Serial.print(c, HEX);
if (i < size - 1) {
Serial.print("-");
}
}
Serial.println("");
}
bool polarDataValid () {
if (!POLAR_Peripheral.discoverAttributes()) {
Serial.println("* Attributes discovery failed!");
Serial.println(" ");
polarDisconnect();
return false;
}
return true;
}
void polarDisconnect() {
POLAR_Peripheral.disconnect();
Serial.println("Decive Disconnected...");
scanRequried = true;
requestStreamRequired = true;
}
void polarConnect() {
Serial.println("Connecting to the device...");
if (POLAR_Peripheral.connect()) {
Serial.println("* Connected");
Serial.println(" ");
} else {
Serial.println("* Ops, Fail Connection");
Serial.println(" ");
scanRequried = true;
requestStreamRequired = true;
}
}
bool polarDiscover () {
BLEDevice peripheral;
Serial.println("Searching HEART RATE SERVICE device...");
do
{
BLE.scanForUuid(POLAR_HR_SERVICE_UUID);
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) {
Serial.println("* POLAR H10 device found!");
Serial.print("* Device MAC address: ");
Serial.println(peripheral.address());
Serial.print("* Device name: ");
Serial.println(peripheral.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(peripheral.advertisedServiceUuid());
Serial.println(" ");
BLE.stopScan();
scanRequried = false;
}
POLAR_Peripheral = peripheral;
}
void setup() {
Serial.begin(9600);
while (!Serial) {
Serial.println("Serial Initialization Failed.");
}
// begin initialization
while (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
}
BLE.setDeviceName(BLE_ARDUINO_NAME);
BLE.setLocalName(BLE_ARDUINO_NAME);
BLE.advertise();
Serial.println(String(BLE_ARDUINO_NAME) + " (Central Device)");
Serial.println("");
}
void loop() {
// Find Polar Device and Connect it.
if (scanRequried) {
polarDiscover();
polarConnect();
}
if (polarDataValid()) {
polarPMD();
requestECGStream();
if(!requestStreamRequired) {
startStream();
}
}
}
下面是输出:
Arduino (Central Device)
Searching HEART RATE SERVICE device...
* POLAR H10 device found!
* Device MAC address: c0:d2:62:ca:3d:46
* Device name: Polar H10 B1915225
* Advertised service UUID: 180d
Connecting to the device...
* Connected
Success 0x01,0x02
Success 0x01,0x00
0-5E-AB-8A
0-19-6B-FA
0-56-DB-69
0-E6-31-8
以下是提到的文档提供的部分信息。
心电图信号不是我的领域,但这里有一些建议。
Electrocardiogram
的大小是3B,其单位是uV作为Frame types ECG
的描述,因此提取输出的前3个八位字节并尝试用大端或小端来解释它们。
0-5E-AB-8A
将为 0x005EAB=24235uV 或 0xAB5E00=11230720uV
0-19-6B-FA
将为 0x00196B=6507uV 或 0x6B1900=7018752uV
0-56-DB-69
将为 0x0056DB=22235uV 或 0xDB5600=14374400uV
0-E6-31-8
将为 0x00E631=58929uV 或 0x31E600=3270144uV
big-endian解释的结果看起来更合理。
void readData(const uint8_t *data) {
int size = sizeof(data) / sizeof(data[0]);
表达式
sizeof(data)
实际上显示了指针data
的大小,因此size
的值将是一个由编译器确定的常量,即4,而不是在运行时确定,这会导致每个输出只有四个八位字节。
如果将 PMD_Data.value()
结果的总大小分配给 size
,则输出可能具有更多八位字节,正如 RFU
中描述的 Frame types ECG
字段。
我将其开发为一个 Python 示例,说明如何从 Polar 设备捕获 ECG 和 ACC 数据。
[电子邮件受保护]:stuartlynne/bleexplore.git