Mavlink Wall-Clock Sync
This guide walks through configuring the NanoPi to set its system clock from a MAVLink peer's SYSTEM_TIME messages. This is useful in systems where there is one device that all of the other device logs should be synced with.
The wall-clock source can be any MAVLink device that sends SYSTEM_TIME with a valid epoch timestamp — a flight controller with GPS, a companion computer with NTP, a dedicated time module, etc. The timesync module does not care where the peer gets its time from.
How It Works
Time source (GPS, NTP, etc.) → MAVLink peer → SYSTEM_TIME → SHM → chrony → Pi clockSome MAVLink device on the bus has an accurate wall clock (however it obtained it).
That device sends
SYSTEM_TIMEmessages containingtime_unix_usec.The timesync module receives those messages and writes valid timestamps into an NTP shared memory segment.
Chrony reads that segment as a reference clock and adjusts the Pi's system clock.
All other Theseus sensors sync from the Pi via NTP automatically.
Prerequisites
The configured MAVLink peer must be sending
SYSTEM_TIMEwith a valid epochtime_unix_usec(i.e., a real wall-clock time, not zero or boot-relative). Without valid timestamps, chrony falls back to whatever time source it had before.If the peer is a flight controller using GPS as its time source, set
BRD_RTC_TYPES=1on the FCU (reboot required). Do not use2— it creates a circular time loop where the FCU trusts the Pi's clock, which is trying to trust the FCU's clock.chrony.confmust include the SHM refclock line. This is included by default on mvps devices, but verify it is present:
refclock SHM 0 refid MAV precision 1e-3 delay 0.01 poll 1Parameters
All parameters live in mav_timesync_params.yaml (file ID: components/timesync/mav_timesync_params). Four parameters control wall-clock sync:
mav_clock_input
bool
false
Master switch. When true, valid SYSTEM_TIME messages from the configured source are written into chrony's SHM segment. When false, no clock adjustment happens regardless of other settings.
system_clock_source_mode
string
timesync_peer
Determines which MAVLink peer provides the wall-clock time for chrony. timesync_peer reuses the normal TIMESYNC target. dedicated_peer uses the explicit sysid/compid below instead.
system_clock_source_sysid
int
42
MAVLink system ID of the dedicated wall-clock peer. Only used when system_clock_source_mode is dedicated_peer.
system_clock_source_compid
int
1
MAVLink component ID of the dedicated wall-clock peer. Only used when system_clock_source_mode is dedicated_peer.
When to use each mode
timesync_peer (default): The same MAVLink peer used for TIMESYNC round-trip offset estimation also provides SYSTEM_TIME for chrony. This is the simpler configuration and works whenever that peer has a valid wall clock.
dedicated_peer: A different MAVLink device provides the wall-clock time for chrony. Use this when:
The TIMESYNC peer does not have a reliable wall clock.
You want to source wall-clock time from a specific device on the MAVLink bus that is not the TIMESYNC target.
In dedicated peer mode, the TIMESYNC peer still handles boot-offset initialization and round-trip time measurement. Only the chrony wall-clock feed is redirected to the dedicated peer.
Configuration
Start by downloading the below python helper script:
The timesync_clock_source.py script wraps the Params API so you don't need to remember individual curl commands. It lives at scripts/device/timesync_clock_source.py in the repository.
Check current status:
Example output:
Enable wall-clock sync with the default TIMESYNC peer:
This sets mav_clock_input: true while leaving system_clock_source_mode: timesync_peer, so chrony gets its time from the same peer used for TIMESYNC.
Switch to a dedicated peer:
This sets system_clock_source_mode: dedicated_peer and configures the peer IDs. If mav_clock_input is already enabled, the dedicated peer will start feeding chrony on the next service restart.
Clear the dedicated peer (revert to TIMESYNC peer):
Disable wall-clock sync entirely:
Custom API URL (if the edge API is not at the default http://192.168.218.100:5050):
All parameters use the Params API at http://<device>:5050/api/v2/params. The file ID for timesync is components/timesync/mav_timesync_params.
Read all timesync params:
Enable wall-clock sync:
Switch to dedicated peer mode with sysid 42, compid 1:
Revert to TIMESYNC peer mode:
Reset peer IDs to defaults:
Parameter changes require restarting the consuming service (Cyclops or MVPS) for the new values to take effect. The process reads its YAML config once at startup.
Verification
After restarting the service, verify that chrony is receiving time from the MAVLink source:
Look for a line with #* MAV — the * means chrony has selected it as the active source:
Verify the system clock is correct:
If chrony shows MAV but without the *, it means chrony sees the source but has not selected it yet (it may still be evaluating samples). Give it 30-60 seconds after the peer starts sending valid timestamps.
Troubleshooting
No MAV source in chronyc sources:
Check that
mav_clock_input: trueis set and the service was restarted.Verify
refclock SHM 0 refid MAV ...exists in/etc/chrony/chrony.conf.
MAV source present but not selected (#? instead of #*):
The peer may not have a valid wall clock yet. Check
time_unix_usecin theSYSTEM_TIMEmessages — values near zero mean the peer does not have a time source.Chrony may be preferring another source. Check
chronyc sources -vfor competing sources with better stratum.
system_time_invalid events in logs:
The configured source is sending
SYSTEM_TIMEwith atime_unix_usecthat is not a valid epoch timestamp (before Feb 2009). This means the peer does not yet have a valid wall clock. The events will stop once the peer starts sending valid time, and asystem_time_recoveredevent will be emitted.
Dedicated peer configured but no clock feed:
Verify
system_clock_source_modeisdedicated_peer, nottimesync_peer. Intimesync_peermode the explicit sysid/compid values are ignored.Verify the dedicated peer is on the MAVLink bus and sending
SYSTEM_TIMEat the expected sysid:compid.
Last updated
