RP 2040 and Polar H10

I have connected my RP2040 with a Polar H10 heartbeat sensor using the code below.

#include <ArduinoBLE.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  Serial.println("BLE Central - Peripheral Explorer");

  // start scanning for peripherals
  BLE.scan();
}

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();

    // see if peripheral is a LED
    if (peripheral.localName() == "Polar H10 9EF6E824") {
      // stop scanning
      BLE.stopScan();

      explorerPeripheral(peripheral);

      // peripheral disconnected, we are done
      while (1) {
        // do nothing
      }
    }
  }
}

void explorerPeripheral(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }

  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  // read and print device name of peripheral
  Serial.println();
  Serial.print("Device name: ");
  Serial.println(peripheral.deviceName());
  Serial.print("Appearance: 0x");
  Serial.println(peripheral.appearance(), HEX);
  Serial.println();

  // loop the services of the peripheral and explore each
  for (int i = 0; i < peripheral.serviceCount(); i++) {
    BLEService service = peripheral.service(i);

    exploreService(service);
  }

  Serial.println();

  // we are done exploring, disconnect
//  Serial.println("Disconnecting ...");
  //peripheral.disconnect();
 // Serial.println("Disconnected");
}

void exploreService(BLEService service) {
  // print the UUID of the service
  Serial.print("Service ");
  Serial.println(service.uuid());

  // loop the characteristics of the service and explore each
  for (int i = 0; i < service.characteristicCount(); i++) {
    BLECharacteristic characteristic = service.characteristic(i);

    exploreCharacteristic(characteristic);
  }
}

void exploreCharacteristic(BLECharacteristic characteristic) {
  // print the UUID and properties of the characteristic
  Serial.print("\tCharacteristic ");
  Serial.print(characteristic.uuid());
  Serial.print(", properties 0x");
  Serial.print(characteristic.properties(), HEX);

  // check if the characteristic is readable
  if (characteristic.canRead()) {
    // read the characteristic value
    characteristic.read();

    if (characteristic.valueLength() > 0) {
      // print out the value of the characteristic
      Serial.print(", value 0x");
      printData(characteristic.value(), characteristic.valueLength());
    }
  }
  Serial.println();

  // loop the descriptors of the characteristic and explore each
  for (int i = 0; i < characteristic.descriptorCount(); i++) {
    BLEDescriptor descriptor = characteristic.descriptor(i);

    exploreDescriptor(descriptor);
  }
}

void exploreDescriptor(BLEDescriptor descriptor) {
  // print the UUID of the descriptor
  Serial.print("\t\tDescriptor ");
  Serial.print(descriptor.uuid());

  // read the descriptor value
  descriptor.read();

  // print out the value of the descriptor
  Serial.print(", value 0x");
  printData(descriptor.value(), descriptor.valueLength());

  Serial.println();
}

void printData(const unsigned char data[], int length) {
  for (int i = 0; i < length; i++) {
    unsigned char b = data[i];

    if (b < 16) {
      Serial.print("0");
    }

    Serial.print(b, HEX);
  }
}

When I connect with the sensor, the result is as follows:

11:01:56.873 -> BLE Central - Peripheral Explorer
11:01:57.106 -> Found ea:1f:b5:f6:9c:5c 'Polar H10 9EF6E824' 180d
11:01:57.106 -> Connecting ...
11:01:57.624 -> Connected
11:01:57.624 -> Discovering attributes ...
11:02:00.347 -> Attributes discovered
11:02:00.347 -> 
11:02:00.347 -> Device name: Polar H10 9EF6E824
11:02:00.347 -> Appearance: 0x0
11:02:00.347 -> 
11:02:00.347 -> Service 1800
11:02:00.347 -> 	Characteristic 2a00, properties 0x2, value 0x506F6C617220483130203945463645383234
11:02:00.394 -> 		Descriptor 2803, value 0x020500012A
11:02:00.439 -> 		Descriptor 2a01, value 0x4103
11:02:00.439 -> 	Characteristic 2a01, properties 0x2, value 0x4103
11:02:00.486 -> 		Descriptor 2803, value 0x020700042A
11:02:00.533 -> 		Descriptor 2a04, value 0xF900900101005802
11:02:00.579 -> 	Characteristic 2a04, properties 0x2, value 0xF900900101005802
11:02:00.627 -> 		Descriptor 2803, value 0x020900A62A
11:02:00.627 -> 		Descriptor 2aa6, value 0x01
11:02:00.673 -> 	Characteristic 2aa6, properties 0x2, value 0x01
11:02:00.720 -> Service 1801
11:02:00.720 -> 	Characteristic 2a05, properties 0x20
11:02:00.720 -> 		Descriptor 2902, value 0x0000
11:02:00.720 -> Service 180d
11:02:00.720 -> 	Characteristic 2a37, properties 0x10
11:02:00.720 -> 		Descriptor 2902, value 0x0000
11:02:00.767 -> 		Descriptor 2803, value 0x021300382A
11:02:00.815 -> 		Descriptor 2a38, value 0x01
11:02:00.861 -> 	Characteristic 2a38, properties 0x2, value 0x01
11:02:00.861 -> Service 181c
11:02:00.861 -> 	Characteristic 2a99, properties 0xA
11:02:00.908 -> 		Descriptor 2803, value 0x0218009A2A
11:02:00.955 -> 		Descriptor 2a9a, value 0x
11:02:00.955 -> 	Characteristic 2a9a, properties 0x2
11:02:01.002 -> 		Descriptor 2803, value 0x281A009F2A
11:02:01.050 -> 		Descriptor 2b9f, value 0x
11:02:01.050 -> 	Characteristic 2a9f, properties 0x28
11:02:01.050 -> 		Descriptor 2902, value 0x0000
11:02:01.097 -> 		Descriptor 2803, value 0x8A1D008A2A
11:02:01.143 -> 		Descriptor 2a8a, value 0x
11:02:01.190 -> 	Characteristic 2a8a, properties 0x8A
11:02:01.237 -> 		Descriptor 2900, value 0x0100
11:02:01.237 -> 		Descriptor 2803, value 0x8A2000902A
11:02:01.284 -> 		Descriptor 2a90, value 0x
11:02:01.331 -> 	Characteristic 2a90, properties 0x8A
11:02:01.331 -> 		Descriptor 2900, value 0x0100
11:02:01.378 -> 		Descriptor 2803, value 0x0A2300802A
11:02:01.425 -> 		Descriptor 2a80, value 0x
11:02:01.425 -> 	Characteristic 2a80, properties 0xA
11:02:01.471 -> 		Descriptor 2803, value 0x0A25008C2A
11:02:01.518 -> 		Descriptor 2a8c, value 0x
11:02:01.565 -> 	Characteristic 2a8c, properties 0xA
11:02:01.612 -> 		Descriptor 2803, value 0x0A2700982A
11:02:01.612 -> 		Descriptor 2a98, value 0x
11:02:01.659 -> 	Characteristic 2a98, properties 0xA
11:02:01.706 -> 		Descriptor 2803, value 0x0A29008E2A
11:02:01.706 -> 		Descriptor 2a8e, value 0x
11:02:01.752 -> 	Characteristic 2a8e, properties 0xA
11:02:01.799 -> 		Descriptor 2803, value 0x0A2B00A22A
11:02:01.846 -> 		Descriptor 2aa2, value 0x
11:02:01.892 -> 	Characteristic 2aa2, properties 0xA
11:02:01.892 -> Service 180a
11:02:01.892 -> 	Characteristic 2a29, properties 0x2, value 0x506F6C617220456C656374726F204F7900
11:02:01.938 -> 		Descriptor 2803, value 0x023000242A
11:02:01.985 -> 		Descriptor 2a24, value 0x48313000
11:02:02.032 -> 	Characteristic 2a24, properties 0x2, value 0x48313000
11:02:02.032 -> 		Descriptor 2803, value 0x023200252A
11:02:02.079 -> 		Descriptor 2a25, value 0x394546364538323400
11:02:02.127 -> 	Characteristic 2a25, properties 0x2, value 0x394546364538323400
11:02:02.127 -> 		Descriptor 2803, value 0x023400272A
11:02:02.173 -> 		Descriptor 2a27, value 0x30303736303639302E303300
11:02:02.173 -> 	Characteristic 2a27, properties 0x2, value 0x30303736303639302E303300
11:02:02.220 -> 		Descriptor 2803, value 0x023600262A
11:02:02.267 -> 		Descriptor 2a26, value 0x352E302E3000
11:02:02.267 -> 	Characteristic 2a26, properties 0x2, value 0x352E302E3000
11:02:02.313 -> 		Descriptor 2803, value 0x023800282A
11:02:02.359 -> 		Descriptor 2a28, value 0x332E312E3100
11:02:02.406 -> 	Characteristic 2a28, properties 0x2, value 0x332E312E3100
11:02:02.406 -> 		Descriptor 2803, value 0x023A00232A
11:02:02.453 -> 		Descriptor 2a23, value 0xE8F69EFEFF1A9EA0
11:02:02.500 -> 	Characteristic 2a23, properties 0x2, value 0xE8F69EFEFF1A9EA0
11:02:02.500 -> Service 180f

I want the program to return values for heart rate. Is there some changes I can make in the program, or something in the results that represents this?

IIRC, the Heart Rate Service is 180D and the characteristic is 2A37. It is observable (the property 0x10 means that it sends data via notifications). So if the BLE library (I have not used BLE on Arduino!) allows it, you can sign up for change notifications and get the HR data that way.

I tried adding the following code
BLEUnsignedCharCharacteristic HeartRate("2A37", BLEIndicate | BLENotify);
but nothing changed. Any ideas as to how I can find the data?

I have never used this library: my BLE experience is with using BLE modules directly or writing apps to connect to them. This snippet from the ArduinoBle library documentation might be helpful: ArduinoBLE - Arduino Reference

I now want to return ecg data from the sensor. Do you know what the characteristic is for this?

I don't recall that being available on the H10, but a quick google shows that it is. This project might be helpful. I don't remember ECG being a standard Heart Rate Service characteristic, so it's probably manufacturer specific.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.