This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf52-dk in nrf52805 mode, sending long BLE UART command works on DK, not on external chip

Hi all,

I'm a beginning hobbyist with nRF52. I'm programming a BC805m using my nRF52-dk and nRF Connect SDK v1.9.0 (zephyr & Segger Embedded Studio).

The learning curve was quite steep, but I'm 99% done with my project. There is one issue remaining.

My project is a key fob to turn on an e-bike over BLE. There are three commands: A) turn bike on, B) turn bike off, C) toggle lights. These use two different GATT services. A+B are done by sending a single byte via a device specific GATT service. C is via the standard UART over BLE GATT service.

On the DK (even in 52805 mode) everything is working great.

On the external module, A and B work great. C does nothing. There is no error. This is the code snippet that I'm using (the exact same code and config are working the nrf52-dk in both 52805 and 52832 mode).


static void function toggleLights() {
    uint8_t d[] = {0x0A, 0x10, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0xd4, 0xb1}; // off
    bt_gatt_write_without_response(default_conn, 0x38, d, 11, false);
}

The only configuration change I had to make for the external module to work was to use CLOCK_CONTROL_NRF_K32SRC_RC as there is no external crystal attached to the BC805m.

Can someone point me in the right direction to start debugging this? Let me know if you need more information.

Edit 1: Via the debugger I've confirmed that the handle (0x38) is the same on the BC805m module.

Edit 2: For reference, this is the function that does work on both modules.

static void bike_turn_off() {
    uint8_t d[] = {0};
    bt_gatt_write_without_response(default_conn, 0x19, d, 1, false);
}

Thank you!

Jouke

Parents
  • FINALLY! I fixed it! There are still some mysteries, but it turns out that I had to subscribe to the UART Rx notify service to get this to work.

    static struct bt_gatt_subscribe_params subscribe_params;
    
    static uint8_t notify_func(struct bt_conn *conn,struct bt_gatt_subscribe_params *params, const void *data, uint16_t length)
    {
    	if (!data) {
    		printk("Ubsubscribed\n");
    		params->value_handle = 0;
    		return BT_GATT_ITER_STOP;
    	}
    
    	printk("Notification: data %p length %u\n", data, length);
    
    	return BT_GATT_ITER_CONTINUE;
    }
    
    static void write_func(struct bt_conn *conn, uint8_t conn_err,  struct bt_gatt_subscribe_params *params)
    {
    	printk("Write callback\n");
    }
    
    static void subscribe() {    
    //    subscribe_params.flags = 0x00;
    //    subscribe_params.node = 0x00;
        subscribe_params.ccc_handle = 0x3b;
        subscribe_params.notify = &notify_func;
        subscribe_params.value = BT_GATT_CCC_NOTIFY;
        subscribe_params.value_handle = 0x3a;
        subscribe_params.write  = &write_func;
        bt_gatt_subscribe(default_conn, &subscribe_params);
    }

    I figured it out by reproducing the same code on an esp32 and sniffing that traffic. It had the same problem, until I turned on the notify callback there. After that I had to puzzle a bit with how the callback could be done in the nrf connect sdk (your documentation REALLY needs more examples, most of the basic functionality is impossible to find on the internet).

    The mystery that still remains is: why does it work on the DK with the exact same config and code?? Maybe because I had the DK hooked up manually before, and sent commands via the "Bluetooth Low Energy" tool in the nrf connect. Does the bike remember the MAC address of the DK? Really weird.

Reply
  • FINALLY! I fixed it! There are still some mysteries, but it turns out that I had to subscribe to the UART Rx notify service to get this to work.

    static struct bt_gatt_subscribe_params subscribe_params;
    
    static uint8_t notify_func(struct bt_conn *conn,struct bt_gatt_subscribe_params *params, const void *data, uint16_t length)
    {
    	if (!data) {
    		printk("Ubsubscribed\n");
    		params->value_handle = 0;
    		return BT_GATT_ITER_STOP;
    	}
    
    	printk("Notification: data %p length %u\n", data, length);
    
    	return BT_GATT_ITER_CONTINUE;
    }
    
    static void write_func(struct bt_conn *conn, uint8_t conn_err,  struct bt_gatt_subscribe_params *params)
    {
    	printk("Write callback\n");
    }
    
    static void subscribe() {    
    //    subscribe_params.flags = 0x00;
    //    subscribe_params.node = 0x00;
        subscribe_params.ccc_handle = 0x3b;
        subscribe_params.notify = &notify_func;
        subscribe_params.value = BT_GATT_CCC_NOTIFY;
        subscribe_params.value_handle = 0x3a;
        subscribe_params.write  = &write_func;
        bt_gatt_subscribe(default_conn, &subscribe_params);
    }

    I figured it out by reproducing the same code on an esp32 and sniffing that traffic. It had the same problem, until I turned on the notify callback there. After that I had to puzzle a bit with how the callback could be done in the nrf connect sdk (your documentation REALLY needs more examples, most of the basic functionality is impossible to find on the internet).

    The mystery that still remains is: why does it work on the DK with the exact same config and code?? Maybe because I had the DK hooked up manually before, and sent commands via the "Bluetooth Low Energy" tool in the nrf connect. Does the bike remember the MAC address of the DK? Really weird.

Children
No Data
Related