ble-serial
ble-serial copied to clipboard
Bluetooth connection failed: Could not write value to characteristic 0024: Protocol Error 0x0A: Attribute Not Found
Hi,
I'm working on a project with the HM-10 module. I've tested it with my phone using a Bluetooth-serial app, and communication works fine there (I have software that parses commands and sends back responses). However, when I use ble-serial or bleak, I can connect to the module, send only one command, get one response, and then the connection drops. Additionally, if I just connect to the device and open a serial terminal like PuTTY and try to send even one character, I get the same error. Only by being "fast" after the connection is established or by using a script can I get this one response before the connection drops. The error I get is:
| ERROR | main.py: Bluetooth connection failed: Could not write value b'CHECK_CONNECTION\r\n' to characteristic 0024: Protocol Error 0x0A: Attribute Not Found.
I have read and tried the solutions mentioned in cannot write to BLE module via Bluetooth #23, but nothing worked. I have run out of ideas.
Also, I am a student and all this is very new to me, so I apologize in advance if my description is insufficient. I will provide any data necessary to resolve my issue.
Log messages
- ble-scan command
> ble-scan -d D4:36:39:8C:B9:43
Started deep scan of D4:36:39:8C:B9:43
Found device D4:36:39:8C:B9:43: robot (out of 1)
SERVICE 00001800-0000-1000-8000-00805f9b34fb (Handle: 1): Generic Access Profile
CHARACTERISTIC 00002a00-0000-1000-8000-00805f9b34fb (Handle: 2): Device Name ['read']
CHARACTERISTIC 00002a01-0000-1000-8000-00805f9b34fb (Handle: 4): Appearance ['read']
CHARACTERISTIC 00002a02-0000-1000-8000-00805f9b34fb (Handle: 6): Peripheral Privacy Flag ['read', 'write']
CHARACTERISTIC 00002a03-0000-1000-8000-00805f9b34fb (Handle: 8): Reconnection Address ['write']
CHARACTERISTIC 00002a04-0000-1000-8000-00805f9b34fb (Handle: 10): Peripheral Preferred Connection Parameters ['read']
SERVICE 00001801-0000-1000-8000-00805f9b34fb (Handle: 12): Generic Attribute Profile
CHARACTERISTIC 00002a05-0000-1000-8000-00805f9b34fb (Handle: 13): Service Changed ['indicate']
DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 15): Client Characteristic Configuration
SERVICE 0000180a-0000-1000-8000-00805f9b34fb (Handle: 16): Device Information
CHARACTERISTIC 00002a23-0000-1000-8000-00805f9b34fb (Handle: 17): System ID ['read']
CHARACTERISTIC 00002a24-0000-1000-8000-00805f9b34fb (Handle: 19): Model Number String ['read']
CHARACTERISTIC 00002a25-0000-1000-8000-00805f9b34fb (Handle: 21): Serial Number String ['read']
CHARACTERISTIC 00002a26-0000-1000-8000-00805f9b34fb (Handle: 23): Firmware Revision String ['read']
CHARACTERISTIC 00002a27-0000-1000-8000-00805f9b34fb (Handle: 25): Hardware Revision String ['read']
CHARACTERISTIC 00002a28-0000-1000-8000-00805f9b34fb (Handle: 27): Software Revision String ['read']
CHARACTERISTIC 00002a29-0000-1000-8000-00805f9b34fb (Handle: 29): Manufacturer Name String ['read']
CHARACTERISTIC 00002a2a-0000-1000-8000-00805f9b34fb (Handle: 31): IEEE 11073-20601 Regulatory Cert. Data List ['read']
CHARACTERISTIC 00002a50-0000-1000-8000-00805f9b34fb (Handle: 33): PnP ID ['read']
SERVICE 0000ffe0-0000-1000-8000-00805f9b34fb (Handle: 35): Vendor specific
CHARACTERISTIC 0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 36): Characteristic 6 ['read', 'write-without-response', 'write', 'notify']
DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 38): Client Characteristic Configuration
DESCRIPTOR 00002901-0000-1000-8000-00805f9b34fb (Handle: 39): Characteristic User Description
Completed deep scan of D4:36:39:8C:B9:43
- ble-serial command
> ble-serial -d D4:36:39:8C:B9:43 -w 0000ffe1-0000-1000-8000-00805f9b34fb -v
17:21:52.078 | DEBUG | main.py: Running: Namespace(verbose=1, timeout=5.0, adapter='hci0', mtu=20, device='D4:36:39:8C:B9:43', addr_type='public', service_uuid=None, write_uuid='0000ffe1-0000-1000-8000-00805f9b34fb', read_uuid=None, mode='rw', filename=None, binlog=False, port='BLE', tcp_host='127.0.0.1', tcp_port=None)
17:21:52.078 | DEBUG | proactor_events.py: Using proactor: IocpProactor
17:21:52.090 | INFO | ble_interface.py: Receiver set up
17:21:52.158 | INFO | ble_interface.py: Trying to connect with D4:36:39:8C:B9:43: None
17:21:55.165 | INFO | ble_interface.py: Device D4:36:39:8C:B9:43 connected
17:21:55.165 | DEBUG | ble_interface.py: Characteristic candidates for write:
0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 36): Characteristic 6 ['read', 'write-without-response', 'write', 'notify']
17:21:55.165 | INFO | ble_interface.py: Found write characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 36)
17:21:55.165 | DEBUG | ble_interface.py: No notify uuid specified, trying builtin list
17:21:55.165 | DEBUG | ble_interface.py: Characteristic candidates for notify:
0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 36): Characteristic 6 ['read', 'write-without-response', 'write', 'notify']
17:21:55.165 | INFO | ble_interface.py: Found notify characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 36)
17:21:55.184 | INFO | main.py: Running main loop!
17:21:58.203 | DEBUG | windows_com0com.py: TX queue timeout: was empty
17:22:01.209 | DEBUG | windows_com0com.py: TX queue timeout: was empty
17:22:02.952 | DEBUG | windows_com0com.py: Read: b'CHECK_CONNECTION\r\n'
17:22:02.952 | DEBUG | ble_interface.py: Sending b'CHECK_CONNECTION\r\n'
17:22:03.061 | ERROR | main.py: Bluetooth connection failed: Could not write value b'CHECK_CONNECTION\r\n' to characteristic 0024: Protocol Error 0x0A: Attribute Not Found
17:22:03.061 | WARNING | main.py: Shutdown initiated
17:22:03.061 | DEBUG | windows_com0com.py: Read: b''
17:22:03.061 | INFO | windows_com0com.py: Stopping RX+TX loop
17:22:03.061 | DEBUG | windows_com0com.py: RX loop ended, alive=False open=False
17:22:03.065 | DEBUG | ble_interface.py: Received notify from 0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 36): Characteristic 6: bytearray(b'OK\r\n')
17:22:03.065 | DEBUG | windows_com0com.py: Write: bytearray(b'OK\r\n')
17:22:06.346 | WARNING | ble_interface.py: Device D4:36:39:8C:B9:43 disconnected
17:22:06.346 | INFO | ble_interface.py: Stopping Bluetooth event loop
17:22:06.346 | INFO | ble_interface.py: Bluetooth disconnected
17:22:06.346 | INFO | main.py: Shutdown complete.
17:22:06.346 | DEBUG | main.py: Asyncio execption handler called Attempting to use a port that is not open
17:22:06.346 | INFO | windows_com0com.py: Stopping RX+TX loop
17:22:06.346 | INFO | ble_interface.py: Stopping Bluetooth event loop
I've tried both Linux and Windows: Setup 1
- OS: Windows 11
- Bluetooth Hardware: HM-10
- Python Version: Python 3.12.3
- ble-serial: 2.7.1
- bleak: 0.22.1
- pyserial: 3.5
Setup 2
- OS: Ubuntu 22.04
- Bluetooth Hardware: HM-10
- BlueZ Version: tried 5.51, 5.58, 5.66
- Python Version: 3.10.12
- ble-serial: 2.7.1
- bleak: 0.22.1
- pyserial: 3.5
Additional Context I've tried just receiving from my module and it works okay. Im sending Hex data from lidar through HM-10 module so the problem is somewhere in ble-serial. This is the script i use for my connection. First im establishing connection on COM9 port ant than i send data through it. As i said previously i can get respond for first command but than the connection drops. (I have also tried code in /examples folder and it works the same - drops connection after first data is send).
Code:
import subprocess
import serial
import time
import os
def send_command(ser, command):
command += '\r\n'
ser.write(command.encode())
print(f"Sent: {command.strip()}")
def wait_for_response(ser, expected_response):
start_time = time.time()
response = ""
while time.time() - start_time < 2:
if ser.in_waiting > 0:
response = ser.readline().decode().strip()
print(f"Received: {response}")
if expected_response in response:
return response
return None
def start_ble_serial(mac_address):
command = ['ble-serial', '-d', mac_address]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return process
def connect_serial(port):
ser = serial.Serial(port, 9600, timeout=None)
return ser
def main():
mac_address = 'D4:36:39:8C:B9:43'
if os.name == 'nt': # Windows
virtual_port = 'COM9'
else: # Linux
virtual_port = '/tmp/ttyBLE'
ble_process = start_ble_serial(mac_address)
time.sleep(6) # Allow time for the connection to establish
try:
ser = connect_serial(virtual_port)
print("Connected to", virtual_port)
send_command(ser, 'CHECK_CONNECTION\r\n')
response = wait_for_response(ser, 'OK')
if response:
print("Robot is connected.")
else:
print("No response from robot.")
while True:
command = input("Enter a command: ")
if command.lower() == 'exit':
break
send_command(ser, command)
response = wait_for_response(ser, 'OK')
if response:
print("Command executed successfully.")
else:
print("No response from robot.")
finally:
ser.close()
ble_process.terminate()
ble_process.wait()
print("BLE serial connection closed.")
if __name__ == '__main__':
main()
This is the result i get:
> python .\pc_controller.py
Connected to COM9
Sent: CHECK_CONNECTION
Received: OK
Robot is connected.
Enter a command: foo
Sent: foo
No response from robot.
Hi @Wocck, your parameters look correct and it's indeed weird that bleak throws after obviously sending the string. Few ideas:
- Are you able to write with bluetothctl (https://stackoverflow.com/a/74080602) on the Linux setup?
- Also you can try ble-serial with the double verbose (-vv) option, this might show more low level errors.
- Did you try a different PC/Laptop? Maybe the ble chipset there is the culprit.
- About the module: I did a lot of tests on a original HM-10 with V710 firmware and never had problems. My scan results are quite different though, doesn't offer a "Device info" or "Generic Access Profile" service and is configured with
ATcommands. Did you flash a custom firmware? Otherwise it's probably a clone and that can cause issues: https://blog.yavilevich.com/2018/04/should-you-throw-away-your-cc41-hm-10-clones-now-that-android-8-is-here/