With OpenGD77 on my MD-UV390, the battery status can be shown in two ways in the top bar of the screen: as a percentage or as a voltage. The voltage doesn’t tell me much, and the percentage is pure fantasy.

The function that computes the remaining battery percentage is a simple straight line (0 % at 6.4 V, 100 % at 8.2 V), which doesn’t reflect at all how a lithium-ion battery discharges. My first idea was to replace it with a “theoretical” Li-ion curve, taken from generic documentation on these batteries. That was even worse: 50 % after 10 h, 7 % with 7 h 30 min still left, and so on. Completely off.

To get an accurate percentage, I had to measure the discharge of my battery, from a full charge until the radio shuts itself off, when the voltage reaches 6.2 V (about 3.1 V per cell, safe for the battery).

(Note: I calibrated the voltage read by the radio against a multimeter before taking the measurement.)

In the Radio Info screen, the first page shows both values (voltage and percentage), and the sixth a discharge graph. Since I didn’t see myself staring at that screen taking notes for the whole discharge, I needed something else. So I thought of logging the discharge data the same way the NMEA stream from the GNSS receiver can be logged to flash memory. And since that logging feature already exists, all it takes is adding lines to the existing log instead of creating a new one. The NMEA standard provides for “proprietary” sentences (they start with $P) to carry your own information: software ignores the ones it doesn’t know, so nothing breaks.

This feature takes two small firmware changes:

  • the NMEA logging mechanism adds a battery status line every minute;
  • the Options → General Options → GPS setting gets a new option: Log Bat joins Off, On, NMEA and Log. This new Log Bat option logs only the battery status, so it takes little room in flash memory. In Log mode, the battery lines are added to the position data.

Once the firmware is modified and rebuilt, you charge the battery to the full and switch the radio to Log Bat mode. I chose to do it somewhere with no GNSS reception (a building with a sheet-metal roof, so the receiver kept searching for satellites throughout the test), tuned to an FM frequency with no traffic, so that the discharge would be as steady as possible. I hadn’t paid much attention to the power-saving settings before the test: it turned out Eco mode was off (Eco Level: 0), with the backlight dropping to 5 % after 30 seconds without interaction.

To my great surprise, the radio took more than 30 hours to discharge in that state. Really impressed. For the record, I’m using the battery that came with the radio, whose label says 7.4V/3600mAh/26.64Wh. If it really holds its rated capacity, that’s an average draw of about 120 mA on receive (3600 mAh / 30 h).

All that was left was to retrieve these measurements. The log lives in the radio’s flash memory, with no file system, and I couldn’t find an option to read it in qDMR, the CPS I usually use. So I wrote my own utility, ogd77reader: a single Python file, with no dependencies at all, for Linux and macOS. It uses the read command the official firmware already has for the CPS, so it also works with the stock firmware, and it only ever reads, never writes. With the radio plugged in over USB, one command is enough:

./ogd77reader.py log journal

It produces a raw copy of the log, one NMEA file per session (readable by GPSBabel, QGIS, etc.), and a CSV file with all the battery measurements, ready for a spreadsheet.

The radio logged one measurement per minute, that is 1808 usable measurements between a full battery and shutdown, all on receive (no transmission during the test). Here’s what they give, compared with OpenGD77’s original calculation and with the generic Li-ion curve:

VoltageOriginal OpenGD77Generic Li-ion curveMeasuredTime left (approx.)
8.3 V100 %95 %100 %30 h
8.0 V88 %80 %81 %24 h
7.8 V77 %68 %70 %21 h
7.6 V66 %50 %59 %18 h
7.4 V55 %30 %50 %15 h
7.2 V44 %15 %38 %11 h 30 min
7.0 V33 %7 %23 %7 h
6.8 V22 %4 %13 %4 h
6.6 V11 %2 %5 %1 h 30 min
6.4 V0 %0 %2 %35 min
6.2 V0 %0 %0 %shutdown

The original straight line is a bit too optimistic (5 to 10 points too high in the second half), the generic curve far too pessimistic. The remaining times only hold for this idle receive test: when transmitting, or with a GPS tracking satellites, the battery drains faster. The percentage, though, stays accurate, since it shows the share of charge left.

I replaced the firmware’s straight line with this measured table, in my own build of OpenGD77. The result: a full battery shows 100 %, 50 % really means half is left, and 7 % no longer hides 7 h 30 min of listening. And I now know this radio lasts more than 30 hours on receive on a single charge!