A GPS tracker for ultra-endurance cyclists

[Preserving this write-up I submitted as an entry in an electronic design competition].

Cycle Tourist

Ultra-endurance cycling events are becoming more and more popular. Events such as the Transcontinental Race (4,000km, unsupported, from Belgium to Turkey or Greece) require cyclists to ride for upwards of 16 hours a day, often catching just a few hours sleep, bivvying at the roadside to avoid wasting time on hotel checkins. Some events, such as the Audax UK “Lumpy End-to-End”, 1,800km in 8 days, require validation by GPS track. Opportunities for charging battery-powered devices are few and far between. While most participants use a dedicated consumer GPS device, or mobile phone, for navigation and capture of their track, there is a serious risk that batteries fail en route. It would be devastating to complete such an event, but not to capture the relevant GPS validation track. The purpose of my device is to provide a very low-power, simple GPS tracker, that can run unattended for days at a time on a single battery charge. It could be used as either the primary, or a backup, GPS tracker for ultra-endurance races.

Requirements

Key requirements for such a device include:

  • Low-power. Rechargeable battery powered with ability to run for several days without a charge.
  • Weather-proof. There is a high probability of heavy rain at some point on such a long event. The device must exclude water.
  • High data storage capacity. Each GPS track point requires 32 bytes, in a suitable binary format. The device must record a point at least every 5 seconds for validation. Hence the device must be capable of storing more than 0.5MB per day in non-volatile storage.

Selection of components

  • ESP32. This microcontroller has many advantages which contribute to delivering the requirements outlined above. Low-power: The device can operate in deep sleep mode, consuming 10 µA, for much of the time e.g. for 4.5 seconds in every 5 second sample period. While collecting track points from the GPS device, the device is powered-up, but WiFi and Bluetooth are not required, so the radios can be disabled. Miniature. Even in a development board format (in this case the ESP32-PICO-KIT board), the device is small enough to be housed in a compact, lightweight enclosure that can be carried unobtrusively by the cyclist. WiFi. The device operates standalone while collecting GPS tracks, but at the end of event, we need to retrieve the saved track. This can easily be achieved by activating WiFi and a simple web server, allowing the GPS file to be downloaded. Touch-sensors. By using touch sensors as switches, e.g. to switch between tracking and track-retrieval mode, we avoid the need to open up physical ports on the enclosure, thus minimising opportunities for water ingress.
  • U-blox MAX-8C GPS. U-blox GPS devices are cheap and easy to obtain. They provide support for text-based NMEA protocol, as well as proprietary UBX binary format. However, many of the development boards are not designed with low-power in mind. MAX-8C is inherently low-power, and can be built into a low-power board such as this one from Uputronics. Typical current during GPS acquisition is 18mA, but low-power modes provide potential for this to drop to around 4mA post-acquisition and during tracking.
  • Winbond W25Q256FVFG External SPI Flash. The ESP32-PICO-KIT provides 4MB of flash memory, but much of this is consumed with firmware and program storage, leaving no more than 2MB available for storing GPS trackpoints. Given our aspiration to record a track for many days at a consumption rate of 0.5MB per day, I identified the need to interface to a further external SPI flash chip. The Winbond W25Q256FVFG provides 32MB of additional flash, which will support 60 days of GPS track recording.
  • LiFePO4 battery. All the above components run at a standard Vcc of 3.3V, therefore – with a suitable voltage regulator – many options of battery format are possible, including LiPo (3.7V – 4.2V), Alkaline, NiMH. LiFePO4 batteries are an attractive option, because the nominal voltage is 3.2V, and the discharge curve is very flat, dropping below 3.0V only after releasing around 95% of its total capacity. This means that 3.3V devices can be reliably powered without a voltage regulator, avoiding the associated inefficiencies. A drawback is that these batteries are heavier and more bulky than LiPo batteries of comparable capacity.
  • TP5000 LiFePO4 charging module. The LiFePO4 battery, which is sealed inside the enclosure, can be charged with 5V from a typical USB charger, via an internal TP5000 charging module. To prevent water ingress, a 5V DC jack with rubber seal is used in preference to a mini- or micro-USB connector.
  • Touch-pad hardware. Touch-pads are implemented with a metallic disc attached on the inside of the enclosure. A steel washer has been used successfully. Further work is required to evaluate alternatives e.g. a copper rivet, for sensitivity and precision.

Design approach

Software is developed in C/C++ using ESP-IDF development framework. Tasks within the framework include:

  • GPS. Initialise the GPS device with the sample rate and protocol messages required. GPS location acquisition can be accelerated by using AssistNow Offline (u-blox), meaning that GPS information (ephemeris and almanac) can be downloaded from an Internet site over WiFi for 35 days into the future. Then, when the device is powered-on, the relevant day’s offline data is downloaded to the GPS device. This speeds up acquisition from 30 seconds to around 5 seconds. Once GPS location has been acquired, the GPS device sends a trackpoint via UART to the ESP32 host once every 5 seconds. A binary message, UBX-NAV-PVT, is used, because it encodes the location data in a relatively compact binary format. The received UART data wakes the ESP32, which, with minimal processing, writes the location data in the same binary format, via SPI, to external flash. The ESP32 can then return to deep sleep. This 5 second cycle will repeat indefinitely for as long as the device is in track-recording mode. A simple file system is implemented on the flash (esp32_fatflash by Illucius) to allow tracks to be associated as files, and so that they can be deleted by the user, and the storage occupied by that track can be made available for reuse.
  • Touch-pad. A second ESP-IDF task monitors for touch pad events. A long-press on a touch pad triggers a software event, which switches the device to “track-retrieval mode”. This activates WiFi and a simple web server. This will normally only occur when the ride is over; the device may be powered with external 5V supply at this time, and the additional power consumption will not be a problem.
  • WiFi / Web server. A third ESP-IDF task, triggered to be created in “track-retrieval mode”, WiFi will activate (could be either as a station on a pre-configured SSID, or as an AP providing a new, temporary SSID). A web server will be started, offering, via a browser page, a list of GPS tracks available for download. Each will be identified according to its start time, which is readily discoverable by decoding the first trackpoints of the binary trackpoint data stored in external flash. When the web client selects a track to download, the web server will decode trackpoints read from external flash, on-the-fly, converting them into the industry-standard GPX file format. The web server will also provide the ability to delete selected files, which will result in an entry being deleted from the list of tracks held in flash, and the flash pages used by that track being returned to a free page pool.

Development status

The hardware elements have been acquired and integrated on breadboard. Each of the main capabilities has been prototyped in software and demonstrated individually, i.e. ESP32-GPS integration, ESP32-external flash (both direct page read/write and via FAT), WiFi and web server, LiFePO4 battery operation and charging, touch sensor detection. The capabilities have not yet been integrated into a single working firmware build; this is work in progress. The current software implementation can be consulted here. Further work is also needed to design the enclosure to accommodate the hardware in a compact, weatherproof format. The build needs to be optimised for power consumption. Initial measurements suggest a current-draw of around 35mA in track-recording mode, but I believe this can be reduced below 20mA with optimised use of deep sleep, and with careful power management of the GPS module. This suggests the device could operate for 3 days on a single 1600mAh LiFePO4 battery, or 6 days on two. I look forward to completing this unfinished work, but wanted to submit an entry for the competition in time for the deadline.

Potential further enhancements

Because the ESP32 is also blessed with Bluetooth, the possibility exists to also track Bluetooth sensors such as heart-rate monitors and pedal-power meters. This would clearly increase power consumption compared to simple GPS tracking, but in certain circumstances it might be an attractive trade-off.


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Baia – Tulcea


80% of our hotel bookings have been made via booking.com, and we have found some great places. The review scores and comments are really helpful but occasionally you get a misery-guts who pans a nice place. “Orange Juice with breakfast was charged as extra, but not mentioned when served” said Istvan about Hotel Mondial. We found the place very nice, the staff were helpful, but when the waitress asked us “would you like Orange Juice with breakfast” I shot Caroline a look to say “it’s a trap!”

Baia to Tulcea was effectively our final bike tour day. The Danube has already divided into multiple branches, and Tulcea is where land turns to swamp. We will take a boat trip to Sulina today, where swamp turns to sea, and then return here for one more day ride to the railway station at Galati, from where we travel to Bucharest and fly home. It’s been a long trip and I think we are ready for home.

Strava: here


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Constanta – Baia

Slightly awkward departure from Villa Anticus, our hotel, this morning. When we checked in, the proprietor was at pains to tell us not to allow any strangers to follow us us in through the front door. “There are many people passing here. Guests have their own key. Do not let anyone enter!” Pause for emphasis. “Do not forget!”.

This morning, ready to leave and waiting for our bikes to be brought up from the cellar, I thought I would step outside and ring the doorbell to get attention. Step back inside and conscious of someone following me. Put shoulder firmly against door to thwart the invader. Eventually realise it is our host and I am expelling him forcefully from his own house!
North of Constanta, the Mamaia beach strip stretches for miles and miles. It’s extraordinary how much accommodation capacity is available on this coast, and more part-built on the way. Then again, Romania has less than 100km of beachy coastline, for a population of 7 million, so they have to pack them in.

Picnic lunch in Säcele, where an old fellow with a long staff was sitting on a nearby bench. A few spots of rain and he retreats into a covered bus stop. Rain dries up and he emerges again. I become convinced he has been engaged by the village as a life-sized Austrian weather house.

Half an hour before we were due to arrive at our isolated hotel in Baia, the heavens opened with an almighty thunderstorm. Absolutely pelted with rain. But welcomed in to a comfortable room with whirlpool bath. It seemed like fun to share the bath but forgot that cyclists at the end of the day are prone to cramp; cue comedy leaps, splashes and stretches.

Strava: here


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Vama Veche – Constanta

Stefan, our young host at Vama Veche, spoke great English. We found out why. “I worked for a year in Scotland, at Blair Atholl.” Hmm, that sounds familiar, in the Highlands, right? “Yes at the House of Bruar”. Suddenly we remembered, we had been there on our Scottish bike tour of 2015, a very large, roadside, shopping complex with would-be posh restaurant, designed for coach loads of mostly American tourists. Caroline just bitterly reminded me “you couldn’t buy a newspaper there”. Stefan loved the area though, Pitlochry was nice and he would go for runs in the hills, which he won’t do in Vama Veche because he’s scared of the dogs.

Speaking of which, we have not been bothered much by roaming dogs since a week ago back in the west of Romania. Yesterday a few big ones gave chase. You’ll read many recommendations about how to deal with them. Ultrasonic hooters, pepper sprays, make eye contact, don’t make eye contact, etc. This time I’ve been following advice to greet them with an enthusiastic “Hello Johnny!” It works just as well as anything else.

Reaching Constanta was an ordeal, on the manic E87 again, which poured its traffic into the city as if the M1 just dumped its load into Watford. Although our hotel is lovely, and we enjoyed a really nice Lebanese meal, we’ve found the city a bit crap. It’s got a glorious history, Jason of the Argonauts visited, but recent improvements haven’t really tamed the Communist-era concrete and poor planning.

And it feels a little bit intimidating. Small children selling flowers at the waterfront restaurants are nothing unusual, but I’m not sure why this one thought hitting me with a stick multiple times would help make a sale.

Strava: here


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Balchik – Vama Veche

The E87 road from Varna (Bulgaria) to Vama Veche (Romania) has a reputation as busy and dangerous. Thanks to Bulgarian Bob we avoided much of this, by-passing via local resorts and villages.

Spent the last of our Bulgarian Lev on a delicious lunch at Tyulenovo Bar and Restaurant (“Cool drink, cool food, cool people”). The fish soup reminded me of one we tasted in Copenhagen, at ten times the price. A cool Romanian guy asked to have a close look at our bikes… seemed like a dawning realisation when he saw essentially road bikes carrying luggage.

Some long, shallow descents on the way to the Romanian border, so, in honour of our 82-year-old cyclist friend Bryce, who is hosting a freewheeling contest in Winchester today, we tucked chins to handlebars and rolled as far as we could.
Luckily heads were back up when we spotted a large object in the road. Some kind of roadkill… a European wildcat, about double the size of a typical moggy.

Even during the Ceauşescu regime, Vama Veche attracted Romanian free-spirits, for wild camping, skinny-dipping and respite from totalitarianism. It continues, albeit a little more commercialised, though, out-of-season on a chilly evening I declined to skinny-dip.


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Fântânele – Ruse

We didn’t really get the hang of Southern Romania. Lodgings so far apart and village shops so poorly stocked that we mostly lived on spready cheese sandwiches and tinned puréed beans.

Though we found some outstandingly kind and generous Romanians. In Ziminicea, after half an hour’s cycling I realised I’d ridden off with the room key from last night’s stay. Wrestled with what to do. One hour round trip, or find the post office and post it back. At the counter in the PO, the lady is helping wrap the key, when a young woman walks and says “Oh, I know the people from the Pension in Fantanele really well, I will take it!”

In Corabia, Andrea, a teenage boy with outstanding English, approached and said: “This is gonna sound weird, but is there anything I can do for you?” Well funnily enough there’s this Pension we’ve been trying to book and they don’t respond to text or email and we’re too scared to call because we know they won’t speak English. “No problem, I’ll call”. He tried the three numbers we had. One wrong number, one disconnected, one no response.

This was a pretty big blow because this Pension at Ion Corvin is the only one in that region, and now we knew, thanks to Andrea, that we couldn’t rely on it. We were missing a stepping stone to reach the Black Sea.

But Ruse! Known as Little Vienna. A glorious pedestrian town square, surrounded by cafés​ and restaurants. Lovely room in a gorgeous, friendly hostel. Just what we needed. We quickly decided to stay an extra day, get some rest and take a Bulgarian train to Varna. Not exactly en route but it allows us to cycle on to later bookings on the Romanian Black Sea coast, and reach the Danube Delta at Tulcea.

Feared Bulgarian train would have wooden benches, nightmare to load bikes, etc, but nothing of the sort. Bikes loaded fine. Smiling guard: “OK no problem”. Comfy carriage to ourselves, will be in Varna by 10am.


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Bechet – Fântânele

I’ve been struggling to write something about Mike Hall’s funeral and celebration yesterday. Marion’s photos seem better than anything I could say. We’ll miss Mike so much. I hope yesterday’s events help begin the healing for Pat, Anna and Russell.

Our #rideformike yesterday was a tough one. My dearest Caroline only signed up for a holiday, but got an adventure/challenge instead. 120km fully laden in 80 degrees and headwind. Together with poor eating opportunities, she is done in. Also, one of our accommodation plans for Friday night fell through. We completed today’s shorter leg into Bulgaria, but the time has come to take a couple of days off the bikes, and fill in the gap with a train. Easier said​ than done, but I think we may have a cunning plan.


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Port Cetate – Bechet

Today was the day for meeting other touring cyclists. In 11 previous days, we’d only encountered one couple, French, with baby in trailer, who were on their way home from a climbing trip in Bulgaria and Greece.

Today, we met Roland and Jana, from Norway, on a honeymoon tour from Budapest to Bucharest. They stayed in the same hotel as us in Bechet (not so much of a surprise as there is only one) and we ate dinner together and compared cycling notes.

On the road, we met Karlis from Latvia, cycling home from the Bulgarian Black Sea coast on an ordinary street bike. A “get on a bike and ride” kind of cyclist, he made all our OCD about equipment seem ridiculous. He was thrilled to be wild camping next to the Danube and waking up to the sound of the bullfrog chorus.

Besides the cyclists, we chatted with a young long-distance lorry driver, who had been visiting grandparents in Nedeia. He explained that only old people live in this part of Romania now. With the arrival of mechanised agriculture, young people moved to the cities, and old people sold their land to Italian and French agribusiness. Now the old people sit on their benches by the roadside, and the arrival of a couple of cyclists seems to make their day.

In Carna, we enjoyed passing the Non Stop Disco Club Bar, where three people quietly dozed in silence.

Strava: here


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Hinova – Port Cetate

The hangover from last night’s shenanigans hung on for a couple of hours, aided by a headwind that shouldn’t have been there. The route took us West, further from our destination, following the meandering Danube.

At Tiganasi we turned East, picked up a pristine road and the promised tailwind, and the world seemed a better place. Every 10km or so, we passed through a different wild west town. Nothing much open. In Izvoarele, a funeral procession, with brass band celebrating the life of the poor old fellow whose face poked out from the back of a hatchback. In Gruia, chased out of town by vaguely intimidating youths, we picnic’d on the outskirts, on a kind of marble dais outside a Roma mansion with loud gypsy dance music playing through an outdoor speaker. Friendly Vrata, where we were high-fived and cheered by almost everyone; mostly in Italian. “Ciao” and “Com esta”.

Unlike last night we were booked into accommodation, at Port Cetate Cultural complex, a former grain port, made obsolete in 1945 when communist Romania was ordered to send its crop to Moscow instead of Vienna. Restored from 1997 by a satirical writer (think Private Eye) as a culture centre with restaurant and accommodation. Food nice, wine from the estate delicious, showers to die for. What a change from last night!

Strava: here


Facebooktwittergoogle_plusredditpinterestlinkedinmail

Danube: Donji Milanovac – Hinova (Romania)

The Ethno Complex at Kapetan Misin Breg was a brilliant place to stay. Styled as a traditional Serbian village and set on top of a hill with fantastic views over the Danube and the village of Donji Milanovac. We were met on arrival by the boss, Surjan, who asked if we wanted dinner and were we vegetarian (I hadn’t requested special meals). Within a few minutes we were presented with an enormous vegetarian feast of local produce (more than we could eat) along with honey Rakija. Breakfast was equally lavish. Everyone there was so nice to us; we loved it.

On the road today, we completed the set of 19 tunnels through the Iron Gates, and the valley scenery got even more spectacular. We climbed one long hill, labelled 10% but nothing like. Before long we were crossing the border into Romania, and hit the shocking traffic of the E70 motorway.

Accommodation options in Romania are very limited. It’s forced us to plan for some longer than comfortable days, longer than Caroline’s 100km stipulation. Today was only 95km but Pension San & Gino, which we were hoping to get into, hadn’t responded to multiple emails, so we approached with fingers crossed. The worst happened. They were full. Asked if there was anywhere else, the suggestion was Calafat, about 120km away. Ridiculous. We decided he just didn’t like us. Few options, but we pressed on to a location where a guesthouse was marked on OpenStreetMap. It was a small marina, but the buildings were fenced off and seemed abandoned. A man was there and I asked if we could get a room, and at first I thought he said yes. Then he played with his dog a while and disappeared into a house. Then emerged with his wife who spoke a little English. “No rooms”. We turned the pitiful looks to maximum. “Do you have a friend with a room?” Romanian husband & wife conversation. She looked pitying but he looked to be taking a hard line. Eventually she said “we make phone call”. Long wait. Long, long wait. Finally: “We have called Pension San & Gino, he is my husband’s friend, they will give you a room”. Back to Pension S&G. All smiles. They find us a room.


Facebooktwittergoogle_plusredditpinterestlinkedinmail