Understanding the Arduino Mavlink library

Understanding the Arduino Mavlink library

Connecting an Arduino to a Pixhawk:
See: https://discuss.ardupilot.org/t/mavlink-and-arduino-step-by-step/25566

Intermittent serial communication with Pixhawk (ig. only get console output when you put your finger on the pin header on the pixhawk)?
Set BRD_SER1_RTSCTS and BRD_SER2_RTSCTS in your Pixhawk to a value of 0 (No flow control).

Download the Arduino Mavlink library:

Sending data (a request) to the Pixhawk

After importing the library into the Arduino IDE, the Mavlink library contains all the files you would need to perform various functions on a Pixhawk, APM, or other Ardupilot based hardware using Mavlink commands.

For example, just say you want to request GPS data from the Pixhawk so you can handle them as variables on the Arduino:

To do this, you’ll navigate to the common directory and search for the relevant file. The files are all titled accordingly, so it aids in finding the correct one to open in order to see the message definitions, variable types, and arguments you’ll need to provide to your code. You will then cross reference this file with the list of messages listed at the Mavlink Developer Guide (https://mavlink.io/en/messages/common.html), and see if the command does what you want it to do. The guide also lists out the parameters required for the message, but you may need to do a few more google searches to see if the command is part of a larger protocol which needs other requirements to be met before it can be implemented (ig. uploading a full mission).

As I previously mentioned, I want to request a data stream to read GPS info from the Pixhawk, therefore I go to the common directory and look for a file which tells me that it can do such a thing. In the above image, request_data_stream.h seems to be the ticket.

**Note** the files in the library allow for bidirectional Mavlink communication…When you open the files and peek inside, you will be confronted with code used both to SEND and RECEIVE Mavlink commands. This can be quite confusing at first (it was for me!).

Inside the mavlink_msg_request_data_stream.h file:

Inside the mavlink_msg_request_data_stream.h file you’ll immediately see the struct which assigns data to variables in the event you wished to read data from the Pixhawk. You wont need this for our purposes just yet.

Further down, you’ll see a line containing something called mavlink_msg_request_data_stream_pack:

This is the line you want to pay attention to as “pack” means you are handling the data to be sent out (which we are hoping to do, so we can pack the data and (later on in the function) send it to the autopilot.

The important thing to understand is that the static inline statement above defines the data which we will want to put into the pack function, and we need to specify those values in order for the autopilot to know what we want and how we want it.

Lets break it down…

So lets break down the static inline statement shown above starting from the first variable right after the ‘(‘ symbol.

The ‘uint8_t’ defines the type of data in the variable next to it. So uint8_t system_id is asking for a type of unsigned integer of 8 bits long under the system_id variable. Like-wise for all the other variables in the static inline statement. We now just need to provide the appropriate data to populate the variables in the correct order specified in the statement for the library to pack the message in a Mavlink compatible command.

In Arduino code, it would look like this:

You dont need to specify any variables like I did at the top of the sketch if you do not wish to, and instead just write them directly into the mavlink_msg_request_data_stream_pack() statement. Variables were defined to further aid in understanding how things work in the function.

Sent. But, what about receive?

The above function will send a request to the Pixhawk requesting the MAV_DATA_STREAM_ALL stream (which sends ALL streams) to be broadcast on the connected serial port once every second. We also know that the Arduino Mavlink library files allow both sending and receiving of Mavlink commands. Armed with this knowledge, we need to find a file which allows us to receive and process the data we requested. Looking at the information from https://mavlink.io/en/messages/common.html#MAV_DATA_STREAM we can see that 0-12 show the different sensor data which is broadcast by enabling all streams (1-6 shows the individual streams that can be enabled).

Since we know that the GPS streams are included in the MAV_DATA_STREAM_ALL we can be safe in assuming we can grab the GPS_RAW stream data by enabling all streams.

Navigating back to our common folder, we take a look around and low and behold, we see a mavlink_msg_gps_raw_int.h file which looks like it will do just what we want! So lets go ahead and open the file and see if it will give us enough information for us to grab GPS variables.

At the beginning of the file, we once again see the familiar typedef struct which defines variables to handle the GPS data that we may want to process. How convenient! Now how exactly do we use these variables? In the same file, one just needs to scroll down a bit till we find the ‘decode’ statement. This statement allows (much like the the pack statement we just went through) one to write an expression handling the variables to decode from a message being sent by the Pixhawk.

We see that after the ‘mavlink_msg_gps_raw_int_decode(‘ two variables are given which informs us we need to specify two variables to grab that data. We will then need to use the typedef struct at the beginning of the file to find the variables we can use to pull the data from the stream being sent by the Pixhawk.

An example looks like this:

Putting the Send and Receive function together

Now that we’ve covered both the send and receive functions. Lets put them together to watch them in action:

Here is what the serial console output looks like from the sketch above (GPS coordinates masked for privacy):

You now have a working send and receive sketch which will request a datastream from the Pixhawk and allow the Arduino to process the response. Note that after you request a datastream, the Pixhawk will continue sending that data at the rate which was specified in the expression. Its a good idea to stop the stream once you’ve gotten the desired data as it may interfere with uploading new flight plans to the Pixhawk.