NRF 51 BLE library for custom services

nrf51 ble stack
nrf51 ble stack

After building my first project using an nRF51 device from the template given in the SDK I was really disappointed by the result, I mean, it works but the code is really bad and hard to maintain.

The given examples are not really generic and if you have to create your custom ble service and characteristics you have  to make many modification in a code that is not clean for all.

So my second project was to create a ble library to make creation of custom services & characteristics as easy as possible and to create a main file with less code.

That is the purpose of my ble_dsk library you can found on bitbucket following this link about a library to quickly create ble services.

This library creates custom bluetooth low energy services and its attached characteristics. It can be instantiated to create multiple services. Services can have misc read/write/notify characteristics of any object size.

To use it you just need to create a structure for describing services & characteristics then call for the init. Your interaction will then be made over callback functions. You can also manually push updates.

You can also add standard ble services like Battery, Device Information, UART and DFU services are not yet implemented but part of the next evolutions.

The library is in version 1,0 and will evolve based on my future needs. Don’t hesitate to request for evolution and to propose some pull requests.

The way to use it is to declare the service & characteristics you need like in the example :

const ble_dsk_peripherical_t myPeriph = {
    /* Peripherical name */                         "disk91Ble",
    /* add_mac_address after name */                false,
    /* Manufacturer name */                         "disk91.com",
    /* Appearance type */                           BLE_APPEARANCE_UNKNOWN,
    /* Basic Service to enable */                   BLE_DSK_SERVICE_BAS | BLE_DSK_SERVICE_DIS,
    /* UUID are 128b format */                      false,
    /* 128b uuid to be used */                      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    /* Configuration bitfield */                    BLE_DSK_CONFIG_SERVICE_CHANGE_CHAR,

    /* Advertising mode */                          (BLE_DSK_ADV_MODE_SLOW | BLE_DSK_ADV_MODE_FAST),
    /* Advertising fast interval ms */              200,
    /* Advertising fast timeout in s */             20,     // 20 seconds
    /* Advertising slow interval ms */              600,
    /* Advertising slow timeout in s */             0,      // never ends
    /* Advertizing callback */                      onAdvertizingChanged,
    /* Advertizing callback stop */                 onAdvertizingChanged,

    /* Security options */                          BLE_DSK_SEC_DEFAULT_OPTIONS,            // Bonding + MITM
    /* Security io capability */                    BLE_DSK_SEC_DEFAULT_IOCAPA,             // None
    /* Security oob data */                         BLE_DSK_SEC_DEFAULT_OOBDATA,            // 0
    /* Security min key size */                     BLE_DSK_SEC_DEFAULT_MINKEYSZ,           // 7
    /* Security max key size */                     BLE_DSK_SEC_DEFAULT_MAXKEYSZ,           // 16

    /* GAP min cnx interval */                      BLE_DSK_GAP_DEFAULT_MINCNX,             // 100ms
    /* GAP max cnx interval */                      BLE_DSK_GAP_DEFAULT_MAXCNX,             // 200ms
    /* GAP slave latency */                         BLE_DSK_GAP_DEFAULT_SLAVLAT,            // 0
    /* GAP cnx Supervision timeout */               BLE_DSK_GAP_DEFAULT_CNXSUPTM,           // 4s

    /* CNX time for update on connect*/             BLE_DSK_CNX_DEFAULT_CNX_TIME,           // 5s
    /* CNX update time */                           BLE_DSK_CNX_DEFAULT_CNX_UPDATE,         // 30s
    /* CNX attempts */                              BLE_DSK_CNX_DEFAULT_CNX_TRY,            // 3
    /* CNX disconnect on fail */                    BLE_DSK_CNX_DEFAULT_DISC_ON_FAIL,   // false

    /* Battery level function */                    getBatteryLevel,

    /* Number of custom services */                 1,  
    /* Link to custom services desc */              myServices
};

Periph contains all the common parameters for the BLE stack. It also allow to start standard services like BAS (battery status) and DIS (device information).

It has a link to the service structure to describe your custom service and characteristics like in the following example. The bitbucket repository have a larger example with 2 services and 3 characteristics.

const ble_dsk_service_desc_t myServices[1] = {
{
    /* Service UUID */                          0x1900,
    /* Service Description */                   "testSrv",
    /* onConnect callback */                    onConnectTestSrv,
    /* onDisconnect callback */                 onDisconnectTestSrv,
    /* Number of characteristics */ 1,
    /* Characteristics */                     { 
    {
         /* Description */                              "testChar1",
         /* Characteristic UUID */                      0x2B01,
         /* Characteristic access right */              (BLE_DSK_ACC_READ | BLE_DSK_ACC_NOTIFY),
         /* Char Data len   */                          2,
         /* Char Data initial value */                  {0x00,0x01},
         /* Char onWrite callback   */                  NULL,
         /* Char onRead callback */                     onReadTestChar1             // set not NULL will request ReadWrite Auth
    }
    }
}
};

All these structure are constant to be stored in flash and preserve RAM. Size of the different elements can be tuned in one of the header files to preserve flash & code size.

Once all of this created, you just need to call the init function and create the characteristics associated callbacks to manage the input & output.

int main(void) {
    // Initialize timer module.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, 4, false);

    // Init the ble structure
    ble_dsk_peripherical_init(&myPeriph);

    for (;;) {
    sd_app_evt_wait();
  }
}

Main don’t need more than what you see above. Call back can be set to be called on every read or write actions ; asynchronous updates & notify is also supported

bool onReadTestChar1(uint8_t * data_buf) {
    uint16_t * _v = (uint16_t *) data_buf;
    *_v = (*_v+1);
    return true;
}
void onWriteTestChar2(uint8_t * v) {}

This library is GPL based, so do not hesitate to try & play with it. If you are looking for another license, you can contact me and we can find the best agreement to integrate it in your project.

The purpose of this BLE library for nRF51 and nRF52 is to get start in 10 minutes with custom ble services for the IoT.

This entry was posted in Hardware and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *