Whilst on lockdown outdoor exercise (on the road and outside of your house) was not allowed. So focus turned to internal options. Through a bit of mix and matching some parts from the storeroom I managed to get an old 1980's bike connected up to an indoor trainer.
The only issue with both of these parts was that there were totally unconnected (didn't offer any speed / distance measurement options). Normally sensors are around $40 but I thought that something I might have in my electronics store might do the job for me....
The new-ish Particle boards, including the Argon have BLE incorporated into them, and so I got thinking. If the Argon can also pretend it is a BLE sensor then perhaps it could emulate a Cycling Speed and Cadence Sensor (official name in the GATT service list). All it would take would be some code, correct uuIDs and a reed switch to count the passing magnet... easy enough?
Initially I must admit some trepidation with regards to getting stuck into BLE. I've only ever used an Argon for BLE Central mode work before, and that was relatively straightforward (scan, find the MAC address / name of the device you want and then receive information; see previous project of mine on Thunderboard Sense connections).
Using an Argon in a BLE Peripheral (see below for basic structure) might be a minefield of programming (think advertising, characteristics, services, packaged data streams and correct units), however the defined standards, and various BLE device manufacturers (Nordic, etc.) have some great documentation on how this all works.
After 3 days of coding and testing (initially with a push button instead of the reed switch and magnet) I managed to finally go for a ride last night. The sensor connected to my watch (Suunto 9) and popped up as a BLE Bike POD sensor. The ride measurements matched exactly to an old-school speed sensor on the bike (calculations worked!) and I was able to track distance and speed throughout the 1 hour exercise routine.
I do still have a few things to polish in the code, namely;
- getting the cadence part to also work (I have a single speed bike and so the rear wheel revolutions will determine the front crank revolutions)
- perhaps implementing some lower power options where the device turns off after some time of inactivity.
- getting the advertised name to emulate a well known brand (although I thought this was required by the BLE Central device it turns out it is not, it only checks for the Charateristic UUid).
- putting it all in a neater package!
Thanks do go out to a few people's Github repositories, for some code guidance.
Further resources worth understanding:
GATT Characteristics (Generic Attribute Profile) - these are globally defined and standardised for use in implementing a variety of BLE sensors, etc.
GATT Services - "collections of characteristics and relationships to other services that encapsulate the behavior of part of a device." - also useful to understand how the services fit into the profile which is advertised.
Specific CSC profiling / packet structure and flags - an XML page with details on the specific measurements, units and flags. This is getting closer to actually working out what data do we need to send to the BLE Central device.