MAVLink Step by Step

@marcsay If a message is encoded as MAVLink 2 it’s message ID can be upto 24 bits long.

He is most probably using FastSerial or Softwareserial library to be able to communicate with the PC with the Arduino UART and then two digital output pins to the Pixhawk.

If using Softwareserial then SerialMAV could be something like:

#include <SoftwareSerial.h>
SoftwareSerial SerialMAV(11,12);    // pins for RX, TX

Then the use of SerialMAV is mostly identical to the normal Serial variables…

Really great explanation. Finally some clarity. I am still struggling to understand how should i start using MAVLink to communicate and how exactly can i monitor whether there is any response?
Suppose i start with a Heartbeat message.How will i monitor it on Pixhawk?
also can someone please upload an example basic program so that i know how exactly to code.
I am using arduino and Pixhawk Px4.


Heartbeat is not really used for anything, just as a way to know that you are connected. The important part is triggering the messages you are interested in and then parsing the messages with the appropriate directives.

Please find attached a sample program I intend to use to implement navigation lights in my drone. Still under development, but basic functionality is already working.

Sorry for the comments, they are in Spanish. If you need help, I can translate them. It is also a working file, so still a lot of “garbage” around of pieces of information and documentation pasted across… (4.5 KB)

Gracias @jplopezll Juan Pedro :slight_smile:

De nada, un placer…

If you are looking for the continuation of this great post, I have published a post on how to interface a Pixhawk with an Arduino and use it to control on-board lights. It is the explanation of my code above and how to modify it setp by step:

Specially dedicated to @LuisVale :wink:.


Thanks @jplopezll Juan Pedro.

I’ve also pinged @Pedro_Albuquerque to follow up on his latest achievements :slight_smile:

@LuisVale, I tried to contact Pedro by PM to see if we could work this out together, but no answer. His profile has no activity since 2016. I do not know if he will receive messages from this forum any longer :worried:.

No problem @jplopezll He is a personal friend and I spoke with him last weekend :slight_smile:

Good news!

If he has any ideas on how to improve the version 2 of his great post, tell him to PM me. I still want to add some pictures and drawings and maybe explain a bit more the code and what it does.

Thanks for the exploitative post…
Does that autopilot send heart beat message to GCS? If not why? If I want to test the receiving messages with QGC what should I need to do? Note that I am pretty new to this…

Hi eveyone, I need I little of help

I want to receive a command on my arduino but im I little lost. For now, im doing the next;

mavlink_message_t msg;
mavlink_command_long_t cmd;
mavlink_status_t status;
while (Serial.available() > 0) {

uint8_t c =;

if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) {

  mavlink_msg_command_long_decode(&msg, &cmd);

    digitalWrite(ledPIN , HIGH);

  switch (msg.msgid) {
    case MAVLINK_MSG_ID_HEARTBEAT:  // #0: Heartbeat
      { }



Awesome intro! Thanks a lot!

Not beat a dead horse to death with a stick , I jad purchased a pixhawk 2.4.8 complete package with radios (sik) long story got the telemetry radio stuck in boot then messed up fiti connection fried it…now still have ground station radio so I go hunting for radio find crius v 1.0 …now I cannot for the life of me get them to lock . Both radios have blinking red and green but green never locking…[quote=“Pedro_Albuquerque, post:1, topic:9629, full:true”]
#MAVLink - Step-by-Step
by Pedro Albuquerque

This post result from my struggle to find information about the subject to understand the concept, and developing a basic concept test.

My background - I have been using Ardupilot software on Multirotors and airplanes for 1 year.
I learned to program C (C86, Microsoft C, Turbo C) 30 year ago (yes 1986) , i’ve been away from programming in C, eventually only reading some code since then , and recently (2 month ago) I got to know arduino and its IDE.

back to the subject.

##A message system
MAVLink is a message protocol, designed to exchange information between a UAV and a GCS or a subsystem (ex:gimbal controller), using a serial communication channel.

The base structure of the protocol is the message. For perfomance reasons it is binary information, so , eventually not readable by humans without some interpretation.

##A simple message with acknowledge

this is an example of a message (WAYPOINT_CLEAR_ALL) sent by the GCS to a UAV. The UAV receives and executes, and responds with another message (WAYPOINT_ACK).
After sending the initial message, the GCS starts a timer to decide for a timeout state if no ACK messages is received .

##System ID, subsystem ID and Message ID

Most messages will indicate source(originating) system ID (sysid) , subsystem ID (compid), destination system ID, destination subsystem/component ID and a message type ID

GCS system ID should be 255 (see here )
Vehicle ID should be 1
(see here the parameter on Ardupilot

Some subsystem codes are already reserved. look for MAV_COMPONENT on this page

Source sysID , compID and MSG are all encoded in the message header.

Destination sysID , compID when necessary will be part of the payload.

The payload content/structure for each MSG is defined here (keep calm… will get into practical details later)

##Library support
A library is available to help prepare a message to be sent or to decode a message just received.
Actually, you will have to build your library following this instruction to adjust it to your platform and your programming language.

You end up with a folder with your library called mavlink (or the name you decide eventually)

###example Steps (performed on a Mac):
download the zip from github to a folder named mavlink-master
On a terminal windows , change to that folder and execute the command
“python -m mavgenerate”
on the new window choose
xml folder: …/tmp/mavlink-master/message_definitions/v1.0/ardupilotmega.xml
out folder: …/tmp/MAVLink
language: C
protocol: 1.0

##How to use the result
Once the folder has been generated I moved it to the library folder , in my case as I am using an arduino as a auxiliar system I installed it at
and include it like

##But what does it contain ?
This was something I really strived to discover
Remember, what we want - compose messages to send and receive messages and interpret them.
The message is the focal point.
So before going into coding, we need to first know what messages are available and their meaning/purpose.
The general message list can be found starting here->

Every platform may choose to implement a sub-set and/or additional messages. Arduplilot implemented messages can be found at
Any message is composed of several fields(struct in C), and is a mavlink_message_t type .

Additionally each specific message has associated with it:

  • a type def for the structure to hold the payload fields
  • a pack function to load the message with the data
  • a decode function to translate the message and load the payload structure (specific for each message)

All of this is defined in a include file with the same name as the message.
(When you include the mavlink.h in your code you are also including all the include files for each message.)

##example: HEARTBEAT

definition file is common/mavlink_msg_heartbeat.h

note: the location of the file can be on platform folder or in common. they are on platform folder if they have some modified from the common definition.

type def: mavlink_heartbeat_t
packing function: mavlink_msg_heartbeat_pack() - load the mavlink_message_t type object with all the necessary information so that it can be sent
decoding function: mavlink_msg_heartbeat_decode() - decode the message and fill the mavlink_hearbeat_t type object with received message information
Note that this definition file serves both purposes, to prepare a message to be sent or to decode a message received.

##Is that all?
We are almost there (able to write a sketch to receive and send a MAVLink message).

###Receiving a message
we need to write a function to read the message from serial com and decode it.

now you just call it when you fill appropriate.

###Sending a message

Sending a message is a bit more tricky.

The system running our software need to have a SysID and a CompID, so we have to decide one.

choose any SysID except 1 ou 255
choose compID 1 is case no match found to reserved codes.

CC_SYSID and CC_COMPID were defined by me for the source system, and I’m sending a message to a ardupilot system (the target system) that has SYSID = 1 and if not for specific component, then use the main that is CompID = 1

msg is an empty object of type mavlink_message_t that will be filled by the pack function
param_id is a char array with the name of the parameter
param_index if set to -1 will use the name, other wise we need to know the index of the parameter in the target system.

copy the message to a byte buffer which is sized to the largest message MAVlink will allow.

finally , just send it to com port.

Note: Remember each message has its own propose and its own payload data, so we need to check os it’s include message file what field do we need as I could not find any other documentation for it.

##What you should achieve

  • Understand what Mavlink is
  • understand the concept and structure of a generic message
  • know how to generate and install a library to deal with MAVLink messages
  • Know where to find the available messages, and the implemented message in Ardupilot
  • know were to look for message definition
  • construct your MAVLink message receive and send routine.

Feel free to send feedback on how to improve this introductory document. Keep in mind that it is meant to help developers get into MAVLink concept and use.



  • List item
1 Like


I am still quite confusing on system id and component id.
For example, I want to send command from arduino uno to pixhawk. The function that I use is mavlink_msg_set_attitude_target_pack. The target_sysid and target_compid should be (1,1) since pixhawk has the sysid and compid of (1,1). What should I put for my source_sysid and source_compid?

Appreciate for anyone who answers me.


Hi Zimin,

“What should I put for my source_sysid and source_compid?”

You must set/decide to your SystemID (1-255, but choose one not used yet, so 1 cannot be because pixhawk already use it) and your component ID (1 if no other is present).

hope this help

1 Like

I am a beginner with mavlink and even pixahawk.
I have an urgent need to just parse mavlink data coming from pixahawk.

I have gone through mavlink tutorials, and also looking at documentation.
The data comes on Uart (telemetry1 port). I am able to receive the data through serial port and buffer it into a shared memory. I am not using any mission planner/QGC etc. I am manually writing the code to parse the data byte by byte from the data arrived on serial port.
Now, I am reusing the code at (My pixahawk sends Mavlink v1 data).

Am I right in this methodology? I am sending each byte to mavlink_parse_char(…) function in serial_port.cpp which is always returning false. Only if this returns true, it means data parsing is working correctly.

Please guide.

I wounder if we can connect Arduino with Pixhawk knowing that Pixhawk is connecting with Simulink. (Embedded Coder Support Package for PX4 Autopilots)

thank you so much for your great information
would you share the arduino sketch testMavlink.ino?