This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Cannot write to more than one characteristic

Greetings,

I have two nRF52840's where one is modeled as a peripheral and the other as a central. I have created a custom service and characteristics on the peripheral and can connect and read and write. However, I can perform one write and not more. In the example beneath, I am trying to write to the same characteristic twice in consequtive order, as can be seen in the discover_all_completed function.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct bt_write_client {
/** Connection object. */
struct bt_conn *conn;
/** Internal state. */
atomic_t state;
/** GATT write parameters write request. */
struct bt_gatt_write_params write_params;
/** Characteristic handle. */
uint16_t val_handle;
/** Handle of the CCCD. */
uint16_t ccc_handle;
/** Characteristic properties. */
uint8_t properties;
/** Characteristic value?. */
uint8_t char_value;
/** Application write callbacks. */
bt_write_cb_t write_cb;
};
struct bt_write_client write_client;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

However, on the peripheral side, I just receive the write of characteristic to be 5:5:5:5, and not 0:1:2:3 afterwards, and I get one error message of "writing to characteristic failed: -120", which looking at errno.h is #define EALREADY 120 /**< Operation already in progress */. I tried putting a k_mutex_lock in bt_write_to_characteristic and k_mutex_unlock in on_sent, but that didn't help either.

This code is largely based on the nRF Uart Service sample / nus_client.c. Could you see what might be the problem?

Best regards,

Jonas

  • You can try to use nRF Connect for Desktop as peer device (e.g. central here) while debugging. I suspect in this case that you are doing an write request, this needs to be handled in the peer before next write request can be executed. If you use write command instead then you avoid this.

    Kenneth

  • Thanks for your quick reply, Kenneth.

    Do you mean that zephyrs bt_gatt_write is a write request and another function is a write command? Or have I misunderstood you?

    Jonas

  • To add onto previous statement: if bt_gatt_write_without_response() is the option for a command, then that is sadly not feasible for our application. However, it should be possible to write to more than only one characteristic once per connection while still getting write acknowledgements from bt_gatt_write, right?

  • Both write request and write commands are acknowledged and retransmissted on the link layer, the only difference is really that write request also require an acknowledgement from the application on the peer. I have not see any lost packets from either really. 

    It should be possible to write to a different characteristic while waiting yes.

  • Alright, so I didn't get any further trying to sequentially use bt_gatt_write, but it worked once I wrapped it into a work item and placed it on a work queue. Is this the preferred way to do it, or do you have other best practices for writing to multiple characteristics / multiple times to the same one.

1 2