PX4 MAVLink-Python Programming: 4. Sending and Receiving MAVLink Messages
Hello. This is Aiden from the marketing team.
Today, I would like to introduce PX4 MAVLink-Python programming, specifically focusing on sending and receiving MAVLink messages. Please note that this content is registered under the copyright of our QUAD Drone Lab, and we kindly ask you to refrain from unauthorized distribution.

Sending and Receiving MAVLink Messages
Sending Messages
This is the main protocol handling class for MAVLink. It is defined in each dialect module and includes methods for all messages in the message definition, following the format <message_name>_send().MAVLink
Message field values are passed as arguments to the function. Fields that are identical across all messages (e.g., source system, source component) are defined within the class. Each message is documented in the dialect source code, even when it is automatically generated.
For example, the system_time_send() function is used to send a SYSTEM_TIME message as shown below.
def system_time_send(self, time_unix_usec, time_boot_ms, force_mavlink1=False):
'''
The system time is the time of the master clock, typically the
computer clock of the main onboard computer.
time_unix_usec : Timestamp (UNIX epoch time). (uint64_t)
time_boot_ms : Timestamp (time since system boot). (uint32_t)
'''When using mavutil for link management, the mav attribute provides access to a configured class object that can be used for message transmission. For example, to send a SYSTEM_TIME message using a MAVLink link named the_connection, use the following:
the_connection.mav.system_time_send(time_unix_usec, time_boot_ms)If you are not using mavutil, you must manually create and configure the object so that it can identify the channel used for message transmission, which is typically represented by the
MAVLinkattribute.
Receiving Messages
Synchronous access to the last received message of a specific type can be achieved using the mavutil.messages attribute. For example, if you are using a mavutil link named the_connection, you can do the following:
try:
altitude = the_connection.messages['GPS_RAW_INT'].alt # Note, you can access message fields as attributes!
timestamp = the_connection.time_since('GPS_RAW_INT')
print("Current Alt is %dm" % (altitude/1000))
except:
print('No GPS_RAW_INT message received')Alternatively, you can use the mavutil.recv_match() method to wait for and intercept a message as it arrives.
def recv_match(self, condition=None, type=None, blocking=False, timeout=None):
'''Receive the next MAVLink message that matches the given type and condition
type: Message name(s) as a string or list of strings - e.g. 'SYS_STATUS'
condition: Condition based on message values - e.g. 'SYS_STATUS.mode==2 and SYS_STATUS.nav_mode==4'
blocking: Set to wait until message arrives before method completes.
timeout: ? <!-- timeout for blocking message when the system will return. Is this just a time? -->
'''For example, you can wait for a message as follows (setting blocking=False means it will not wait):
msg = the_connection.recv_match(blocking=True)To obtain a specific message with a particular attribute value (e.g., SYS_STATUS), you can use the following approach instead:
# Wait for a 'SYS_STATUS' message with the specified values.
msg = the_connection.recv_match(type='SYS_STATUS', blocking=True)In addition, you must ensure that the message is valid before using it.
msg = the_connection.recv_match(type='SYS_STATUS',blocking=True)
if msg.get_type() == "BAD_DATA":
if mavutil.all_printable(msg.data):
sys.stdout.write(msg.data)
sys.stdout.flush()
else:
#Message is valid
# Use the attribute
print('Status: %s' % msg.battery_remaining)The MAVLink_message object returned is a subclass specific to that message. You can access message fields as class attributes, as shown for the mode in the code snippet above. If necessary, you can also query the MAVLink_message for information regarding its signature, CRC, and other header details.
Requesting Specific Messages
emote systems typically stream a default set of messages to connected Ground Control Stations (GCS), cameras, or other systems. This default set is often hard-coded and is inevitably limited to reduce traffic on the communication channel.
Systems can also request additional information by sending a REQUEST_DATA_STREAM message, which specifies the required stream (MAV_DATA_STREAM) and its corresponding rate.
Messages are sent using request_data_stream_send() (where the arg.rate below represents the desired transmission rate in Hz).
# Request all data streams
the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component,
mavutil.mavlink.MAV_DATA_STREAM_ALL, args.rate, 1)[Reference] MAVLink Message List
{% embed url=”https://mavlink.io/en/messages/common.html#messages” %}
YOUTUBE Class
This concludes the fourth step of PX4 MAVLink-Python programming, focusing on sending and receiving MAVLink messages. In the next post, I will return with an article on ensuring MAVLink reliability.

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