1

I am using the following code to make an ftms service. This service is easily visible on the mobile phone as shown below but the python script below doesn't show that and gives some unknown junk service shown in the image:

My esp32 code:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEAdvertising.h>
#include <BLE2902.h>

// External globals (dummy values) bool fetchingAllowed = false; int modeInt = 0; int16_t powerTarget = 0; int16_t windspeed = 0; int16_t grade = 0; uint8_t crr = 0; uint8_t crw = 0;

#define SERVICE_FITNESS_MACHINE_UUID 0x1826
#define fitnessMachineService BLEUUID((uint16_t)SERVICE_FITNESS_MACHINE_UUID)
#define CHAR_INDOOR_BIKE_DATA_UUID 0x2AD2
#define CHAR_FITNESS_MACHINE_FEATURE_UUID 0x2ACC
#define CHAR_FITNESS_MACHINE_CONTROL_POINT_UUID 0x2AD9
#define CHAR_FITNESS_MACHINE_STATUS_UUID 0x2ADA

#define CHAR_INDOOR_BIKE_DATA_SIZE 13 const uint16_t indoorBikeDataCharacteristicDef = 0b0000100001010100; uint16_t speedOut = 0; uint16_t cadenceOut = 0; int16_t powerOut = 0; uint8_t bufferIndoorBikeData[CHAR_INDOOR_BIKE_DATA_SIZE] = {   (uint8_t)(indoorBikeDataCharacteristicDef & 0xff),   (uint8_t)(indoorBikeDataCharacteristicDef >> 8),   (uint8_t)(speedOut & 0xff),   (uint8_t)(speedOut >> 8),    (uint8_t)(cadenceOut & 0xff),  (uint8_t)(cadenceOut >> 8),   0x0, 0x0, 0x0,   (uint8_t)(powerOut & 0xff),    (uint8_t)(powerOut >> 8),   0x0, 0x0, };

#define CHAR_FITNESS_MACHINE_FEATURE_SIZE 8 uint8_t bufferFitnessMachineFeature[CHAR_FITNESS_MACHINE_FEATURE_SIZE] = {0x86, 0x50, 0x00, 0x00, 0x0C, 0xE0, 0x00, 0x00};

BLECharacteristic fitnessMachineFeatureCharacteristic (BLEUUID((uint16_t)CHAR_FITNESS_MACHINE_FEATURE_UUID), BLECharacteristic::PROPERTY_READ); BLECharacteristic indoorBikeDataCharacteristic (BLEUUID((uint16_t)CHAR_INDOOR_BIKE_DATA_UUID), BLECharacteristic::PROPERTY_NOTIFY); BLECharacteristic fitnessMachineControlPointCharacteristic (BLEUUID((uint16_t)CHAR_FITNESS_MACHINE_CONTROL_POINT_UUID), BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_INDICATE); BLECharacteristic fitnessMachineStatusCharacteristic (BLEUUID((uint16_t)CHAR_FITNESS_MACHINE_STATUS_UUID), BLECharacteristic::PROPERTY_NOTIFY);

BLEAdvertisementData advertisementData = BLEAdvertisementData(); bool deviceConnected = false;

class MyServerCallbacks: public BLEServerCallbacks  {
    void onConnect(BLEServer* pServer) 
    {
      deviceConnected = true;
      Serial.println("CONNECTED");
    };
    void onDisconnect(BLEServer* pServer) 
    {
      deviceConnected = false;
      Serial.println("DISCONNECTED");
    } };

void advertiseInit(void) {   BLEDevice::init("WH_PDC0EAD356A");

  BLEServer* pServer = BLEDevice::createServer();   pServer->setCallbacks(new MyServerCallbacks());

  // Fitness Machine Service   BLEService* pFTMS = pServer->createService(fitnessMachineService);   fitnessMachineFeatureCharacteristic.setValue(bufferFitnessMachineFeature, CHAR_FITNESS_MACHINE_FEATURE_SIZE);   pFTMS->addCharacteristic(&fitnessMachineFeatureCharacteristic);   pFTMS->addCharacteristic(&indoorBikeDataCharacteristic);   pFTMS->addCharacteristic(&fitnessMachineControlPointCharacteristic);   pFTMS->addCharacteristic(&fitnessMachineStatusCharacteristic);   indoorBikeDataCharacteristic.addDescriptor(new BLE2902());   fitnessMachineControlPointCharacteristic.addDescriptor(new BLE2902()); fitnessMachineStatusCharacteristic.addDescriptor(new BLE2902());   pFTMS->start();  // Start the Fitness Machine Service

  // Advertising   BLEAdvertising *pAdvertising = pServer->getAdvertising();   advertisementData.setFlags(ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);   advertisementData.setCompleteServices(BLEUUID((uint16_t)SERVICE_FITNESS_MACHINE_UUID)); pAdvertising->setAdvertisementData(advertisementData);   pAdvertising->addServiceUUID(fitnessMachineService);   pAdvertising->start();

  Serial.println("FTMS ready, advertising"); }

void updateFTMSData(int speed, int cadence, int power) {   speedOut = speed;   cadenceOut = cadence;   powerOut = power;

  bufferIndoorBikeData[2] = (uint8_t)(speedOut & 0xff);   bufferIndoorBikeData[3] = (uint8_t)(speedOut >> 8);    bufferIndoorBikeData[4] = (uint8_t)(cadenceOut & 0xff);   bufferIndoorBikeData[5] = (uint8_t)(cadenceOut >> 8);   bufferIndoorBikeData[9] = (uint8_t)(powerOut & 0xff);    bufferIndoorBikeData[10] = (uint8_t)(powerOut >> 8);

  indoorBikeDataCharacteristic.setValue(bufferIndoorBikeData, CHAR_INDOOR_BIKE_DATA_SIZE);

  if (deviceConnected)   {
    indoorBikeDataCharacteristic.notify();   } }

void setup()  {   Serial.begin(115200);   advertiseInit(); }

void loop()  {   // Add your logic to update speed, cadence, and power based on your requirements   int speed = 1000; // example value   int cadence = 80; // example value   int power = 500; // example value

  updateFTMSData(speed, cadence, power);

  delay(1000); // update every second }

The Python script and the output of the script is also shown:

import asyncio
from bleak import BleakScanner, BleakClient

async def main():
    target_name = "WH_PDC0EAD356A"
    target_address = None

    SERVICE_UUID = "00001826-0000-1000-8000-00805F9B34FB"
    CHARACTERISTIC_UUID = "00002AD2-0000-1000-8000-00805F9B34FB"

    devices = await BleakScanner.discover()
    for d in devices:
        if target_name == d.name:
            target_address = d.address
            print(f"Found target {target_name} Bluetooth device with address {target_address}")
            break

    if target_address is not None:
        async with BleakClient(target_address) as client:
            print(f"Connected: {client.is_connected}")

            # Print services of the device
            services = await client.get_services()
            for service in services:
                print(f"Service UUID: {service.uuid}")
                for characteristic in service.characteristics:
                    print(f"  Characteristic UUID: {characteristic.uuid}")

            while True:
                text = input()
                if text == "quit":
                    break

                await client.write_gatt_char(CHARACTERISTIC_UUID, bytes(text, 'UTF-8'), response=True)

                try:
                    data = await client.read_gatt_char(CHARACTERISTIC_UUID)
                    data = data.decode('utf-8')  # convert bytes to str
                    print(f"Received data: {data}")
                except Exception as e:
                    print(f"Error reading characteristic: {str(e)}")

    else:
        print("Could not find target Bluetooth device nearby")

asyncio.run(main())

The image below is on the App:

enter image description here

And the result of python is:

enter image description here

I am not sure why am I not able to detect the third service as the first two are easily discovered.

3
  • This might be unrelated, but as you can see in your output, get_services will be removed in future versions of bleak. Try to use the services property instead: bleak.readthedocs.io/en/latest/api/… Commented Jul 9 at 8:23
  • 1
    @MichaelKotzjan It doesnt make any difference still it gives the same Commented Jul 9 at 8:54
  • Could it be the BLE cache is out of date on your windows machine? Try refreshing it to see if it clears up. Or try using chrome://bluetooth-internals/#devices to get another view on Windows
    – ukBaz
    Commented Jul 9 at 12:04

1 Answer 1

0

The device/ESP32 was paired to my bluetooth in Laptop. As I unpaired it with laptop then the device was recognized by the python script.

Not the answer you're looking for? Browse other questions tagged or ask your own question.