I have a loooot of things to tell you tonight. Are you ready? Let’s go!
On Friday, Matthieu, Adèle and I spent a lot of time reading several datasheets to compare different SoCs. In the end, only the nRF51822 and the CSR101x series seemed flawless… until we discovered that the CSR101x was really difficult to get. As a result, we definitely chose the nRF51822. The timing was good, since we received our developement kits on the very same day! We also worked on the choice of other components, in particular the button cells, with Adèle spending a lot of time on Farnell. Having filled up a table of the characteristics of all components, we were able to choose. For the battery, we selected a few of them (CR2032 and CR3032, rechargeable and not rechargeable), but we still needed some information on the support availability and actual prices for big ordering.
Setting up a comfortable environment
I invested my Saturday to ensure a better productivity later: I configured my development environment. More precisely, I set up a .screenrc file which automatically opens windows in the right directory, for all the tasks I do when developing for embedded systems and runs the appropriate commands (openocd, arm-none-eabi-gdb ch.elf, git status, emacs -nw main.c, and so on) at startup, with appropriate key bindings in addition. It was a bit difficult at first to understand how to write this file, but now it is done, and I am very happy of the result! When I start my computer, all I have to do now is to plug my STM32, create (or attach) a screen… and program! It may not seem like such a big change, but I know that I was always spending much time opening, renaming and closing tabs, remembering where my openocd.cfg and .gdbinit files were, opening lots of buffers in emacs… And now I won’t have to anymore. Of course my .screenrc is specific to my directories and my habits, but I can help you setting your own environment if you want!
I also spent an important part of my weekend on my STM32 lab, and I have now working semaphores, threads and events!
Today, I worked with Matthieu and Adèle to complete today’s PSSCs: the choice of components and the BLE architecture for drops.
While Matthieu was crying in front of complex schemes of solar panel connectors and Adèle was losing hope to find a CR3032 support, I was busy searching for rechargeable batteries cheaper than button cells and for application notes about impedance matching in datasheets. However, I found neither of them. I guess that we will keep our first idea of rechargeable button cells!
Afterwards, we considered our BLE architecture. I read the SoftDevice specification and Android API documentation for BLE. Then the three of us discussed about architecture questions: what is the best granularity level, from a consumption point of view? How to ensure atomicity for read and write operations? We designed four architectures :
- A single service, very generic, with characteristics “OperationID”, “Input”, “Output”. The current operation (read, write, edit, list boxes…) is selected by the “OperationID” characteristics and the semantics of the other characteristics depends on the operation.
- A single service Message (characteristics “id” and “content”, when the client changes one value, the server updates the other one accordingly) and a service Box to select the appropriate box for current operations.
- One service per operation, and appropriate characteristics for each one of them. For instance, service Read would have characteristics BoxId (write only), MsgId (write only), MsgContent (read only). In this architecture, there can be a service Authentification, used before any other operation, typically for the treasure hunt.
- One service per operation and per box. It increases a lot the number of services, but reduces the number of characteristics by 1 per service.
The first architecture is conceptually the easiest, but probably the hardest to implement. The second one may create concurrence issues when several devices are connected. For the fourth one, the risk is to have too much services and exchange a lot of messages just to give the list of services. But in the third case, the problem is the same, except that it is moved to the level of sending the list of boxes.
There is still a problem of atomicity. With the second architecture for instance, when the client reads the message 136 and then writes the message 137, it first writes id=136 (the server updates content=foo), then reads content=foo, then writes id=137 and content=bar, but in which order? The server must wait for both characteristics to be updated or the box will be corrupted. Possible solutions are to add an extra boolean characteristics that could act as a mutex, or to require a short delay (how much?) after each update before processing.
Right now, we don’t understand BLE well enough to decide what the best architecture is. We need to start developing an Android app with BLE API to know what is easy or not to implement and how much messages it represents.
Another idea: maybe we could use characteristic descriptors (for instance the MsgId as a descriptor for MsgContent), but we are not sure yet of what changes between attributes and descriptors, concerning notifications, updates and number of messages. Are descriptors really the same as attributes, but only at a different level, with different semantics?
PHEW! That was already a lot of work for a few days. I will now spend the rest of the day working on ADC and reading documentation for Android development. Then I will rest a little, because next week will be very dense: we must finish our STM32 lab, design the PCBs, learn how to use the nRF51822 and how to develop Android apps… and develop our first app!