Thursday, 12 March 2015

The Bluegiga DKBLE development kit

Introduction
I was given a Bluegiga DKBLE development board by Bluegiga and have recently been using it in support of some work I'm doing. I hadn't used a Bluegiga board before and so had to learn how to use it and I thought I could share my experience and the things I learned here.

The Kit
The kit consists of a main DKBLE board and several "carrier boards" which can be plugged into the main board. These are small boards containing a particular Bluegiga module. There are 4 in total; 1 x BLE112-A, 1 x BLE113-A, 1 x BLE113A-M256K and 1 x BLE121LR-A-M256. The latter is Bluegiga's long range module which their web site says has a range of up to 450 metres. Pretty impressive.








The main board has pins at one edge which allow one carrier board to be plugged into it. It also includes an LCD display, a temperature sensor, an accelerometer, an altimeter, a potentiometer and a USB to UART converter.










Project Configuration
A Bluegiga project consists of a number of different files, one of which is the project configuration file. It has an extension of ".bgproj" and defines the target hardware and the names of other key project files, such as the name of the XML file which defines the GATT services, the name of the hardware definition file, the name of the primary bgscript file and the name of the output image file to be created by the compiler.

 <?xml version="1.0" encoding="UTF-8" ?>  
 <project>  
   <gatt in="gatt.xml" />  
   <hardware in="hardware.xml" />    
   <script in="course_project.bgs" />  
   <image out="out-ble113.hex" />   
   <device type="ble113" />  
      <boot fw="bootuart" />  
 </project>  
myproject.bgproj

Defining GATT Services
This is a straightforward task and similar to other boards I've worked with from Nordic Semiconductor and CSR for example, in that it involves using XML to describe services, characteristics and descriptors in a logical, intuitive way. There's no GUI to help with this so your tool is your favourite text editor. There are lots of examples that come with the SDK so it's easy to get started.

I had a custom profile I wanted to implement which included 4 services. The first was an adopted service called the Battery Service. The other three were all custom services; the counter service and random number service are those I used for my Texas Instruments SensorTag hacking and the Personal Naming service was a new one I came up with which allows you to give a custom name to your device. Yes, a "pet name" is what I had in mind :-)

 <?xml version="1.0" encoding="UTF-8" ?>  
 <configuration>  
   <service uuid="1800">  
    <description>Generic Access Profile</description>  
    <characteristic uuid="2a00">  
     <properties read="true" const="true" />  
     <value>Innovation Series Device</value>  
    </characteristic>  
    <!-- APPEARANCE = unknown -->  
    <characteristic uuid="2a01">  
     <properties read="true" const="true" />  
     <value type="hex">0000</value>  
    </characteristic>  
   </service>  
       <!-- Battery Service -->  
       <service uuid="180f">  
     <description>Battery</description>  
     <characteristic uuid="2a19" id="xgatt_battery">  
       <properties read="true" />  
       <value length="1" type="user" />  
     </characteristic>  
   </service>  
   <!-- Counter Service -->  
   <service uuid="3E099914-293F-11E4-93BD-AFD0FE6D1DFD" advertise="true">  
     <description>Counter</description>  
     <!-- Counter -->  
     <characteristic uuid="3E099915-293F-11E4-93BD-AFD0FE6D1DFD" id="xgatt_counter">  
      <properties read="true" write="true"/>  
      <value length="1" type="user" />  
     </characteristic>  
   </service>  
   <!-- Random Number Service -->  
   <service uuid="3E099916-293F-11E4-93BD-AFD0FE6D1DFD" advertise="true">  
     <description>Counter</description>  
     <!-- Random Number -->  
     <characteristic uuid="3E099917-293F-11E4-93BD-AFD0FE6D1DFD" id="xgatt_random">  
      <properties read="true" notify="true"/>  
      <value length="2" type="user" />  
     </characteristic>  
   </service>  
   <!-- Personal Naming Service -->  
   <service uuid="3E099918-293F-11E4-93BD-AFD0FE6D1DFD" advertise="true">  
     <description>Counter</description>  
     <!-- Personal Name -->  
     <characteristic uuid="3E099919-293F-11E4-93BD-AFD0FE6D1DFD" id="xgatt_personal_name">  
      <properties read="true" write="true"/>  
      <value variable_length="true" length="20"/>  
     </characteristic>  
   </service>  
 </configuration>  
gatt.xml

The id attribute defines a name for the GATT attribute which can be used to reference it from code. The file attributes.txt maps these ID values to GATT handle values.

 xgatt_battery 8  
 xgatt_counter 11  
 xgatt_random 14  
 xgatt_personal_name 18  
attributes.txt

Developing for the Bluegiga DKBLE
The first thing that strikes you as different when it comes to developing for this board is the programming language. Their API does allow C to be used but in addition, Bluegiga have their own scripting language called bgscript. I liked working with bgscript. It's reminiscent of the BASIC programming language, the first language I ever learned, over 30 years ago! It's pretty quick to develop with as well.

Coding for Bluegiga involves implementing event handlers which receive call backs from the system, generating events by making API calls and writing and calling your own custom procedures, which are like functions which cannot return a result (i.e. they're similar to functions which have a return type of void). When you call a system API, you generally (perhaps always) receive a call back once your event has been handled, so there's a symmetrical request/response pattern working with the event system.

If all you want to do is expose simple characteristics whose values can be read or written to, you don't need to do much coding. The characteristic values lives in the device's attribute table and the framework gives access to it without you having to write any bgscript. If reading or writing to a characteristic requires more processing than this though, then you must implement code inside the appropriate event handler. This was the case for my counter service. Reading from the counter value characteristic required the value to be incremented before returning it to the GATT client. As such, I had to mark the characteristic as having a type of "user" in the gatt.xml file.

   <!-- Counter Service -->  
   <service uuid="3E099914-293F-11E4-93BD-AFD0FE6D1DFD" advertise="true">  
     <description>Counter</description>  
     <!-- Counter -->  
     <characteristic uuid="3E099915-293F-11E4-93BD-AFD0FE6D1DFD" id="xgatt_counter">  
      <properties read="true" write="true"/>  
      <value length="1" type="user" />  
     </characteristic>  
   </service>  

Requests to read characteristics of type user result in system calls to the event handler called attributes_user_read_request. A simplified version of my implementation appears next:

 # Listen for GATT read events  
 event attributes_user_read_request(connection, handle, offset, maxsize)  
     
   if handle = xgatt_counter then  
    call attributes_user_read_response(connection, 0, 1, counter)  
    counter = counter + 1  
    if counter > 255  
      counter = 0  
    end if  
    return  
   end if  
   
   if handle = xgatt_random then  
    # swap from little endian (Bluegiga internal format) to big endian for GATT  
    random_be(0:1) = random(1:1)  
    random_be(1:1) = random(0:1)  
    call attributes_user_read_response(connection, 0, 2, random_be(0:2))  
    return  
   end if  
   
   if handle = xgatt_battery then  
                batconn_handle=connection  
                #start measurement, read VDD/3, 9 effective bits   
                call hardware_adc_read(15,3,0)  
    return  
   end if  
     
 end  
   

Note that bgscript supports simple variables and types of variable known as buffers. These are essentially byte arrays and they're addressed using name(start:length) notation.

After dealing with a simple read request, you call attributes_user_read_response which causes the attribute protocol response to be returned to the client.

In the case of the Battery Service, this requires interaction with the hardware APIs and in this case a call to hardware_adc_read. This in turn, causes a callback to an event handler called hardware_adc_result once the operation has completed. My full source code appears below.

The Random Number service generates a 16 bit random number when its characteristic is read and generates and returns a random number once every second as a GATT notification whenever notifications are enabled. The bgscript has no random number function so I coded my own implementation of a simple Linear Congruential Generator algorithm, which is the basis of the random number function in a lot of programming languages. See http://en.wikipedia.org/wiki/Linear_congruential_generator .

 # Random number generation  
 export dim rseed(4)  
 export dim m  
 export dim a  
 export dim c  
 dim x  
 dim r  
 dim mod_result  
   
 procedure mod(number, divisor)   
   
  x = number / divisor  
  mod_result = (number - (x * divisor))  
   
 end  
   
 procedure genRandom()  
   
  # Xn+1 = (aXn + c) mod m  
    
  r = (a * rseed(0:4) + c)  
  call mod(r,m)  
  rseed(0:4) = mod_result  
    
 end  

To seed the random number sequence I used a temperature reading from the board's temperature sensor.

I used a timer to generate a fresh random number each second and write it to the GATT attribute table. If the client had enabled notifications then the framework automatically generated a notification message with the new value in it. I didn't have to explicitly code this which I rather liked.

 event hardware_soft_timer(handle)  
     
   call genRandom()  
     
   random(0:2) = rseed(0:2)  
   # swap from little endian (Bluegiga internal format) to big endian for GATT  
   random_be(0:1) = random(1:1)  
   random_be(1:1) = random(0:1)  
   
   # update characteristic value (will push data if client has subscribed to notifications/indications)  
   call attributes_write(xgatt_random, 0, 2, random_be(0:2))  
     
 end  


The only thing I didn't like about the Bluegiga SDK was how difficult it seemed to be to use the LCD display. The LCD is really useful and I had it displaying the random numbers my timer was generating once per second and displaying a visual acknowledgement of GATT operations such as read requests. This was very useful and reassuring to see during development. But the API is really low level and I can't help but wish a set of higher level wrapper functions had been made available to bgscript to make this easier. A minor point given how great the kit is in every other way.

I have a simple Android client application which I used with the board. It shows the random number service working very nicely!




My full project can be downloaded from here, possible/probably bugs and all. This is yours for educational purposes. No responsibility is accepted for anything you find to be wrong :-)

Droidcon Tunisia

I just got back from my very favourite event of the year so far. That event was Droidcon Tunisia which was held in the beach resort of Hammamet, an hour from Tunis! It was my first time in Tunisia and in fact my first time in Africa so this made the trip all the more exciting. Of the event itself, I really wasn't sure what to expect but it turned out to be excellent.

I had the keynote and talked about the major technological developments of the last three decades, highlighting IoT as the most significant development of our time, one which historians will write about in years to come. IoT is unquestionably the biggest opportunity that developers of all sorts have had in a long time and certainly the biggest opportunity mobile developers have had since the smartphone was invented. Naturally, this being Droidcon I also "got technical" and showed the audience how the Android APIs can be used to create applications which exploit Bluetooth Smart, the killer enabler of IoT.

The audience were wonderful. The room was wonderful. Attendees were mostly university students and there was over 700 in total with standing room only during the keynote.


I also had the honour of meeting Tunisia's Minister of Communication Technologies and Digital Economy, Mr Noomane Fehri and enjoyed watching his rather inspiring opening speech. There's a good deal of positive patriotism and national pride in Tunisia which given recent history is not surprising. There's an optimism too and a determination to succeed, and Mr Fehri's speech exemplified this. I met some *really* bright young people at the event so there's every reason to believe Tunisia has an equally bright future.

The Droidcon franchise is well supported by an informal group of respected speakers and I had the pleasure to meet some impressive and very likeable people from amongst the speakers. I expect to meet some of them again, beginning with Droidcon Italy next month.

It wasn't all work either. I had the opportunity to see Carthage and to wander around a Medina in old Tunis and drink lots of delicious mint tea :-)


And I also managed to take a short walk to the beach about 100 metres from the venue and marvelled at the highly obedient... possibly not completely real.... cats in the trees inside the venue :-)


That's it! Hopefully I'll be lucky enough to be invited back next year. I hope so.