How to create your own custom messages in MAVlink?

I’m just a beginner in drones and I wanted to create a custom MAVlink message to the flight controller and the flight controller needs process the data off this message. I did go through the ‘MavLink Tutorial for Absolute Dummies’, I’m clear about how the xml file must look like but I’m still not sure of the procedure to follow. Could someone briefly explain to me the steps for creating a custom message in MAVlink and the ways to implement this in the ground station and the flight controller.
Thank you


Hello, year ago I tried to get some data to arduplane and send it to gcs. Mainly I was referring to

How I did it.

  1. We should change firmware for our drone.
    Download source code, and add your msg to mavlink message definitions

     <message id="227" name="TEST_INFO">
         <description>Test Info</description>
         <field name="test_temp1" type="float">Temp1</field>
         <field name="test_temp2" type="float">Temp2</field>
         <field name="test_voltage" type="float">Voltage</field>
         <field name="test_rpm" type="float">RPM</field>

Choose ID according to notes in this xml file.

Build firmware, so we mavlink will be updated with our message.

Open Plane.h and add variables for this new msg.

// Test vars
float temp1;
float temp2
float volt1;
float rpm1;

Lets modify GCS_Mavlink.cpp, in order to send our new msg.

I added it to the end of function

 void Plane::send_extended_status1(mavlink_channel_t chan)
 // sending our msg

Somewhere You should make handler of your data.

  1. Change code of GCS.

I modified Mission Planner. First, You should change mavlink too. Add the same message to


Then update mavlink via running regenerate.bat.
Now we should see definetion of our message in Mavlink.cs

Lets add our data to “status” tab in Flight Data window.

Open and modify CurrentState.cs

 public class Mavlink_Sensors

Add new variables for our msg.

 // Test Info 
 public float test_temp1 { get; set; }
 public float test_temp2 { get; set; }
 public float test_voltage { get; set; }
 public float test_rpm { get; set; }

Now we should parse and output our data, look at

public void UpdateCurrentSettings(System.Windows.Forms.BindingSource bs, bool updatenow, MAVLinkInterface mavinterface, MAVState MAV)

And add something like that

mavLinkMessage = MAV.getPacket((uint) MAVLink.MAVLINK_MSG_ID.TEST_INFO);

if (mavLinkMessage != null) 
                    var aero = mavLinkMessage.ToStructure<MAVLink.mavlink_test_info_t>();

                    test_temp1 = (float) (aero.test_temp1);
                    test_temp2 = (float) (aero.test_temp2);
                    test_voltage = (float) (aero.test_voltage);
                    test_rpm = (float) (aero.test_rpm);

After that I made new window and outputted this data how I wanted.

label1.Text = MainV2.comPort.MAV.cs.test_rpm.ToString("R");

I hoped that can help you a little.


Thank you Nikita for your quick reply!
This sure did help me but I’m still stuck with a few doubts. I Guess if I explain my use case it would be easier to answer my doubts. I want to create a permission checker on the flight controller such that only a verified PIN can allow the flight controller to arm.
So, for this I’ll include the xml message in common.xml.
Then as per your instructions I will build the new firmware. After this I can make required additions in the copter.h file, as I’m using a copter and then modify GCS_Mavlink.cpp? I want to verify if this is the right procedure to be followed on flight controller. Also, the function to check if PIN is accepted can be included in GCS_Mavlink.cpp?
Very sorry if these are silly questions. I’m an absolute beginner in this.
Thank you

I made new file, something like
test_check.cpp in ArduPlane folder.
Wrote my handler of the sensor.

void Plane::test_sensor()

Then added this new handler inside scheduler in ArduPlane.cpp

SCHED_TASK(aerostart_engine_sensor, 5,   1500),

Add our function to Plane.h

Add it inside

class Plane : public AP_HAL::HAL::Callbacks {

At the end of private functions.
If I’m not mistaken that’s all that I did.

Hi @Nikita
Could you please explain how you received messages from the Autopilot and then send it to the GCS?
I need to do this and you can help me a lot. I appreciate it.

Hello, everything is stated above, I dont know what can add to that.


Hi, just read through your post and was really curious whether you were able to implement that functionality. I am trying to do the same but haven’t been able to get the message sending part on GCS_MAVLINK.cpp to work.


this is the most helpful post response I’ve seen for creating custom messages to this date! Thank you for this!

I had a question about how your sensor was configured. Was it mounted directly to the flight controller or did you have it go through a companion computer? I ask because my sensor’s data is formatted as ASCII and fed through the companion computer pi at a rate of 1Hz. And im still trying to figure out how to get the data to GCS.

I dont really remember, anyway that was custom board on fmuv3, i think that can-bus was used. so i had to add uavcan msg too, lol.

Hello Nikita
I connected arduino to pixhawk to add new sensors to it, and I want just to see the data in mission planner. I generated the arduino custom library.
in mission planner side, I changed the common.xml file and add the message number 187 to it and regenerate.bat and build the missionplanner.sln in visual studio.
but the message number 187 doesn’t shown in mavlink inspector of mission planner.
when I change it to an existing msgid, like 29 (scaled pressure), it apppears. where is my mistake?

just for continuity sake, after updating the XML files in both Ardupilot AND mission planner, will we be able to see our message in the Mavlink Inspector? The tutorial does not mention modifying the Mission Planner XML, so it’s a bit confusing.