I used a small off the shelf microcontroller to connect to standard bike computers using ANT+ and then read information from a 24Ghz mmwave sensor to determine the relative position of 2 riders from eachother. This was all in an attempt to help new riders learn how to draft and aid in keeping them in your draft if you are leading.
Primary Language : Arduino C
Microcontroller: Seeed Studio XIAO-nRF52840
Sensors: Seeed Studio XIAO 24Ghz mmwave human static presence sensor
Communication Protocols: ANT+
Programmer: ST-LINK V2
Ive recently gotten really into Road biking/racing, and as such have also convinced my wife to join me on longer rides. One important feature of road racing is drafting. By riding very close to the person in front of you, the wind is significantly reduced allowing you to use almost half as much power (watts) while going the same speed as the person in front of you. While getting into someone's draft, and staying there isn't as much of an issue for myself, its more of a challenge for my wife. She will draft for a little while behind me, but slowly fall off without me realizing until she is no longer getting the benefit of the draft.
To solve this, I wanted some way to determine how far behind (or in front of if mounted on the front of the bike) someone was. There are several commercial bike radars on the market, however most of them function with the same underlying technology, Doppler radars. While this is great for their intended use case of detecting cars behind, it only really functions when there is a noticeable speed difference between the biker and the object. Instead of Doppler radars, we can use mmwave sensors. These sensors function at very high frequencies to give very accurate positioning data of specifically humans or living things, at least that's the theory. Supposedly these chips are so accurate that if you get a 50-60Ghz mmwave sensor, you can even detect someone's heartbeat from a distance due to the expansion of their skin due to the heart beating (May be a future project Idea here).
For the first prototype of my radar, I ordered 3 parts, a 2000mAh 3.7v Lipo battery, seeed studio's XIAO-nRF52840 module (IE, the microcontroller), and the seeed studio's human static presence mmwave sensor module (IE, the mmwave). The cool thing about this project is how simple it sounds on the surface. Seeed studio built the mmwave as a hat/shield for the microcontroller so without much effort you can connect the two. Additionally, the microcontroller itself has USB-C for power and charging, has a built in lipo charging circuit, and most importantly has a chip that supports both BLE and ANT+.
The bike computers instead of using BLE, use a custom proprietary protocol called ANT+. While the radio is the same for both BLE and ANT+, the protocol is different, ANT+ is essentially the multicast version of BLE. A device will advertise its data, and any number of devices in range can subscribe to it. Luckily for me, this should all be handled by the radio itself, and I only need to format the data correctly. However the firmware that is shipped with the seeed microcontroller only supports BLE, so the first thing I will need to do, after of course programming a basic test, is flashing the firmware that switches the radio into ANT+ mode.
I'll be honest here, this project makes heavy use of AI, specifically at this point I am using Gemini Pro. To create a test image, it was quite simple using AI, I was able to create a single prompt that stated the board, how its connected, and indicate that I would like to program it via the command line using makefiles and linux. With this information the AI was able to build me a basic toolchain for building, flashing, and monitoring the serial bus. This means I don't need to deal with arduino IDE and I can just us VScode as I am used to. The initial test program simply flashed the RGB LED on the board different colors. This worked without much hiccups and was quite pain free as far as engineering projects go. Also I originally thought I would need a serial programmer, however this chip allowed me to program it via USB-C. I think this is also possible for flashing the ANT+ firmware, but thats a future issue.
Oooooooweeeeee. Pain free this is not. The ANT+ protocol is owned by Garmin, in order to use said protocol you have to first create an account on the thisisant website. Following the creation of an account, Garmin or thisisant needs to hand verify you, its not automated.
This is to get the nordic semiconductors s340 firmware that supports ANT+ and BLE on the same radio at the same time.
Note at the moment, I am waiting on this verification so could not get ANT+ working.
This was supprisingly simple using BLE instead. Most bike computers support BLE for some sensors but not all. Other sensors need ANT+.
Initially I wanted to spoof Heartreat, Speed, and Cadence. Again making heavy use of AI for this, I simply asked it to spoof all th sensors so that I can pair from my bike computer and see the values increment in set increments. Gemini was able to handle this with ease. The chip alone was able to connect and display the values. There was only a minor bug with the units showing up in the sensor values but otherwise it was fairly pain free.
I plan on attaching a Lipo battery to this project, so I need a way to put the chip into low power mode and stop all the internal high frequency clocks. Luckily for me the chip itself comes with this feature. I again made use of Gemini to configure the chip such that a button on pin 0 to ground shuts the board down and puts everything into low power mode. I still need to do some power checking to make sure its not draining, but at the very least it stops UART and kills LEDs. Then upon pressing the button again, it turns back on and reconnects everything. The final low power update I made was to disable the bluetooth connection that the mmwave board had. For some reason it has its own bluetooth chip so you need to send extra UART commands to disable it. Since I am hardwired to the mmwave chip, there is no need for its bluetooth.
This was the scariest part of the project so far. I hate soldering lipos. They are scary and if you mess up you could at best case arc the batteries and at worst case start a near uncontrollable fire. Luckily for me it went smoothy I used some kapton tape to isolate one terminal of the battery at a time, and went very slowly to make sure I didn't arc anything.
After the battery was in place, I added a button for shutdown, and the headers on the microcontroller as well as the mmwave sensor so they could connect to eachother.
This was a bit more of a pain than I was expecting. Gemini could not figure out the specification and needed to be coached much more indepth than anything so far. I had to explain the protocol and point it to specific sections of the specification. For a while it was dumping unreadable HEX and using the wrong baud rate. Once I got these corrected, and generated a parser, I was able to get useful data that seemed to work correctly. I was able to get distance readings from the sensor that were mostly accurate. Accuracy tests are needed, but I don't have space in my appartment for them at the moment.
There are also several other values and configurations this sensor can use, so I will need to experiment at some point, but that will be at a later time.
At this point I have a full system, My device detects distances, has a microcontroller with charging circuit and battery, and a power button. It also satisfies the requirement of sending data to my bike computer. It is really cool and refreshing to see a project come together so smoothly. Honestly this took less than 2 days to go from parts to working system. There will likely be additional improvements I add, however for now the hardware will likely stay the same. Notification LEDs for following distance, breaking, and battery levels may be added in the future, but at the moment are not added.
WIP
WIP
WIP