(Complete list of all blog entries in this series)
OK, the bad news first: no devkits from Analog have arrived yet (though Christian told me Farnell is working on them). So it looks like I won't keep my timeline for the first prototype (its less than two weeks away).
But at least I made progress on the software part of my project - namely getting first results regarding the Bluetooth connection I need.
Bluetooth 4.0 vs. Bluetooth Low Energy
Sometimes these two terms are used as they would mean the same, but they don't. Bluetooth 4.0 consists of three different protocol definitions: Bluetooth classic (the original protocol), Bluetooth High Speed (introduced with Bluetooth 2.0) and Bluetooth Low Energy. So BLE (as its abbreviated) is part of the Bluetooth 4.0 specification. That means that a BL4.0 device can handle BLE connection (as well as classical Bluetooth). But its not necessarily the other way round - a BLE device is not required to handle classical Bluetooth connection.
Where Classical Bluetooth and Bluetooth High Speed are quite similar (and differ mostly in how the physical data transfer works), BLE is completely new protocol. That means applications cannot easily be ported. Especially the serial protocol (SPP) that gets used very often is not available with BLE. The reason is that the BLE protocol is designed for extreme low power (design target was running of a coin cell), so it doesn't work with continuous connection, but with short data bursts.
Instead, BLE is designed to transfer state information. So e.g. a heart rate sensor has the current heart beat as state (its just a number), and maybe a max and min value of a given time period. It also may have an alert state when the heart rate goes over (or under) a given threshold. All these states are modeled as a set of services (e.g. 'heart beat' and 'alert'), each of which has a number of characteristics (the data sets). To access them there is a part of the protocol called GATT (the generic attribute protocol) that gives access to the services and characteristics (discover which ones are available, writing to attributes and reading their values).
GATT has the notion of a server and a client, where the GATT server is the device that provides states and attribute data, and the client is the one that reads (or writes) this data. This is not necessarily the same distinction as done between central and peripheral device - in the case of the heart rate sensor the periperal (the senor) is also the GATT server since it provides the data.
To get a somewhat more detailed overview, I can recommend the Adafruit BLE introduction. If you weant to see the details, Bluegiga has a nice introduction too.
PSoC4 BLE experiments
I'm using the PSoC4 BLE Pioneer kit (CY8CKIT-042) for development. It comes with a base board (that uses a PSoC5LP as programmer and USB-UART bridge), two BLE breakout modules (one with the PSoC4 BLE, one with the PRoC BLE) and thr CySmart BLE dongle that also has a PRoC BLE on board so it can act as central device. I already wrote a little bit about the demo program before, so I don't need to cover them again.
I used the supplied demo program to get a feeling for how the API of the BLE component is used. I cannot use any of the per-defined BLE services, since there is no profile for acceleration data yet.
So I started PSoC Creator, and created a very simple schematic with all the components that I need:
Main element is the BLE component that encapsulates all the hardware and software needed for a BVLE device. The LED pins on the right are used for signalling state to the user and will probably look different in the final version). The WDT on the left is a low-power clock source and wakes up the device once per second to handle the BLE events. The SAR ADC is used for measuring the battery voltage at regular intervals, so the sensor can create an alert if the battery goes low. The switch pin on the right wakes the device from deep sleep (which it goes to if its disconnected). Last but not least the UART component is used for debugging and redirects all printf() calls to the serial port (which in turn sends it via USB to the PC).
The BLE component contains the configuration of all the provided services and their characteristics:
I defined a custom service 'AccelHistory', with three different characteristics. The accel.rrd data contains the time series of acceleration, the accel.log stores data when too high acceleration values are measured, and accel.current returns the current acceleration. I use the latter one for experiments, since its easier to mock that time series data. In the final version its probably not available anymore.
You may notice other services here as well - I did utilize standard services to provide additional functionality. Immediate alert can provide push notifications to connected phones, and the Alert notification proves just a notification (like an incoming short message). Battery provides the battery voltage level, and Device information some meta data about the device (name, software and firmware versions and so on). I will experiment with them and see how useful they are in practice.
My current focus is around the current acceleration, since its rather easy to fake and allows immediate feedback. I wrote a small value simulation, using a 16-bit integer that just gets counted up with each timer tick (completely unrealistic, but simple to implement and I can be sure it changes all the time). Using the demo programs I came up with all the code I needed to write so a client can read the current acceleration value, and gets notified about changes to it. Many thanks go to the Cypress Developer community that provided some valuable help.
When using the CySmart tool to connect with by PSoC4 BLE module, this is how it looks like:
Each service and each characteristic gets its own UUID, and CySmart show only this (and not the name as its defined on the component configuration. To get the name, a client would need to read the 'Characteristic User Description' field of the characteristic.
One can see in the image that the value directly underneath the 'Characteristic Declaration' is marked in blue - that because it got changed by a notification. The log window at the bottom also shows which attribute (0x0019) got changed. To disable the notification, the client needs to change the 'Client Characteristic Configuration' - I have already set 0x00 as value and just need to send it to the device.
Data transfer
I'm not sure about the best way for transferring the time series data between device and phone. BLE-wise the preferred way would be to just write into the associated characteristics every time they change, and let the phone just read it from there. But since the MTU for packages are limited, so is the data size for the characteristics. That means it seems sensible to split the data up, and define a protocol to do so. (I found references that the maximum payload is 20 bytes, but my RRD config is as an array of 180 bytes, and the CySmart application reads it without problems. So I need to investigate that a little bit)
Next steps
While I'm still waiting for the hardware to arrive, I will further investigate the data transfer. I also will start on the real phone software, but there I need to start with the discovery and connection part first.