Hi All,

I was recently fiddling around the code for a while and decided to create a tutorial out of it so that others may find it useful. If I would have known this knowledge long back, I am sure I would have saved a lot of time since then! I find lot of beginners getting swayed and lack of knowhow on MavLink with respect to APM/PX4. Information on internet is scattered and not much of use!! 

This will be "Step by Step" entertaining, PART - I of the series I plan to write.on:


What it Covers:

  1. MavLink, starting from scratch. What the hell is it and understand how it works with APM/ PX4
  2. Learn how developers think -> Arducopter communication with Mission Planner and vice-versa.
  3. Get a feel of 'How Stuffs works'.

Too much hype:) Well, this information has been collated from my experience and from internet. I know there is information on the new Wiki, it tells you what, I plan to tell you 'how'! :)

Please let me know if you found it interesting. If there is enough response, I will make another tutorial where I would add more 'Step by step' knowhow!!


- More on MavLink

- Learning Arducopter source code, Step by Step

- Making swarm (multiple) copters work with your 3DR Telemetry radio! I am working on it.

See attachment for [MAVLink Tutorial for Absolute Dummies (Part –I)]

Edit: Request you to post your queries over the forum directly, as it is not possible for me to address all queries I get by email!


Best regards,



You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –


  • Hi Shyam,

    Thank you for sharing. I would like know how it's done. I am planning to send the message directly from one pixhawk to another pixhawk using telemetry. I have been studying the code for weeks but there are still things that I don't understand. I hope you could help me clear my doubts.

    there is this function in the GCS_Common.cpp file

    GCS_MAVLINK::update(void (*run_cli)(AP_HAL::UARTDriver *))
    // receive new packets
    mavlink_message_t msg;
    mavlink_status_t status;
    status.packet_rx_drop_count = 0;

    // process received bytes
    uint16_t nbytes = comm_get_available(chan);



    I would like to know how this "chan" is switched. As I know, the uartA and uartC are updated using the following function

    static void gcs_check_input(void)
         for (uint8_t i=0; i<num_gcs; i++) {
              if (gcs[i].initialised) {

    From what I understand, correct me if i am wrong, gcs[0], gcs[1], gcs[2] use the same GCS_MAVLINK::update function. Since this GCS_MAVLINK::update function just calls the  "chan" variable and does not modify the "chan". I wonder if the chan in the function comm_get_available(chan) corresponds to MAVLINK_COMM_0 for gcs[0].update() and MAVLINK_COMM_1 for gcs[1].update(). Is there any function that I may have missed out that switches the value of the chan between MAVLINK_COMM_0 and MAVLINK_COMM_1

  • Thank you! Scattered info has kept me from fiddling with the code for a long time. This is really neat tutorial. Anything else you want to cover will be greatly appreciated. Personally, I can't wait for the step by step source code guide.

  • Thanks! This is a huge help for me. Well done!

  • Hi Shyam,

    Absolutely great tutorial.

    Would you mind if I put a copy of your PDF (and future ones) on my Drones Are Fun site for people to link directly to from there?

    Best Regards,


    • Hi Gary,

      Sure, please go ahead!!



  • Hi Shyam ......

    thank you for the great tutorial. It helps me understand mavlink very quickly and in a efficient way. 

    I actually have some project dealing with mavlink. my project is to measure the radio quality of the RFD 900 (http://rfdesign.com.au/index.php/rfd900). To test this device and in order to have the rssi (received signal strenght indication) signal report, i need to communicate two RFD 900 and use the mavlink message number  #109 RADIO_STATUS on https://pixhawk.ethz.ch/mavlink/.

    In order to do so, i thought about this simple architecture,  i need one system (a GCS) on one side where there is one RFD 900 plugged in and ......one system (autopilot) where the second RFD 900 is plugged in. And i want them to be connected and to exchange data (in the beginning, just a simple text).

    So far, i use the MavProxy (http://tridge.github.io/MAVProxy/) on the GCS side ( i can also use QGroundControl) and it works perfectly. I was able to receive data when i use the 3DR/RFD900 compatible configuration tool on the other side (i mean by that the other rfd 900) : http://vps.oborne.me/3drradioconfig.zip 

    Now, my problem is on the autopilot side. Actually, i've not any autopilot available right now ( because i just want to measure the radio quality of the RFD 900  modem and then include it  into my autopilot depending on the radio quality measure result. That would be the next step), how can i possibly simulate an autopilot on my computer (i run on ubuntu 14.04) ?. Is there a way that i used the code on this post (http://qgroundcontrol.org/dev/mavlink_arduino_integration_tutorial) but without a true autopilot but just send a message mavlink over the RFD 900 and then receive it on my linux. 

    I'm thinking about creating a thread or somekind of process to receive and to send data mavlink on the other side, to emulate an autopilot but this is not easy at all :)

    Last question. i've read that you have tested the code on this tutorial:  http://qgroundcontrol.org/dev/mavlink_arduino_integration_tutorial

    how did you manage to compile it because i've got some errors. From what i understand, it is on the autopilot side (because on the GCS side, all is already set with the software). So what is the prerequisite before compiling this code ?

    Thank you Shyam . 

  • Thank you very very much,

  • Mr. Shyam,

    Thanks for this amazing contribution. Interesting and very instructive. Keep on!

    • @Quadzimodo and @Anderl,

      Glad it was useful to you guys. Thank you for your feedback.



  • Wonderful! Thank you so much.  I look forward to learning more.

This reply was deleted.