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

  • Hi Jouke, 
    Please correct me if I'm wrong. 
    What you are trying to do is to interface with a 3rd party device (the bike). Your device is the central in the connection. 

    When you test, either with the phone or with a DK as the central, the bike react properly to the commands. But with the bc805m as central, the bike didn't react accordingly ? 
    I would suggest to capture the sniffer trace of the DK when you do the exact same thing then it's easier to track down what would be wrong. 
    I suspect something wrong with the timing or related to that. I don't know if the bike has some special treatment for the command to handle 0x38 or not. 

  • Hi Hung,

    That would be ideal, but I only have one DK and can't use it to transmit and sniff at the same time :) I will try a couple of other things.

    Thanks nevertheless!

  • 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.

Related