Transcontinental Race 2016: Durmitor

I wrote this little piece as a comment on a TCR Facebook group. Re-posting it here to preserve the memory.
On the CP4 parcour, Durmitor, Montenegro

Croatia had been hard on me. A small crash at the border left me a little concussed, and with a slightly bent disc rotor that was dragging me down, perhaps more mentally than physically. Then the heat of Rijeka and the bora wind of the coast nearly beat me to a pulp and I thought my attempt on TCR was all over. Passing through Sinj, things started looking up. I met Rory Bear Kemper in a bus shelter; we shared a few words, the first company I’d had in days. Then a roadside bike workshop appeared like an oasis in the desert, and they straightened my disc in moments. I was rolling again. Bosnia seemed to go by in a flash, and I spent a cheap night in a doss house in Capljina.

Up before dawn, I started on the deserted road through Republika Srpska to the ‘secret’ border with Montenegro, the beginning of maybe the most perfect day’s cycling of my life. Herdsmen led their sheep flocks down the road, but not a soul otherwise. I tweeted there might be radio silence because I had no data allowance in Montenegro, and Kevin, who’d been enjoying my gastrotour, said he *needed* to know what I was eating. I reported it was Nutella straight from the jar, as I rested in a shady grove next to a rough gravel path. The final 5km ascent to the frontier – the unmanned secret border crossing from which some riders had been sent back – was pure rock, a steep hike-a-bike for me (though I later saw photos of Carlos Mazon riding it I think). For all I knew it could have carried on like that all day, or I could have been sent back down for an 80km detour to one of the official crossings. But no! At the border, entering Montenegro and Durmitor National Park, the gravel turned to silky tarmac ( for a gorgeous descent to Pluzine. The cool and funky (but very slow) cafe marked the start of the parcours. It was late afternoon by now and I dawdled – my weakness – using the slow service as excuse for a longer rest. Riders passed through. Mark Booker, with his legs all scraped from a bad fall. Vinicius looking fit and organised. And Hilde, bright and cheerful despite a very painful knee. Eventually I dragged myself back onto the bike leaving Hilde finishing her food. As Mikko describes, the road climbs up from the lake via tunnels dug from the rock. But afterwards it’s bucolic. In the warm, dusky evening, farm workers rested beside the medieval-looking haystacks they’d gathered that day, swigging well-earned beers. The sun set, the air grew cooler and eventually I climbed to the double peak of Prevoj Sedlo in darkness. A pair of motor-bikers passed me and stopped to talk. They told me they’d met Hilde behind and she planned to sleep part way up the climb; I think a family had offered her a barn. Descending was tricky in the darkness. A few days earlier I’d descended the San Pellegrino pass in darkness to reach CP3, and that had been scary enough, even with the benefit of road markings and chevrons at the bends. This descent to Žabljak had no such help. But eventually Žabljak was reached and as I rolled past a restaurant with TCR riders, super-helpful CP volunteer (and future TCR5 finisher) Martin called out to me. The Highlander hostel was full, but Martin arranged a place in an overspill room. I was too tired for food, but elated to have reached CP4. With ‘only’ 1000km to go, and the major climbs all done, I had flipped into the ‘you can do this’ mindset that had deserted me in Croatia.

Next morning I woke up with the ever cheerful Giorsio, who told me that my loud snoring overnight wasn’t a problem at all, as he had noise-cancelling earplugs for *exactly* that purpose. It was the first of a few encounters over the next several days that would see us getting into various scrapes. The weather had turned cold and rainy overnight; I hadn’t expected that. Hilde had rolled in early that morning. The Highlander hostel promised breakfast, and Hilde and I waited, keeping warm under that same blanket Mikko is wrapped in. Martin had contacted a doctor to check out Hilde’s knee, and, after breakfast she sadly climbed into a car. We all thought it was the end of her race. Happily it turned out not to be so, and after a day’s rest she was declared fit and rolled into Çanakkale a day or so after I did.

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.


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.

June 2017: Mike Hall’s Wake

A gathering, centred around the village of Abbeycwmhir, in mid-Wales, to celebrate the life of Mike Hall. Winner of multiple ultra-distance, self-supported bicycle races and organiser of the Transcontinental Race. Mike was killed by a car driver south of Canberra, Australia, during the inaugural Indian Pacific Wheel Race, on 31 March 2017.

Danube: Baia – Tulcea

80% of our hotel bookings have been made via, 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

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

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