Closed xmeow closed 7 years ago
This is a bit strange. In most cases you should be able to write up to 20 bytes by default on all characteristics (MTU size - some BLE heading). Could it be the application you are testing with that has this limitation?
These are my test results on the pca10040:
MicroPython code:
from ubluepy import Service, Characteristic, UUID, Peripheral, constants
from pyb import LED
def event_handler(id, handle, data):
if id == constants.EVT_GAP_CONNECTED:
# connected
LED(2).on()
elif id == constants.EVT_GAP_DISCONNECTED:
# disconnect
LED(2).off()
elif id == constants.EVT_GATTS_WRITE:
print("Write, len: %d, data:", len(data), data)
else:
print("BLE event:", id, "handle:", handle)
s = Service(UUID(0xABCD))
c0 = Characteristic(UUID(0x1234), props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP)
s.addCharacteristic(c0)
p = Peripheral()
p.addService(s)
p.setConnectionHandler(event_handler)
p.advertise(device_name="test_char", services=[s])
Linux gatttool command trace:
$ gatttool -b 'FE:70:57:3B:04:50' -t random --interactive
[FE:70:57:3B:04:50][LE]> connect
Attempting to connect to FE:70:57:3B:04:50
Connection successful
[FE:70:57:3B:04:50][LE]> characteristics
handle: 0x0002, char properties: 0x0a, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x0008, char properties: 0x02, char value handle: 0x0009, uuid: 00002aa6-0000-1000-8000-00805f9b34fb
handle: 0x000c, char properties: 0x0c, char value handle: 0x000d, uuid: 00001234-0000-1000-8000-00805f9b34fb
[FE:70:57:3B:04:50][LE]> char-write-req 0x000d 7468697320697320612074657374
Characteristic value was written successfully
[FE:70:57:3B:04:50][LE]>
As a result the ubluepy event handler gets a write request with the > 4 bytes test string:
>>> Write, len: %d, data: 14 bytearray(b'this is a test')
There is a hidden setting which i have added to get some more verbose logs in the bluetooth driver (only working if you are using UART REPL, and not BLE REPL). https://github.com/tralamazza/micropython/blob/master/nrf/drivers/bluetooth/ble_drv.c#L41 Could you flip this define to 1 and see if you get any traces which could give a hint on why there is a 4-byte limitation for you?
Thank you for quick reply, I make a mistake that write char only accept 2 byte instead of 4. Here is the code I use, modified from modublupy header. A successful write will trig the EVT_GATTS_WRITE event. I don't have a linux device with ble support, and not sure if this is an issue of iOS or LightBlue app.
from ubluepy import Service, Characteristic, UUID, Peripheral, constants
def event_handler(id, handle, data):
#print("BLE event:", id, "handle:", handle)
#print(data)
global p
global s
if id == constants.EVT_GAP_CONNECTED:
print("connected")
elif id == constants.EVT_GAP_DISCONNECTED:
print("diconnected")
# restart advertisment
p.advertise(device_name="micr", services=[s])
elif id == constants.EVT_GATTS_WRITE:
print("Write, len: %d, data:", len(data), data)
# u0 = UUID("0x180D") # HRM service
# u1 = UUID("0x2A37") # HRM measurement
u0 = UUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
u1 = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
u2 = UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e")
s = Service(u0)
c0 = Characteristic(u1, props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP)
c1 = Characteristic(u2, props = Characteristic.PROP_NOTIFY, attrs = Characteristic.ATTR_CCCD)
s.addCharacteristic(c0)
s.addCharacteristic(c1)
p = Peripheral()
p.addService(s)
p.setConnectionHandler(event_handler)
p.advertise(device_name="micr", services=[s])
And here is debug output with BLE_DRIVER_VERBOSE set to 1.
import pyboard
pyboard.execfile('ubluepy_test.py', device='COM9')
------ start of ublupy -------
Is enabled status: 0
SoftDevice enable status: 0
IRQ enable status: 0
BLE ram size: 9824
BLE enable status: 0
Is enabled status: 0
Is enabled status: 0
Is enabled status: 0
Is enabled status: 0
Device name applied
encoded uuid for service 0: 9e ca dc 24 0e e5 a9 e0 93 f3 a3 b5 01 00 40 6e
ADV: uuid size: 16, type: 20, uuid: 1, vs_idx: 2
Set Adv data size: 27
------ here I connect with my phone -----
------ and a successful write 0x1234------
GAP CONNECT
connected
GAP CONN PARAM UPDATE
GATTS EVT EXCHANGE MTU REQUEST
GATTS write
Write, len: %d, data: 2 bytearray(b'\x124')
------ if write value longer than 2 byte nothing output --------
2 bytes sounds like you might be writing the CCCD descriptor of the notification characteristic.
In this case of the ubluepy header example i have swapped the UUID of TX and RX as there was a bug in Nordic SDK naming of the characteristics and implementation (fixed in latest SDK). If the phone/tablet applications have handle values hardcoded, and do not perform a service discovery, it might trigger a write to the wrong handle.
I believe this is the correct UUID's: RX Characteristic (UUID: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E) TX Characteristic (UUID: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E)
You can do one easy test, to swap the UUID's between the two characteristics and see if the app works better.
Awesome, after swape the uuid everything works as expected. Thank you so much~
When I try to start a peripheral with modubluepy, I found that any write character accept no more than 4 byte char. PS: I use a PCA10040 devboard and LightBlue app to go through the test.