MAVLink and Arduino: step by step

Actually, if you have a look at the code in my GitHub - pauljeffress/Pulsar-MAVLink-Tester there are a number of MISSION options towards the bottom of the menu that set a bunch of waypoints. You could reuse that code but inject your own waypoints etc. I have tested it and it has proven reliable. There may be better ways or more efficient ways, but this is a start.

Hey I hope here is someone who can help me. I currently have the problem that in my MavLink Inspector in the MissionPlanner two vehicles (or 3 if you include the MissionPlanner as GCS) appear. Vehicle 1 has the Comp 0 Mav_COMP_ID_ALL. There is only one heartbeat included, which I can’t do anything with. However, my data are in Vehicle 2 in the Comp 1 MAV_COMP_ID_AUTOPILOT1. However, nothing happens when requesting the data stream from System 2 and Component 1. I always get only the data (only one heartbeat) from Vehicle 1!
If I send a heartbeat myself, it shows up in the MavLink Inspector with the corresponding System ID and Component ID, so my Pixhawk seems to receive Tx data from the Arduino as Rx. All baudrates are set correctly.

Does anyone have any ideas what else I could try or what this could be due to?

Hi Christian,
I’d love to help, but first ca you clarify what your setup is? Whats connected to what. Please mark what SysID and what CompID you have on each MAVLink speaking device.
Even a photo or two is helpful sometimes.
Thanks,
Paul

Hey, thanks for your reply and sorry for my late reply, unfortunately I could not do anything about this the last few days.

The setup is that I want to communicate over the Serial1 TX and RX of an Arduino Mega using the Telemetry 2 port of the Pixhawk.
My Arduino has the System ID 3 and Component ID 5 (theoretically everything should be possible, as long as nothing is duplicated with other IDs, right?).
In the MissionPlanner 2 vehicles appear as said. Vehicle 1 has only one heartbeat (which I can read and decode with the Arduino like HEARTBEAT.autopilot = 8). Vehicle 2 has all the data I want to access (e.g. GPS). The picture shows a section from the Mission Planner regarding the Vehicles.

The code is identical to the example. However, the Pixhawk does not seem to respond to my requests that I want to receive the data stream from Vehicle 2 (Sys ID 2 and Comp ID 1).

Do you have any idea what this could be? I have checked all connections several times and reinstalled the library several times.

Hello @pauljeff it’s me again. I’m still trying to set a mission waypoint but have no luck so far. I already saw your project on github but I still don’t understand the plataformio structure.
I made the following code based on yours and jplopez’s ones, but it doesn’t work, can you help me figure out what may be wrong?
Thanks!

#include "Arduino.h"
#include <ardupilotmega/mavlink.h> 



// Mavlink variables
unsigned long previousMillisMAVLink = 0;     // will store last time MAVLink was transmitted and listened
unsigned long next_interval_MAVLink = 1000;  // next interval to count
const int num_hbs = 10;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

uint8_t sysid = 1;
uint8_t compid = 100;
uint8_t dsysid = 1;
uint8_t dcompid = 1;
uint8_t type = MAV_TYPE_QUADROTOR;
uint8_t system_type = MAV_TYPE_GENERIC;
uint8_t autopilot_type = MAV_AUTOPILOT_INVALID;
uint8_t system_mode = MAV_MODE_PREFLIGHT; ///< Booting up
uint32_t custom_mode = 0;                 ///< Custom mode, can be defined by user/adopter
uint8_t system_state = MAV_STATE_STANDBY; ///< System ready for flight

uint8_t we_got_expected_packet = true;
void heart_beat();
void send_mission_count();
void receive_mission_request();
void send_mission_item_int();


void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial1.begin(57600);
  delay(10000);
}

//timing
void loop() {
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    previousMillisMAVLink = currentMillisMAVLink;
    heart_beat();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      send_mission_count();
      uint8_t count_requests = 0;
      while (count_requests <= 20){
      receive_mission_request();
      count_requests++;
      }
      if (we_got_expected_packet == true){
      send_mission_item_int();
      }
      num_hbs_pasados = 0;
    }
  }
//  receive_comm();
}


void heart_beat()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_heartbeat_pack(sysid,compid, &msg, type, autopilot_type, system_mode, custom_mode, system_state);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
}


void send_mission_count()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_count_pack(sysid,compid, &msg, dsysid, dcompid, 1);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
  Serial.println("send_mission_count finished");
}


void receive_mission_request()
{
  // Message variables
  mavlink_message_t msg;
  mavlink_status_t status;

  // Message receive
  while (Serial1.available() > 0) {
    // Store received char
    uint8_t c = Serial1.read();

    // Check integrity of stored char
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      Serial.print("lol");

      // what to do depend on msgid
      switch(msg.msgid) {
        case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
          {
          // Extract the acknowledgement status from the message
          mavlink_mission_request_t packet;
          mavlink_msg_mission_request_decode(&msg, &packet);
          Serial.print(packet.target_system);
          Serial.print(" target_component:");
          Serial.print(packet.target_component);
          Serial.print(" seq:");
          Serial.println(packet.seq);
          we_got_expected_packet = true;
          }
          break;
      }
    }
  }
  Serial.println("receive_mission_request finished");
} 

void send_mission_item_int()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buffer[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(sysid, compid, &msg, dsysid, dcompid, 0, MAV_FRAME_GLOBAL, MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, -33.4931104, -70.6280565, 0);
  

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buffer, &msg);

  // Send message
  Serial1.write(buffer, len);
}

/*void receive_comm() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (Serial1.available() > 0) {
    uint8_t c = Serial1.read();
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      switch(msg.msgid) {


        case MAVLINK_MSG_ID_HEARTBEAT:
          {
          Serial.println("FC HB");
          }
          break;


        default:
          Serial.print("--- Otros: ");
          Serial.print("[ID: ");
          Serial.print(msg.msgid);
          Serial.print("], [seq: ");
          Serial.print(msg.seq);
          Serial.println("]");
          break;
  
      }
    }
  }
} 
*/

I am not able to receive MAVLINK_MSG_ID_MISSION_REQUEST_INT

Here is my last attempt but still not working

#include "Arduino.h"
#include <ardupilotmega/mavlink.h> 



// Mavlink variables
unsigned long previousMillisMAVLink = 0;     // will store last time MAVLink was transmitted and listened
unsigned long next_interval_MAVLink = 1000;  // next interval to count
const int num_hbs = 1;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

uint8_t sysid = 1;
uint8_t compid = 100;
uint8_t dsysid = 1;
uint8_t dcompid = 1;
uint8_t type = MAV_TYPE_QUADROTOR;
uint8_t system_type = MAV_TYPE_GENERIC;
uint8_t autopilot_type = MAV_AUTOPILOT_INVALID;
uint8_t system_mode = MAV_MODE_PREFLIGHT; ///< Booting up
uint32_t custom_mode = 0;                 ///< Custom mode, can be defined by user/adopter
uint8_t system_state = MAV_STATE_STANDBY; ///< System ready for flight

uint8_t we_got_expected_packet = false;
uint8_t count_requests = 0;

void heart_beat();
void send_mission_count();
void receive_mission_request();
void send_mission_item_int();


void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial1.begin(57600);
  delay(10000);
}

//timing
void loop() {
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    previousMillisMAVLink = currentMillisMAVLink;
    heart_beat();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      if(count_requests <= 1){
        send_mission_count();
      }
      if(count_requests >= 1){
        receive_mission_request();
      }
      if(count_requests >= 5){
        count_requests = 0;
      }
      if (we_got_expected_packet == true){
      send_mission_item_int();
      }
      num_hbs_pasados = 0;
      count_requests++;
    }
  }
//  receive_comm();
}


void heart_beat()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_heartbeat_pack(sysid,compid, &msg, type, autopilot_type, system_mode, custom_mode, system_state);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
  Serial.println("HB sended");
}


void send_mission_count()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_count_pack(sysid,compid, &msg, dsysid, dcompid, 1);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
  Serial.println("send_mission_count finished");
}


void receive_mission_request()
{
  // Message variables
  mavlink_message_t msg;
  mavlink_status_t status;
  bool gotFullMsg = false;

  // Message receive
  while (Serial1.available() && !gotFullMsg) {
    // Store received char
    uint8_t c = Serial1.read();

    // Check integrity of stored char
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      gotFullMsg = true;

      // what to do depend on msgid
      switch(msg.msgid) {
        case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
          {
          // Extract the acknowledgement status from the message
          mavlink_mission_request_t packet;
          mavlink_msg_mission_request_decode(&msg, &packet);
          Serial.print(packet.target_system);
          Serial.print(" target_component:");
          Serial.print(packet.target_component);
          Serial.print(" seq:");
          Serial.println(packet.seq);
          we_got_expected_packet = true;
          }
          break;
        default:
          Serial.print("--- Otros: ");
          Serial.print("[ID: ");
          Serial.print(msg.msgid);
          Serial.print("], [seq: ");
          Serial.print(msg.seq);
          Serial.println("]");
          break;
      }
    }
  }
  Serial.println("receive_mission_request finished");
} 

void send_mission_item_int()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buffer[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(sysid, compid, &msg, dsysid, dcompid, 0, MAV_FRAME_GLOBAL, MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, -33.4931104, -70.6280565, 0);
  

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buffer, &msg);

  // Send message
  Serial1.write(buffer, len);
  Serial.println("send_mission_item_int finished");
}

/*void receive_comm() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (Serial1.available() > 0) {
    uint8_t c = Serial1.read();
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      switch(msg.msgid) {


        case MAVLINK_MSG_ID_HEARTBEAT:
          {
          Serial.println("FC HB");
          }
          break;


        default:
          Serial.print("--- Otros: ");
          Serial.print("[ID: ");
          Serial.print(msg.msgid);
          Serial.print("], [seq: ");
          Serial.print(msg.seq);
          Serial.println("]");
          break;
  
      }
    }
  }
} 
*/

And this is what i get in the serial port

Here is my closest attemp, but still no working

#include "Arduino.h"
#include <ardupilotmega/mavlink.h> 



// Mavlink variables
unsigned long previousMillisMAVLink = 0;     // will store last time MAVLink was transmitted and listened
unsigned long next_interval_MAVLink = 1000;  // next interval to count
const int num_hbs = 1;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

uint8_t sysid = 1;
uint8_t compid = 100;
uint8_t dsysid = 1;
uint8_t dcompid = 1;
uint8_t type = MAV_TYPE_QUADROTOR;
uint8_t system_type = MAV_TYPE_GENERIC;
uint8_t autopilot_type = MAV_AUTOPILOT_INVALID;
uint8_t system_mode = MAV_MODE_PREFLIGHT; ///< Booting up
uint32_t custom_mode = 0;                 ///< Custom mode, can be defined by user/adopter
uint8_t system_state = MAV_STATE_STANDBY; ///< System ready for flight

uint8_t we_got_expected_packet = false;
uint8_t count_requests = 0;

void heart_beat();
void send_mission_count();
void receive_mission_request();
void send_mission_item_int();


void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial1.begin(57600);
  delay(1000);
}

//timing
void loop() {
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    previousMillisMAVLink = currentMillisMAVLink;
    heart_beat();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      if(count_requests <= 1){
        send_mission_count();
      }
      if(count_requests >= 5){
        count_requests = 0;
      }
      if (we_got_expected_packet == true){
      send_mission_item_int();
      }
      num_hbs_pasados = 0;
      count_requests++;
    }
  }
 receive_mission_request();
}


void heart_beat()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_heartbeat_pack(sysid,compid, &msg, type, autopilot_type, system_mode, custom_mode, system_state);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
  Serial.println("HB sended");
}


void send_mission_count()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_count_pack(sysid,compid, &msg, dsysid, dcompid, 1);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);

  // Send message
  Serial1.write(buf, len);
  Serial.println("send_mission_count finished");
}


void receive_mission_request()
{
  // Message variables
  mavlink_message_t msg;
  mavlink_status_t status;
  bool gotFullMsg = false;

  // Message receive
  while (Serial1.available() && !gotFullMsg) {
    // Store received char
    uint8_t c = Serial1.read();

    // Check integrity of stored char
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      gotFullMsg = true;

      // what to do depend on msgid
      switch(msg.msgid) {
        case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
          {
          // Extract the acknowledgement status from the message
          mavlink_mission_request_t packet;
          mavlink_msg_mission_request_decode(&msg, &packet);
          Serial.print(packet.target_system);
          Serial.print(" target_component:");
          Serial.print(packet.target_component);
          Serial.print(" seq:");
          Serial.println(packet.seq);
          we_got_expected_packet = true;
          }
          break;
        default:
          Serial.print("--- Otros: ");
          Serial.print("[ID: ");
          Serial.print(msg.msgid);
          Serial.print("], [seq: ");
          Serial.print(msg.seq);
          Serial.println("]");
          break;
      }
    }
  }
} 

void send_mission_item_int()
{
  // Message variables
  mavlink_message_t msg;
  uint8_t buffer[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(sysid, compid, &msg, dsysid, dcompid, 0, MAV_FRAME_GLOBAL, MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, -33.4931104, -70.6280565, 0);
  

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buffer, &msg);

  // Send message
  Serial1.write(buffer, len);
  Serial.println("send_mission_item_int finished");
}

/*void receive_comm() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (Serial1.available() > 0) {
    uint8_t c = Serial1.read();
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)){
      switch(msg.msgid) {


        case MAVLINK_MSG_ID_HEARTBEAT:
          {
          Serial.println("FC HB");
          }
          break;


        default:
          Serial.print("--- Otros: ");
          Serial.print("[ID: ");
          Serial.print(msg.msgid);
          Serial.print("], [seq: ");
          Serial.print(msg.seq);
          Serial.println("]");
          break;
  
      }
    }
  }
} 
*/

And my serial monitor

As you can see i am not receiving MAVLINK_MSG_ID_MISSION_REQUEST_INT msg

Reading paul code i found ardupilot was sending MAVLINK_MSG_ID_MISSION_REQUEST and not MAVLINK_MSG_ID_MISSION_REQUEST_INT, as you can see in my serial monitor i was receiving ID:40 so i changed it, also added another waypoint becausa ardupilot uses the first waypoint as home, so fixing that 2 things y was finally able to set waypoint, hope this information is going to be helpful to someone.

Hello,

I have connected the GPS1 port of cube orange to Serial2 port of arduino.

I enabled serial3 in mission planner for mavlink2 protocol and set baud rate as 57600.

I’m trying to read some messages through the program available like GPS and IMU information.

However, I’m not able to get any messages. PFA of the arduino code I’m using. Any help or guidance will be really helpful.

It is able to enter the Serial2.available() ? condition, but the immediate if statement after that never gets executed.

#include <mavlink.h>
//#include <SoftwareSerial.h>

//#define RXpin 0
//#define TXpin 1
//SoftwareSerial SerialMAV(RXpin, TXpin); // sets up serial communication on pins 3 and 2

void setup() {
Serial2.begin(57600); //RXTX from Pixhawk (Port 19,18 Arduino Mega)
Serial.begin(115200); //Main serial port for console output

request_datastream();

}

void loop() {

MavLink_receive();

}

//function called by arduino to read any MAVlink messages sent by serial communication from flight controller to arduino
void MavLink_receive()
{
mavlink_message_t msg;
mavlink_status_t status;

while(Serial2.available())
{Serial.println(“Serial port available”);
uint8_t c= Serial2.read();
Serial.println(c);
//Get new message
if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
{

//Handle new message from autopilot
  switch(msg.msgid)
  {

    case MAVLINK_MSG_ID_GPS_RAW_INT:
  {
    mavlink_gps_raw_int_t packet;
    mavlink_msg_gps_raw_int_decode(&msg, &packet);
    
    Serial.print("\nGPS Fix: ");Serial.println(packet.fix_type);
    Serial.print("GPS Latitude: ");Serial.println(packet.lat);
    Serial.print("GPS Longitude: ");Serial.println(packet.lon);
    Serial.print("GPS Speed: ");Serial.println(packet.vel);
    Serial.print("Sats Visible: ");Serial.println(packet.satellites_visible);
   
  }
  break;

  }
}

}
}

void request_datastream() {
//Request Data from Pixhawk
uint8_t _system_id = 255; // id of computer which is sending the command (ground control software has id of 255)
uint8_t _component_id = 2; // seems like it can be any # except the number of what Pixhawk sys_id is
uint8_t _target_system = 1; // Id # of Pixhawk (should be 1)
uint8_t _target_component = 0; // Target component, 0 = all (seems to work with 0 or 1
uint8_t _req_stream_id = MAV_DATA_STREAM_ALL;
uint16_t _req_message_rate = 0x01; //number of times per second to request the data in hex
uint8_t _start_stop = 1; //1 = start, 0 = stop

// STREAMS that can be requested
/*

  • Definitions are in common.h: enum MAV_DATA_STREAM and more importantly at:
    Messages (common) · MAVLink Developer Guide
  • MAV_DATA_STREAM_ALL=0, // Enable all data streams
  • MAV_DATA_STREAM_RAW_SENSORS=1, /* Enable IMU_RAW, GPS_RAW, GPS_STATUS packets.
  • MAV_DATA_STREAM_EXTENDED_STATUS=2, /* Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS
  • MAV_DATA_STREAM_RC_CHANNELS=3, /* Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
  • MAV_DATA_STREAM_RAW_CONTROLLER=4, /* Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT.
  • MAV_DATA_STREAM_POSITION=6, /* Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages.
  • MAV_DATA_STREAM_EXTRA1=10, /* Dependent on the autopilot
  • MAV_DATA_STREAM_EXTRA2=11, /* Dependent on the autopilot
  • MAV_DATA_STREAM_EXTRA3=12, /* Dependent on the autopilot
  • MAV_DATA_STREAM_ENUM_END=13,
  • Data in PixHawk available in:
    • Battery, amperage and voltage (SYS_STATUS) in MAV_DATA_STREAM_EXTENDED_STATUS
    • Gyro info (IMU_SCALED) in MAV_DATA_STREAM_EXTRA1
      */

// Initialize the required buffers
mavlink_message_t msg;
uint8_t buf[MAVLINK_MAX_PACKET_LEN];

// Pack the message
mavlink_msg_request_data_stream_pack(_system_id, _component_id, &msg, _target_system, _target_component, _req_stream_id, _req_message_rate, _start_stop);
uint16_t len = mavlink_msg_to_send_buffer(buf, &msg); // Send the message (.write sends as bytes)

Serial2.write(buf, len); //Write data to serial port
}

Hi @hemanth_narayan,
Welcome to the chat :slight_smile:
I just had a quick look at your code and I think you are setting the systemIDs and componentIDs incorrectly.
Try the following
// Arduino sysID and compID
uint8_t sysid = 1;
uint8_t compid = 100;
// Target autopilot sysID and compID
uint8_t dsysid = 1;
uint8_t dcompid = 1;

And let us know if that helps.
Thanks,
Paul

Hello,

Thanks for the reply. I made the changes but still facing the same issues. mavlink_parse_char if statement seems to return 0 all the time.

I’m using Arduino Mega. Please let me know if you need more information.

Right now I’m connecting the GND, RX, and TX pin from the GPS1 port to the GND TX, and RX pin of Arduino. Should I connect the 5V from Arduino to the VCC pin as well?

Hello,

Today, I connected the Arduino with GPS2 ports in cube orange and ran the below attached program. There is an improvement, I’m able to enter the if statement containing mav_parse_char(), however, the switch case statement is not getting executed. Please let me know if I could do anything different.

#include <mavlink.h>

void setup() {
// put your setup code here, to run once:
Serial2.begin(57600); //for pixhawk to arduino
//Serial2.begin(115200); // for arduino-myrio

Serial.begin(115200); //monitor

request_datastream();
}

void loop() {
//Serial.println(“Started”);
MavLink_receive();
delay(1000);
}

void MavLink_receive()
{
//Serial.println(“Entered mavlink recieve”);
mavlink_message_t msg;
mavlink_status_t status;

while(Serial2.available())
{ //Serial.println(“mavlink available”);
uint8_t c= Serial2.read();
//Serial.println(c);
//Get new message
if(mavlink_parse_char(MAVLINK_COMM_3, c, &msg, &status))
{ Serial.println(“Entered if statement”);
mavlink_gps_raw_int_t packet;
mavlink_msg_gps_raw_int_decode(&msg, &packet);
//Serial.println(“In the switch case”);
//Serial.print("GPS Latitude: ");Serial.println(packet.lat);
//Serial.print("GPS Longitude: ");Serial.println(packet.lon);
//Serial.print("GPS Speed: ");Serial.println(packet.vel);
//Serial.print("Sats Visible: ");Serial.println(packet.satellites_visible);
//Serial.println(msg.msgid);
//Handle new message from autopilot
switch(msg.msgid)
{

    case MAVLINK_MSG_ID_GPS_RAW_INT:
  {
    mavlink_gps_raw_int_t packet;
    mavlink_msg_gps_raw_int_decode(&msg, &packet);
    Serial.println("In the switch case");
    Serial.print("GPS Latitude: ");Serial.println(packet.lat);
    Serial.print("GPS Longitude: ");Serial.println(packet.lon);
    Serial.print("GPS Speed: ");Serial.println(packet.vel);
    Serial.print("Sats Visible: ");Serial.println(packet.satellites_visible);

    //Serial2.print("GPS Latitude: ");Serial2.println(packet.lat);

   
  }
  break;

  }
}

}
}

void request_datastream() {
Serial.println(“Entered datastream”);
//Request Data from Pixhawk
uint8_t _system_id = 1; // id of computer which is sending the command (ground control software has id of 255)
uint8_t _component_id = 100; // seems like it can be any # except the number of what Pixhawk sys_id is
uint8_t _target_system = 1; // Id # of Pixhawk (should be 1)
uint8_t _target_component = 1; // Target component, 0 = all (seems to work with 0 or 1
uint8_t _req_stream_id = MAV_DATA_STREAM_ALL;
uint16_t _req_message_rate = 0x01; //number of times per second to request the data in hex
uint8_t _start_stop = 1; //1 = start, 0 = stop

// Initialize the required buffers
mavlink_message_t msg;
uint8_t buf[MAVLINK_MAX_PACKET_LEN];

// Pack the message
mavlink_msg_request_data_stream_pack(_system_id, _component_id, &msg, _target_system, _target_component, _req_stream_id, _req_message_rate, _start_stop);
uint16_t len = mavlink_msg_to_send_buffer(buf, &msg); // Send the message (.write sends as bytes)
//Serial.println(_req_stream_id);
Serial2.write(buf, len); //Write data to serial port

}

Hi @hemanth_narayan ,
Your wiring sounds correct. You only need to, RX and ground. Do not connect 5v/Vcc.

@hemanth_narayan there are a couple of things I think you should try.

  1. Recheck that you have setup the setup the AutoPilot port correctly, and also try it set for MAVLink version 1 to see if that helps.
  2. Add the following code just inside your “ if (mavlink_parse_char(….” IF statement.

Serial.println(“MSG RCVD -”);
Serial.print(" magic:“);
Serial.println(msg.magic);
Serial.print(” seq:“);
Serial.println(msg.seq);
Serial.print(” sysid:“);
Serial.println(msg.sysid);
Serial.print(” compid:“);
Serial.println(msg.compid);
Serial.print(” msgid#:");
Serial.println(msg.msgid);

That will show a bit about each MAVLink message you have received. For example if the msgid = 0 then thats a HEARTBEAT. You can lookup all of the msgids on the MAVLink.io documentation pages.

I suspect that what you will find is that you are receiving valid MAVLink packets from your AutoPilot, but your code is only setup to decode MAVLINK_MSG_ID_GPS_RAW_INT messages. And the AutoPilot may not be sending any of those.
Try adding code to decode the HEARTBEAT messages, you should pretty much always see those.
Good luck,
Paul

Here is an example of the code you can use to decode MAVLink HEARTBEAT messages;

case MAVLINK_MSG_ID_HEARTBEAT: // #0 Messages (common) · MAVLink Developer Guide
{
mavlink_heartbeat_t hb; mavlink_msg_heartbeat_decode(&msg, &hb);
Serial.println(“HEARTBEAT”);
Serial.print(" Type:“);
Serial.print(hb.type);
Serial.print(” APclass:“);
Serial.print(hb.autopilot);
Serial.print(” BaseMode:“);
Serial.print(hb.base_mode);
if ((hb.base_mode == 1) || (hb.base_mode == 65)) // Complete Parameter List — Rover documentation
Serial.print( " DISarmed”);
if ((hb.base_mode == 129) || (hb.base_mode == 193))
Serial.print( " !!ARMED!!“);
Serial.print(” Custom/Flightmode:“);
Serial.print(hb.custom_mode);
if (hb.custom_mode == 0)
Serial.print( " MANUAL”);
if (hb.custom_mode == 4)
Serial.print( " HOLD");
if (hb.custom_mode == 10)
Serial.print( " !!AUTO!!“);
Serial.print(” SysStat:“);
Serial.print(hb.system_status);
Serial.print(” MavVer:");
Serial.print(hb.mavlink_version);

Hello,

Thanks for the reply. Your suggestions improved the results. This is what my output looks like after adding in your suggestions to the program. Now it’s able to enter the switch case for GPS however, the output I get for GPS is wrong. Also, the TYPE below heartbeat is 27 in some cases and 6 in some case. However, I’m still not getting my GPS data. I’m just able to get my heartbeat.

Entered if statement
MSG RCVD -
magic:254
seq:88
sysid:1
compid:0
msgid#:0
HEARTBEAT
Type:27
APclass:8
BaseMode:4
Custom/Flightmode:0
MANUALSysStat:4
MavVer:3

Good progress.
The different TYPEs in the HEARTBEATs is usually because there is more than one CompID talking. For example, in the one you show above, the SysID=1 and the CompID=0, which is not the main AutoPilot, it’s a sub system of the AutoPilot, and given that the TYPE=27, when you look that up in the table Messages (common) · MAVLink Developer Guide that says it’s an ADSB system. My Cube Orange with ADSB Carrier board also sends heartbeats from its ADSB sub module. The clue is the different CompID.

Now as for why you are getting incorrect data in your GPS MAVLink message, that I can’t help with. Does your gps get a satellite fix? Can you see if it is operating correctly from Mission Planner?

By the way, you should probably be sending HEARTBEATs regularly from your Arduino to the Autopilot, so it knows you are still connected. How to do that, plus a bunch of code to help you decode lots of other MAVLink messages can be pulled out of my GitHub - pauljeffress/Pulsar-MAVLink-Tester code if that helps.

Hello Paul,

Thanks for the reply. I have made good progress today. I’m able to read different message IDs. I changed it to mavlink1 in the mission planner. I also edited the SR_4 parameters.

However, what is happening is, I get inconsistent message id’s.

For example, I continuously get 0, then continuously get 30, then 27, 32, and 24, then 0. If I keep running my programming for 20 minutes continuously, I get the GPS data only 4 times, whereas I get imu data 40 times.

I want to run the program and get GPS data only continuously. PFA attachment for the code below. Please let me know if I can do anything better.

#include <mavlink.h>

int count=0;
int gps_count=0;
int imu_count=0;
int att_count=0;

void setup() {
// put your setup code here, to run once:
Serial2.begin(57600); //for pixhawk to arduino
//Serial2.begin(115200); // for arduino-myrio

Serial.begin(115200); //monitor

request_datastream();
}

void loop() {
//Serial.println(“Started”);

MavLink_receive();
delay(1000);
}

void MavLink_receive()
{
//Serial.println(“Entered mavlink recieve”);
mavlink_message_t msg;
mavlink_status_t status;

while(Serial2.available())
{ //Serial.println(“mavlink available”);
uint8_t c= Serial2.read();
//Serial.println(c);
//Get new message
if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
{ //Serial.println(“Entered if statement”);
//Serial.println(“MSG RCVD -”);
//Serial.print(“magic:”);
/Serial.println(msg.magic);
Serial.print(“seq:”);
Serial.println(msg.seq);
Serial.print(“sysid:”);
Serial.println(msg.sysid);
Serial.print(“compid:”);
Serial.println(msg.compid);
/
Serial.print(“msgid#:”);
Serial.println(msg.msgid); //Handle new message from autopilot
if(msg.msgid==0)
count=count+1;
Serial.print(“the number of heartbeats :”);
Serial.println(count);

  switch(msg.msgid)
  {
    /*case MAVLINK_MSG_ID_HEARTBEAT: // #0 Messages (common) · MAVLink Developer Guide

{
mavlink_heartbeat_t hb; mavlink_msg_heartbeat_decode(&msg, &hb);
Serial.println(“HEARTBEAT”);
Serial.print(“Type:”);
Serial.println(hb.type);
Serial.print(“APclass:”);
Serial.println(hb.autopilot);
Serial.print(“BaseMode:”);
Serial.println(hb.base_mode);
if ((hb.base_mode == 1) || (hb.base_mode == 65)) // Complete Parameter List — Rover documentation
Serial.println( “DISarmed”);
if ((hb.base_mode == 129) || (hb.base_mode == 193))
Serial.println( " !!ARMED!!“);
Serial.print(“Custom/Flightmode:”);
Serial.println(hb.custom_mode);
if (hb.custom_mode == 0)
Serial.print( " MANUAL”);
if (hb.custom_mode == 4)
Serial.println( " HOLD");
if (hb.custom_mode == 10)
Serial.println( " !!AUTO!!");
Serial.print(“SysStat:”);
Serial.println(hb.system_status);
Serial.print(“MavVer:”);
Serial.println(hb.mavlink_version);

}
break;*/
case MAVLINK_MSG_ID_GPS_RAW_INT://#24
{
mavlink_gps_raw_int_t packet;
mavlink_msg_gps_raw_int_decode(&msg, &packet);
Serial.println(“In the switch case”);
Serial.print("GPS Latitude: ");Serial.println(packet.lat);
Serial.print("GPS Longitude: ");Serial.println(packet.lon);
Serial.print("GPS Speed: ");Serial.println(packet.vel);
Serial.print("Sats Visible: ");Serial.println(packet.satellites_visible);
gps_count=gps_count+1;
Serial.print(“The number of GPS message :”);
Serial.println(gps_count);
//Serial2.print("GPS Latitude: ");Serial2.println(packet.lat);

  }
  break;
 case MAVLINK_MSG_ID_SYS_STATUS:  // #1: SYS_STATUS
      {
        /* Message decoding: PRIMITIVE
         *    mavlink_msg_sys_status_decode(const mavlink_message_t* msg, mavlink_sys_status_t* sys_status)
         */
        //mavlink_message_t* msg;
        mavlink_sys_status_t sys_status;
        mavlink_msg_sys_status_decode(&msg, &sys_status);
        Serial.println("PX SYS STATUS: ");
        Serial.print("[Bat (V): ");
        Serial.print(sys_status.voltage_battery);
        Serial.print("], [Bat (A): ");
        Serial.print(sys_status.current_battery);
        Serial.print("], [Comms loss (%): ");
        Serial.print(sys_status.drop_rate_comm);
        Serial.print("]");
      }
      break;

      case MAVLINK_MSG_ID_ATTITUDE: //#30: ATTITUDE
      {
        mavlink_attitude_t attitude;
        mavlink_msg_attitude_decode(&msg,&attitude);
        Serial.print("Roll :");
        Serial.println(attitude.roll);
        Serial.print("Pitch :");
        Serial.println(attitude.pitch);
        Serial.print("Yaw :");
        Serial.println(attitude.yaw);
        Serial.print("Roll speed :");
        Serial.println(attitude.rollspeed);
        att_count=att_count+1;
        Serial.print("The number of Attitude message :");
        Serial.println(att_count);
    
        
      }
       break;
       case  MAVLINK_MSG_ID_RAW_IMU:
      {
        mavlink_raw_imu_t highres;
        mavlink_msg_raw_imu_decode(&msg, &highres);
        Serial.println("RAW IMU Message");
        Serial.print("Xacc: "); Serial.print(highres.xacc); Serial.println(" m/s/s");
        Serial.print("Yacc: "); Serial.print(highres.yacc); Serial.println(" m/s/s");
        Serial.print("Zacc: "); Serial.print(highres.zacc); Serial.println(" m/s/s");
        Serial.print("Xgyro: "); Serial.print(highres.xgyro); Serial.println(" rad/s");
        Serial.print("Ygyro: "); Serial.print(highres.ygyro); Serial.println(" rad/s");
        Serial.print("Zgyro: "); Serial.print(highres.zgyro); Serial.println(" rad/s");
        Serial.print("Xmag: "); Serial.print(highres.xmag); Serial.println(" gauss");
        Serial.print("Ymag: "); Serial.print(highres.ymag); Serial.println(" gauss");
        Serial.print("Zmag: "); Serial.print(highres.zmag); Serial.println(" gauss");
        /*Serial.print("Absolute Pressure: "); Serial.print(highres.abs_pressure); Serial.println(" mbar");
        Serial.print("Diff Pressure: "); Serial.print(highres.diff_pressure); Serial.println(" mbar");
        Serial.print("Pressure Alt : "); Serial.println(highres.pressure_alt);
        Serial.print("Temperature : "); Serial.print(highres.temperature); Serial.println(" degC");*/
        imu_count=imu_count+1;
        Serial.print("The number of IMU message :");
        Serial.println(imu_count);
    

        Serial.print("\n");
      }
      break;
    }
}

}
}

void request_datastream() {
Serial.println(“Entered datastream”);
// for(int i=2;i<256;i++){
//Request Data from Pixhawk
uint8_t _system_id = 1; // id of computer which is sending the command (ground control software has id of 255)
uint8_t _component_id = 100; // seems like it can be any # except the number of what Pixhawk sys_id is
uint8_t _target_system = 1; // Id # of Pixhawk (should be 1)
uint8_t _target_component = 1; // Target component, 0 = all (seems to work with 0 or 1
uint8_t _req_stream_id = MAV_DATA_STREAM_RAW_SENSORS;
uint16_t _req_message_rate = 0x02; //number of times per second to request the data in hex
uint8_t _start_stop = 1; //1 = start, 0 = stop

// STREAMS that can be requested
/*

  • Definitions are in common.h: enum MAV_DATA_STREAM and more importantly at:
    Messages (common) · MAVLink Developer Guide
  • MAV_DATA_STREAM_ALL=0, // Enable all data streams
  • MAV_DATA_STREAM_RAW_SENSORS=1, /* Enable IMU_RAW, GPS_RAW, GPS_STATUS packets.
  • MAV_DATA_STREAM_EXTENDED_STATUS=2, /* Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS
  • MAV_DATA_STREAM_RC_CHANNELS=3, /* Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
  • MAV_DATA_STREAM_RAW_CONTROLLER=4, /* Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT.
  • MAV_DATA_STREAM_POSITION=6, /* Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages.
  • MAV_DATA_STREAM_EXTRA1=10, /* Dependent on the autopilot
  • MAV_DATA_STREAM_EXTRA2=11, /* Dependent on the autopilot
  • MAV_DATA_STREAM_EXTRA3=12, /* Dependent on the autopilot
  • MAV_DATA_STREAM_ENUM_END=13,
  • Data in PixHawk available in:
    • Battery, amperage and voltage (SYS_STATUS) in MAV_DATA_STREAM_EXTENDED_STATUS
    • Gyro info (IMU_SCALED) in MAV_DATA_STREAM_EXTRA1
      */

// Initialize the required buffers
mavlink_message_t msg;
uint8_t buf[MAVLINK_MAX_PACKET_LEN];
const int maxStreams = 2;
//const uint8_t MAVStreams[maxStreams] = {MAV_DATA_STREAM_EXTENDED_STATUS, MAV_DATA_STREAM_EXTRA1};
//const uint16_t MAVRates[maxStreams] = {0x02,0x05};

//for (int i=0; i < maxStreams; i++) {
/*
* mavlink_msg_request_data_stream_pack(system_id, component_id,
* &msg,
* target_system, target_component,
* MAV_DATA_STREAM_POSITION, 10000000, 1);
*
* mavlink_msg_request_data_stream_pack(uint8_t system_id, uint8_t component_id,
* mavlink_message_t* msg,
* uint8_t target_system, uint8_t target_component, uint8_t req_stream_id,
* uint16_t req_message_rate, uint8_t start_stop)
*
*/

// Pack the message
//Serial.print(“Component id:”);
//Serial.println(i);
mavlink_msg_request_data_stream_pack(_system_id, _component_id, &msg, _target_system, _target_component,_req_stream_id ,_req_message_rate , _start_stop);
uint16_t len = mavlink_msg_to_send_buffer(buf, &msg); // Send the message (.write sends as bytes)
//Serial.println(_req_stream_id);
Serial2.write(buf, len); //Write data to serial port
}
//}
//}

I forgot to add, my outputs are correct, it is just that the messages are random.