bleak.exc.BleakError: Characteristic 00002011-0000-1000-8000-00805f9b34fb not found!
- 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))
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 thanks for your comment!
I tried both UUID settings.
When using service_explorer.py, the message is:
usage: service_explorer.py [-h] (--name
You need to provide the correct command line parameters so that the script will connect to your device.
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...
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
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...
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.
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
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.
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);