bleak icon indicating copy to clipboard operation
bleak copied to clipboard

bleak.exc.BleakError: Characteristic 00002011-0000-1000-8000-00805f9b34fb not found!

Open Thm14 opened this issue 2 years ago • 10 comments

  • bleak version: 0.20.2
  • Python version:3.11
  • Operating System: Windows 10
  • BlueZ version (bluetoothctl -v) in case of Linux:

Description

I need to measure the accelerations of a moving object. For this, I am using the Arduino Nano 33, which has the integrated sensor IMU LSM9DS1, so I am trying to read and save the accelerations from the sensor and be able to keep them in the computer, all through communication BLE, for this, I am using a code that I found on the web (I attach them below, credits to: Antony García González from PanamaHitek, [https://panamahitek.com/comunicacion-inalambrica-entre-arduino-y-python-usando-ble/]) the problem is that I get an error: raise BleakError(f"Characteristic {char_specifier} not found!") bleak.exc.BleakError: Characteristic 00002011-0000-1000-8000-00805f9b34fb not found!

The first thing I thought was that the UUID must be misspelled or it had to be another, I used two applications on my cell phone: nRF Connect and BLE Scanner to know the characteristics, and in my opinion, the numbers are fine (they are the same as the script), but the error continues

What I Did

File "C:\Users\Tomás Herrera Muño\Dropbox\PhD PUC\Tesis\Proyecto Towing Tank\Arduino\Códigos\Nano 33 BLE\read_Nano33.py", line 46, in run
    await client.start_notify("00002011-0000-1000-8000-00805f9b34fb", handle_accel_notification)
  File "C:\Users\Tomás Herrera Muño\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\bleak\__init__.py", line 705, in start_notify
    raise BleakError(f"Characteristic {char_specifier} not found!")
bleak.exc.BleakError: Characteristic 00002011-0000-1000-8000-00805f9b34fb not found!

Logs

Include any relevant logs here.

Arduino script:
#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h>

// Declare a BLE service with UUID "1001"
BLEService IMUservice("1001");

// Declare two BLE characteristics for the accelerometer and gyroscope data, both with UUIDs "2001" and "2011" respectively.
// The characteristics are readable and notify, and have a maximum data length of 20 bytes.
BLECharacteristic accelData("2001", BLERead | BLENotify, 20);
BLECharacteristic gyroData("2011", BLERead | BLENotify, 20);

void setup() {
  // Initialize the BLE module
  if (!BLE.begin()) {
    // If the BLE module fails to initialize, enter an infinite loop
    while (1) {
    }
  }

  // Initialize the IMU
  if (!IMU.begin()) {
    // If the IMU fails to initialize, enter an infinite loop
    while (1) {
    }
  }

  // Set the device name and local name to "IMU"
  BLE.setDeviceName("IMU");
  BLE.setLocalName("IMU");

  // Add the service to the BLE module
  BLE.setAdvertisedService(IMUservice);

  // Add the two characteristics to the service
  IMUservice.addCharacteristic(accelData);
  IMUservice.addCharacteristic(gyroData);

  // Add the service to the BLE module
  BLE.addService(IMUservice);

  // Set the connection interval for the BLE connection
  BLE.setConnectionInterval(8, 8);

  // Enable the BLE module to be connectable
  BLE.setConnectable(true);

  // Start advertising the BLE connection
  BLE.advertise();
}

void loop() {
  float acX, acY, acZ, gX, gY, gZ;

  // Get the connected BLE central device
  BLEDevice central = BLE.central();
  if (central) {
    // If there is a connected BLE central device, enter an infinite loop
    while (central.connected()) {
      // Read the accelerometer data from the IMU device
      IMU.readAcceleration(acX, acY, acZ);

      // Create a string with the accelerometer data
      String accelString = String(acX) + "," + String(acY) + "," + String(acZ);

      // Write the accelerometer data to the BLE characteristic
      accelData.writeValue(accelString.c_str());

      // Read the gyroscope data from the IMU device
      IMU.readGyroscope(gX, gY, gZ);

      // Create a string with the gyroscope data
      String gyroString = String(gX) + "," + String(gY) + "," + String(gZ);

      // Write the gyroscope data to the BLE characteristic
      gyroData.writeValue(gyroString.c_str());

      // Wait 7 milliseconds before sending the next data
      delay(7);
    }
  }
}

Python script:

import asyncio, time, json
from bleak import BleakClient

# Function to handle accelerometer data received as a notification
def handle_accel_notification(sender, data):
    # Split the data into separate x, y, z values
    x, y, z = data.decode().split(',')
    acX = float(x)
    acY = float(y)
    acZ = float(z)

    # Get the current time
    timestamp = time.time()

    # Create a dictionary with the accelerometer data
    accel_data = {"acc_x": acX, "acc_y": acY, "acc_z": acZ, "Timestamp": timestamp}

    # Write the accelerometer data to a JSON file
    with open("data.json", "a") as json_file:
        json.dump(accel_data, json_file)
        json_file.write(',\n')

# Function to handle gyroscope data received as a notification
def handle_gyro_notification(sender, data):
    # Split the data into separate x, y, z values
    gx, gy, gz = data.decode().split(',')
    gX = float(gx)
    gY = float(gy)
    gZ = float(gz)

    # Get the current time
    timestamp = time.time()

    # Create a dictionary with the gyroscope data
    gyro_data = {"gy_x": gX, "gy_y": gY, "gy_z": gZ, "Timestamp": timestamp}

    # Write the gyroscope data to a JSON file
    with open("data.json", "a") as json_file:
        json.dump(gyro_data, json_file)
        json_file.write(',\n')

# Asynchronous function to connect to the BLE peripheral
async def run(address, loop):
    async with BleakClient(address, loop=loop) as client:
        # Start receiving notifications for the accelerometer data
        await client.start_notify("00002011-0000-1000-8000-00805f9b34fb", handle_accel_notification)

        # Start receiving notifications for the gyroscope data
        await client.start_notify("00002011-0000-1000-8000-00805f9b34fb", handle_gyro_notification)

        # Continuously run the loop
        while True:
            await asyncio.sleep(0.001)

# Address of the BLE peripheral to connect to
address = "7E:36:B3:47:6F:DA"

# Get the event loop
loop = asyncio.get_event_loop()

# Run the asynchronous function
loop.run_until_complete(run(address, loop))

Thm14 avatar Jul 27 '23 15:07 Thm14

What happens when you run the service_explorer.py example with this device?

Does it work if you use 128-bit UUIDs on the arduino instead of 16-bit UUIDs?

dlech avatar Jul 27 '23 15:07 dlech

Dlech thanks for your comment! I tried both UUID settings. When using service_explorer.py, the message is: usage: service_explorer.py [-h] (--name | --address

) [--macos-use-bdaddr] [--services [ ...]] [-d] service_explorer.py: error: one of the arguments --name --address is required

Thm14 avatar Jul 27 '23 16:07 Thm14

You need to provide the correct command line parameters so that the script will connect to your device.

dlech avatar Jul 27 '23 18:07 dlech

I see, I'm new to python, I don't know much about the nomenclature, I understand that it should be: python service_explorer.py--IMU--7E:36:B3:47:6F:DA ?? which would be the name: IMU and the address: 7E:36:B3:47:6F:DA, I don't know if it is with those hyphens, if it has a space or not, or if some other input parameter is missing to perform the scan...

Thm14 avatar Jul 27 '23 19:07 Thm14

python service_explorer.py--IMU--7E:36:B3:47:6F:DA ??

python service_explorer.py --address 7E:36:B3:47:6F:DA

or

python service_explorer.py --name IMU

dlech avatar Jul 28 '23 15:07 dlech

Hello!!!, I was able to run the code "service explorer", it gives the following results:

C:\Users\Tomás Herrera Muño\Dropbox\PhD PUC\Tesis\Proyecto Towing Tank\Arduino\Códigos\Nano 33 BLE>python service_explorer.py --address 7E:36:B3:47:6F:DA
2023-07-31 09:28:30,443 __main__ INFO: starting scan...
2023-07-31 09:28:30,751 __main__ INFO: connecting to device...
2023-07-31 09:28:31,229 __main__ INFO: connected
2023-07-31 09:28:31,229 __main__ INFO: [Service] 00001800-0000-1000-8000-00805f9b34fb (Handle: 1): Generic Access Profile
2023-07-31 09:28:31,245 __main__ ERROR:   [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb (Handle: 2): Device Name (read), Error: Could not read characteristic handle 2: Unreachable
2023-07-31 09:28:31,246 __main__ ERROR:   [Characteristic] 00002a01-0000-1000-8000-00805f9b34fb (Handle: 4): Appearance (read), Error: Not connected
2023-07-31 09:28:31,247 __main__ INFO: [Service] 00001801-0000-1000-8000-00805f9b34fb (Handle: 6): Generic Attribute Profile
2023-07-31 09:28:31,247 __main__ INFO:   [Characteristic] 00002a05-0000-1000-8000-00805f9b34fb (Handle: 7): Service Changed (indicate)
2023-07-31 09:28:31,248 __main__ ERROR:     [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 9): Client Characteristic Configuration, Error: Not connected
2023-07-31 09:28:31,248 __main__ INFO: [Service] 00001101-0000-1000-8000-00805f9b34fb (Handle: 10): Serial Port
2023-07-31 09:28:31,249 __main__ ERROR:   [Characteristic] 00002101-0000-1000-8000-00805f9b34fb (Handle: 11): Vendor specific (read,notify), Error: Not connected
2023-07-31 09:28:31,250 __main__ ERROR:     [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 13): Client Characteristic Configuration, Error: Not connected
2023-07-31 09:28:31,251 __main__ ERROR:   [Characteristic] 00002102-0000-1000-8000-00805f9b34fb (Handle: 14): Vendor specific (read,notify), Error: Not connected
2023-07-31 09:28:31,251 __main__ ERROR:     [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 16): Client Characteristic Configuration, Error: Not connected
2023-07-31 09:28:31,252 __main__ ERROR:   [Characteristic] 00002103-0000-1000-8000-00805f9b34fb (Handle: 17): Vendor specific (read,notify), Error: Not connected
2023-07-31 09:28:31,252 __main__ ERROR:     [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 19): Client Characteristic Configuration, Error: Not connected
2023-07-31 09:28:31,253 __main__ INFO: disconnecting...
2023-07-31 09:28:31,261 __main__ INFO: disconnected

Apparently it's not reading the characteristic, and that's why many errors come out later...

Thm14 avatar Jul 31 '23 14:07 Thm14

You are supposed to pay the Bluetooth SIG if you want your own 16-bit UUID. The 16-bit UUIDs you are using may be blocked by Windows. For both of these reasons, I have suggested using 128-bit UUIDs instead.

dlech avatar Jul 31 '23 15:07 dlech

I tried that and now the error is another: in start_notify await winrt_char.write_client_characteristic_configuration_descriptor_async(OSError: [WinError -2147467260] Operación anulada

Thm14 avatar Jul 31 '23 16:07 Thm14

It looks like the device is disconnecting before it finishes enumerating the characteristics. I would log Bluetooth packets to see what is going on. Probably something misconfigured on the Arduino or a Windows caching issue.

dlech avatar Jul 31 '23 18:07 dlech

Finally I was able to measure, they were the UUID of the IMU that the board brings, the correct ones for my ARDUINO NANO 33 BLE board are:

// Declare a BLE service with UUID:
BLEService IMUservice("19B10010-E8F2-537E-4F6C-D104768A1214");
// Declare two BLE characteristics for the accelerometer and gyroscope data, both with UUIDs:
BLECharacteristic accelData("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);
BLECharacteristic gyroData("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);

Thm14 avatar Aug 09 '23 19:08 Thm14