PX4 MAVLink-Python Programming: 5. Ensuring MAVLink Reliability
Hello. This is Aiden from the Marketing Team.
Today, I would like to introduce PX4 MAVLink-Python Programming, specifically focusing on Ensuring MAVLink Reliability. Please note that this content is registered under the copyright of our QUAD Drone Research Institute, and we kindly ask you to refrain from unauthorized distribution.

HEARTBEAT
All MAVLink components must periodically broadcast a HEARTBEAT message and receive heartbeats from other systems. A system considers itself connected to another system as long as it regularly receives a HEARTBEAT from it.
The message can be sent using the HEARTBEAT message from the generated Python dialect file. The MAVLink.heartbeat_send() method is defined as follows:
def heartbeat_send(self, type, autopilot, base_mode, custom_mode, system_status, mavlink_version=3, force_mavlink1=False):
'''
The heartbeat message shows that a system is present and responding.
The type of the MAV and Autopilot hardware allow the
receiving system to treat further messages from this
system appropriate (e.g. by laying out the user
interface based on the autopilot).
type : Type of the MAV (quadrotor, helicopter, etc.) (type:uint8_t, values:MAV_TYPE)
autopilot : Autopilot type / class. (type:uint8_t, values:MAV_AUTOPILOT)
base_mode : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
custom_mode : A bitfield for use for autopilot-specific flags (type:uint32_t)
system_status : System status flag. (type:uint8_t, values:MAV_STATE)
mavlink_version : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)
'''Assuming we are using a mavutil link named the_connection returned by mavutil.mavlink_connection(), you can send a heartbeat as follows:
# Send heartbeat from a GCS (types are define as enum in the dialect file).
the_connection.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS,
mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0)
# Send heartbeat from a MAVLink application.
the_connection.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_ONBOARD_CONTROLLER,
mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0)The rate at which heartbeats must be transmitted depends on the channel, but it is typically 1Hz.
Generally, it should be sent from the same thread as all other messages. This is to ensure that the heartbeat is only published when the thread is healthy.
Message Signing
Pymavlink supports message signing (authentication) when using MAVLink 2.
The Pymavlink library already implements almost all the expected behavior for signing messages. You only need to provide a secret key and an initial timestamp, and optionally specify callbacks to determine whether outgoing messages should be signed, the link ID, and which unsigned messages (if any) to accept.
How you perform this depends on whether you manage the connection using mavutil or use the MAVLink object directly.
While we won’t cover them in this section, you should also write code for the following:
- Saving and loading the secret key and the last timestamp from persistent storage.
- Implement a mechanism for creating and sharing keys. For more details, refer to Message Signing > Secret Key Management.
Signing with the MAVLink Class
If you are using the MAVLink class directly, you can access the MAVLinkSigning object using the MAVLink.signing attribute and set the required properties.
The example/mavtest.py script demonstrates how to do this using a random secret key.
# Create a MAVLink instance (in this case on a file object "f")
mav = mavlink.MAVLink(f)
if signing:
mav.signing.secret_key = chr(42)*32
mav.signing.link_id = 0
mav.signing.timestamp = 0
mav.signing.sign_outgoing = TrueThe class does not verify whether the packet’s
link_idor initialtimestampare appropriate. The initial timestamp should be based on the current system time. For more details, refer to Message Signing.
Signing with mavutil (MAVLink 2)
If you are managing the connection using mavutil, you can enable or disable signing using the methods shown below.
#Setup signing
def setup_signing(self, secret_key, sign_outgoing=True, allow_unsigned_callback=None, initial_timestamp=None, link_id=None)
# Disable signing (clear secret key and all the other settings specified with setup_signing)
def disable_signing(self):This method configures the MAVLink object owned by the connection using setup_signing() and provides some additional internal code to manage the state.
- If you do not specify a link_id, the value will iterate internally.
- If initial_timestamp is not set, an appropriate value for the current time will be populated by the underlying OS.
Using allow_unsigned_callback
Message Signing > Accepting Unsigned Packets and Accepting Incorrectly Signed Packets specifies that the message signing implementation must provide a mechanism where library users can conditionally choose to accept unsigned or incorrectly signed packets.
Pymavlink provides an optional allow_unsigned_callback() for this purpose.
bool allow_unsigned_callback(self, msgId)When configured as part of the signing setup, this function is called for unsigned packets (including all MAVLink 1 packets) or packets with incorrect signatures. If the function returns False, the message is dropped; otherwise, it is processed as if it were signed.
The rules for when to accept unsigned packets depend on the specific implementation; however, it is highly recommended to always accept RADIO_STATUS packets to ensure feedback from 3DR radios, which do not support signing.
For example:
# Assuming you already have a connection set up
the_connection = mavutil.mavlink_connection(...)
# Create a callback to specify the messages to accept
def my_allow_unsigned_callback(self,msgId):
#Allow radio status messages
if msgId==mavutil.mavlink.MAVLINK_MSG_ID_RADIO_STATUS:
return True
return False
# Pass the callback to the connection (here we also pass an arbitrary secret key)
secret_key = chr(42)*32
the_connection.setup_signing(secret_key, sign_outgoing=True, allow_unsigned_callback=my_allow_unsigned_callback)YOUTUBE Class
That concludes our look at Ensuring MAVLink Reliability, the fifth step in PX4 MAVLink-Python Programming. In the next post, I will return with an article focusing on MAVLink Reliability: MAVLink 2 Message Signing.

Author: Aiden, Marketing Team at QUAD Drone Lab
Date: March 06, 2026
