Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE Writable Variables

I have a working application based on one of the examples in the dev kit. It was quite a struggle, and shouldn't be that hard. I would have expected simply a table of variables to expose on BLE, along with attributes such as size and preferred display format (most of which would already be covered by the various groups of UUIDs in the BLE spec), and pointers to a function to call when the variable is read or written. That said, I've slogged my way thru the examples and the official BLE specs, and have an application running nicely, wherein a variable is read from hardware and the value periodically updated on the nRF Connect display.

Now I need to add a variable that can be written via nRF Connect, a simple integer value. I am attempting to use the BLE defined Analog I/O type, and running into no end of strange compiler warnings as I try to build a scaffolding to match that very shaky conglomeration in the BLE example in the dev kit. I think I have everything in place that I need, except that I can't get the event handler hooked up for a write to the variable. Can anyone point me to an example in one of the provided examples that would give me some guidance? I have looked extensively and all I find is examples going in the other direction - reading values from the nRF52 via BLE to display on nRF Connect.

Help?!?

  • The ble_app_blinky example could maybe be helpful. In that example you could write 0 or 1 in nRFConnct on the LED Characteristic (0x1525) to turn the LED off/on.

  • Okay, thanks. I'll have another look at that. I had tried using that but got lost in that unwieldy chain of calls stacked into calls and structs stacked on structs.

  • I have been chasing my tail and burning up my client's billable hours for a couple weeks now on this. Is it really too much to ask that there be a simple example of a characteristic that allows me to write a value from a phone into my app and have it call a routine? Based on more decades of embedded development than I really want to admit, there should be a simple table for BLE, with a line for each variable of interest, containing a pointer to an internal variable, the size of that variable, formatting information, flags to allow read or write, and pointers to one or both functions to be called before the value is read and after it is written. I have struggled with the CGMS example and have it displaying a value from my analog hardware in real time, but it was way more of a struggle than it should have been. Could someone PLEASE point me to some example code that actually works, and containing a simple example that I can lift into my code, that will allow me to write a variable from BLE?

  • I now have my example working based on Blinky, and it's much cleaner than being based on CGMS even though the latter is closer to what I'm ultimately trying to accomplish. I have changed the value being reported for a button press to reflect the value I need to report, and have even succeeded at making it a 2-byte value instead of one byte as in the Blinky example code. So far so good. But I need to have the number treated as a 16-bit SFloat type, and displayed accordingly. Here's how I've modified the relevant section of button_char_add to change the type and units, but thus far it's completely ignored.

        char_md.char_props.read   = 1;
        char_md.char_props.notify = 1;
        char_md.p_char_user_desc  = (uint8_t *) "Glucose";
        char_md.char_user_desc_max_size = 12;
        char_md.char_user_desc_size = 7;
        char_pf.format = 0x16;   // 16-bit SFLOAT
        char_pf.unit   = 0x27B1; // units of mG per dL
        char_md.p_char_pf         = &char_pf;
        char_md.p_user_desc_md    = NULL;
        char_md.p_cccd_md         = &cccd_md;
        char_md.p_sccd_md         = NULL;

        ble_uuid.type = BLE_UUID_TYPE_BLE; //FIXME p_lbs->uuid_type;
        ble_uuid.uuid = BLE_UUID_CGM_MEASUREMENT;

    Also, what's the best way to ensure that all the previously-captured configuration information that shows up in nRF Connect is actually refreshed from my code? I've been tripped up several times by nRF Connect continuing to use old values after I change my code. I'm not sure exactly what steps to take.

Related