MAVLink and Arduino: step by step

Hello,
I have the problem that I receive the high correctly, but when I want to receive the thrust (additionally also placed on channel 7) and channel 6, I get random values.

I have Mavlink set up as above, use an Aruino Mega and and use a Pixhawk 6X.
I hope maybe someone can help me because I just can not find the error.

#include <mavlink.h>
#include <SoftwareSerial.h>
//#include "common/mavlink_msg_gps_raw_int.h"
SoftwareSerial _MavLinkSerial(11, 10); // PIN 9=Telemetry TX->Pixhawk RX, PIN 10=Telemetry RX->Pixhawk TX

// 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 = 60;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

void setup() {
  // MAVLink interface start
  _MavLinkSerial.begin(57600);

  Serial.begin(115200);
  Serial.println("MAVLink starting.");
}

void loop() {

  // MAVLink
  /* The default UART header for your MCU */
  int sysid = 1;                   ///< ID 20 for this airplane. 1 PX, 255 ground station
  int compid = 158;                ///< The component sending the message
  int type = MAV_TYPE_QUADROTOR;   ///< This system is an airplane / fixed wing

  // Define the system type, in this case an airplane -> on-board controller
  // uint8_t system_type = MAV_TYPE_FIXED_WING;
  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

  // Initialize the required buffers
  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);
  mavlink_msg_heartbeat_pack(1, 0, &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 the message with the standard UART send function
  // uart0_send might be named differently depending on
  // the individual microcontroller / library in use.
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    // Record last HB update
    previousMillisMAVLink = currentMillisMAVLink;


    //Mav_Request_Data();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      // Request streams from Pixhawk
      Serial.println("Streams requested!");
      Mav_Request_Data();
      num_hbs_pasados = 0;

    }

  }

  // Check reception buffer
  comm_receive();
}


void Mav_Request_Data()
{
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  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

     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
  */

  // To be setup according to the needed information to be requested from the Pixhawk
  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)

    */
    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);
    //mavlink_msg_request_data_stream_pack(2, 200, &msg, 1, 0, MAVStreams[i], MAVRates[i], 1);
    uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
    _MavLinkSerial.write(buf, len);
  }
}
void comm_receive() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (_MavLinkSerial.available() > 0) {
    uint8_t c = _MavLinkSerial.read();

    // Try to get a new message
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
    {
      Serial.print("DEBUG msgid:"); Serial.println(msg.msgid);
      // Handle message
      switch (msg.msgid)
      {
        case MAVLINK_MSG_ID_HEARTBEAT:  // #0: Heartbeat
          {
            // E.g. read GCS heartbeat and go into
            // comm lost mode if timer times out
          }
        case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:  // #30
          {
            mavlink_global_position_int_t Position;
            mavlink_msg_global_position_int_decode(&msg, &Position);
            Serial.print("Position high: "); Serial.println(Position.relative_alt);
          }
        case MAVLINK_MSG_ID_RC_CHANNELS_SCALED:  // #35
          {
            mavlink_rc_channels_scaled_t RCCHANNEL;
            mavlink_msg_rc_channels_scaled_decode(&msg, &RCCHANNEL);
            Serial.print("Chanel 6 (3-Kanal Schalter): ");
            int RAW_SERVO = RCCHANNEL.chan6_scaled;
            Serial.println(RAW_SERVO);
            Serial.print("Chanel 7 (Schub): ");
            Serial.println(RCCHANNEL.chan3_scaled);
            Serial.print("Drei Kanal: ");
            Serial.println(mavlink_msg_rc_channels_scaled_get_chan6_scaled(&msg));
            Serial.print("Schub: ");
            Serial.println(mavlink_msg_rc_channels_scaled_get_chan3_scaled(&msg));
          }
        case MAVLINK_MSG_ID_MANUAL_CONTROL:  // #69
          {
            mavlink_manual_control_t SCHUB;
            mavlink_msg_manual_control_decode(&msg, &SCHUB);
            //mavlink_msg_rc_channels_scaled_decode(&msg, &RCCHANNEL);
            //mavlink_msg_manual_control_get_thrust(const mavlink_message_t* msg)
            Serial.print("Schub2: ");
            Serial.println(SCHUB.thrust);
            Serial.print("Schub3: ");
            Serial.println(mavlink_msg_manual_control_get_thrust(&msg));
          }
        case MAVLINK_MSG_ID_SERVO_OUTPUT_RAW:  // #69
          {
            mavlink_servo_output_raw_t SERVOX;
            mavlink_msg_servo_output_raw_decode(&msg, &SERVOX);
            Serial.print("Schub4: ");
            Serial.println(SERVOX.servo7_raw);
            Serial.print("Schub5: ");
            Serial.println(mavlink_msg_servo_output_raw_get_servo7_raw(&msg));
          }
        case MAVLINK_MSG_ID_RC_CHANNELS_RAW:  // #35
          {
            mavlink_rc_channels_raw_t chs;
            mavlink_msg_rc_channels_raw_decode(&msg, &chs);
            Serial.print("Chanel 6 (3-Kanal Schalter): ");
            Serial.println(chs.chan3_raw);
          }
          break;
      }
    }
  }
}

Thank you very much for your reply. The baud rate value of the autopilot telem2 port is 115200. I will try the Serial2 port instead of the virtual ports you mentioned as soon as possible and provide feedback.

Have a good work.

Hello again

As you said, I made the baud rate value of the SERIAL2 parameter 57600 and used the Serial2 port on Mega. However, I still see the same output. I wonder if there is another parameter(s) I need to set on the Pixhawk side? I don’t understand. (I am sure there is no problem with my connections).

Can you share a screenshot of how you have your autopilot SERIAL2 configured?
Also do you have it set to MAVLink v1?

Hello again

You can see my configuration settings in the pictures.


Ekran görüntüsü 2023-07-31 103308

It seems that it never enters the if block here.

Hi @Ufuk_Beydemir
Try changing SERIAL2_PROTOCOL to 1
The arduino code is expecting Mavlink v1 not v2.
I think that may be the problem.
Paul

Hi,
I am trying to get the Attitude data from the Pixhawk (Arducopter 4.3.7, cube black) using Arduino Mega. I get heartbeat (msgid:0), and a couple of more message ids like 22, 111, and 253 but not attitude (30). I checked with both Serial2 protocols 1, and 2 without any changes. Can anyone help me to find the problem here? Please see the code below.

#include <mavlink.h>
#include <SoftwareSerial.h>
SoftwareSerial _MavLinkSerial(11, 12); // PIN 9=Telemetry TX->Pixhawk RX, PIN 10=Telemetry RX->Pixhawk TX

// 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 = 60;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

void setup() {
  // MAVLink interface start
  _MavLinkSerial.begin(57600);

  Serial.begin(57600);
  Serial.println("MAVLink starting.");
}

void loop() {

  // MAVLink
  /* The default UART header for your MCU */
  int sysid = 1;                   ///< ID 20 for this airplane. 1 PX, 255 ground station
  int compid = 158;                ///< The component sending the message
  int type = MAV_TYPE_QUADROTOR;   ///< This system is an airplane / fixed wing

  // Define the system type, in this case an airplane -> on-board controller
  // uint8_t system_type = MAV_TYPE_FIXED_WING;
  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

  // Initialize the required buffers
  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);
  mavlink_msg_heartbeat_pack(1, 1, &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 the message with the standard UART send function
  // uart0_send might be named differently depending on
  // the individual microcontroller / library in use.
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    // Record last HB update
    previousMillisMAVLink = currentMillisMAVLink;


    //Mav_Request_Data();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      // Request streams from Pixhawk
      Serial.println("Streams requested!");
      Mav_Request_Data();
      num_hbs_pasados = 0;
    }

  }

  // Check reception buffer
  comm_receive();
}


void Mav_Request_Data()
{
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];


  // To be setup according to the needed information to be requested from the Pixhawk
  const int  maxStreams = 1;
  const uint8_t MAVStreams[maxStreams] = {MAV_DATA_STREAM_POSITION};
  const uint16_t MAVRates[maxStreams] = {0x02};

  for (int i = 0; i < maxStreams; i++) {
    mavlink_msg_request_data_stream_pack(2, 200, &msg, 1, 1, MAVStreams[i], MAVRates[i], 1);
    uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
    _MavLinkSerial.write(buf, len);
  }
}

void comm_receive() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (_MavLinkSerial.available() > 0) {
    uint8_t c = _MavLinkSerial.read();
    // Try to get a new message
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
    {
      Serial.print("DEBUG msgid:"); Serial.println(msg.msgid);
      // Handle message
      switch (msg.msgid)
      {
          case MAVLINK_MSG_ID_HEARTBEAT:  // #0: Heartbeat
          {
            // E.g. read GCS heartbeat and go into
            // comm lost mode if timer times out
          }
          break;

          case MAVLINK_MSG_ID_ATTITUDE :  // #0: Heartbeat
          {
          mavlink_attitude_t attitude;
          mavlink_msg_attitude_decode(&msg, &attitude);
          Serial.print(attitude.roll);
          Serial.print(",");
          Serial.print(attitude.pitch);
          Serial.print(",");
          Serial.println(attitude.yaw);

          }
          break;
      }
    }
  }
} 

Hello, I’m trying to connect rasberry pi pico w with Mission Planner, I’ve changed to 255 but Mission Planner still can’t recieve the heartbeat.Is there ant solution or do you have an example code which can connect to Misiion Planner.

Hello, could someone help me with the rc_chanel output.
i try to get the data from RC_chanels_raw and scaled, it is the same value in both but it doesnt make sense.
here is a outcut of the code.

#include <mavlink.h>
#include <SoftwareSerial.h>
#include <Servo.h>
Servo myservo;
//#include "common/mavlink_msg_gps_raw_int.h"
SoftwareSerial _MavLinkSerial(11, 10); // PIN 9=Telemetry TX->Pixhawk RX, PIN 10=Telemetry RX->Pixhawk TX
// 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 = 60;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

void setup() {
  // MAVLink interface start
  _MavLinkSerial.begin(57600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, OUTPUT);
  Serial.begin(115200);
  Serial.println("MAVLink starting.");
}

void loop() {
  // MAVLink
  /* The default UART header for your MCU */
  int sysid = 1;                   ///< ID 20 for this airplane. 1 PX, 255 ground station
  int compid = 158;                ///< The component sending the message
  int type = MAV_TYPE_QUADROTOR;   ///< This system is an airplane / fixed wing
  // Define the system type, in this case an airplane -> on-board controller
  // uint8_t system_type = MAV_TYPE_FIXED_WING;
  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

  // Initialize the required buffers
  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);
  mavlink_msg_heartbeat_pack(1, 0, &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 the message with the standard UART send function
  // uart0_send might be named differently depending on
  // the individual microcontroller / library in use.
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    // Record last HB update
    previousMillisMAVLink = currentMillisMAVLink;
    //Mav_Request_Data();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      // Request streams from Pixhawk
      Serial.println("Streams requested!");
      Mav_Request_Data();
      num_hbs_pasados = 0;
    }
  }
  // Check reception buffer
  comm_receive();

}
void Mav_Request_Data()
{
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
  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#
     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
  */

  // To be setup according to the needed information to be requested from the Pixhawk
  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, _req_stream_id, _req_message_rate, _start_stop);
    //uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
    //mavlink_msg_request_data_stream_pack(2, 200, &msg, 1, 0, MAVStreams[i], MAVRates[i], 1);
    uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
    _MavLinkSerial.write(buf, len);
  }
}
void comm_receive() {
  mavlink_message_t msg;
  mavlink_status_t status;
  while (_MavLinkSerial.available() > 0) {
    uint8_t c = _MavLinkSerial.read();
    // Try to get a new message
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
    {
      //Serial.print("DEBUG msgid:"); Serial.println(msg.msgid);
      // Handle message
      switch (msg.msgid)
      {
        case MAVLINK_MSG_ID_HEARTBEAT:  // #0: Heartbeat
          {
            // E.g. read GCS heartbeat and go into
            // comm lost mode if timer times out
          }
          case MAVLINK_MSG_ID_RC_CHANNELS_RAW:  // #35
          {
            mavlink_rc_channels_raw_t chs;
            mavlink_msg_rc_channels_raw_decode(&msg, &chs);
            Serial.print("Chanel 6 (3-Kanal Schalter): ");
            Serial.println(chs.chan6_raw);
          }
          case MAVLINK_MSG_ID_RC_CHANNELS_SCALED:  // #35
          {
            mavlink_rc_channels_scaled_t RCCHANNEL;
            mavlink_msg_rc_channels_scaled_decode(&msg, &RCCHANNEL);
            Serial.print("Chanel 6 (3-Kanal Schalter): ");
            int RAW_SERVO = RCCHANNEL.chan6_scaled;
            Serial.println(RAW_SERVO);
            Serial.print("Chanel 5 (Schub): ");
            Serial.println(RCCHANNEL.chan5_scaled);
            Serial.print("Drei Kanal: ");
            Serial.println(mavlink_msg_rc_channels_scaled_get_chan6_scaled(&msg));
            Serial.print("Schub: ");
            Serial.println(mavlink_msg_rc_channels_scaled_get_chan5_scaled(&msg));
          }
        case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:  // #30
          {
            mavlink_global_position_int_t Position;
            //mavlink_msg_attitude_decode(&msg, &attitude);
            mavlink_msg_global_position_int_decode(&msg, &Position);

Hi @Dennisw6
It sounds like this is more about understanding Mavlink and your autopilot than about using Arduino to read the values (which you look like you have done successfully).
I’d try a different group/thread here in the forum, I’m not sure if there is a MAVLink specific place you could ask?
Good luck,
Paul

Hi Paul,
Thanks for the fast reply.
So you mean that the Code ist fine and should works because i receiver the high of the pixhawk right, but nur the RC Channels or the Servooutputs not.

Thanks
Best regards
Dennis

thanks for your useful information. I have a sensor connected to arduino and I want to transfer the data of the sensor through Pixhawk to the GCS(mission planner). Would you consult me with its method? what should I do?

Hi @zara,
You will need to get your Arduino talking MAVLink with your Pixhawk in both directions (send & receive) first. Once you have that working on your Arduino you need to read the value from your sensor and then create a suitable MAVLink message to hold the sensor value, and send it to the PixHawk. You should then be able to listen on your GCS and look for the MAVLink message. Look for messages that come from the MAVLink Component_ID and Sys_ID of your Arduino.
Does that make sense?

1 Like

Did you ever get this working? I am trying to get my TTGO LoRa32 to package up mavlink messages and send them over the air via LoRa.

MavlinkMessage → Lora32 ------> Telem Radio → QGC

Can you tell me please which Arduino IDE you used and which Mavlink library?
Actually I can’t compile any code including the mavlink library with the newest Arduino IDE.
Im using this library: GitHub - mavlink/c_library_v2: Official reference C / C++ library for the v2 protocol

@starter-one You probably need to specify the message definitions, i.e. folder common https://github.com/mavlink/c_library_v2/tree/master/common, to use it in your Arduino sketches.

Hi guys,

First of all, thank you for your valuable comments on this topic. However, since I am new in this field, I appreciate any help and suggestion you can provide. I am struggling with reading data from Pixhawk 4 via Arduino UNO, as well as Arduino MEGA. I cannot figure out where the problem is (I am not a programmer/developer and I doesn’t have much experience in coding). I want to read roll, pitch, yaw and altitude data from Pixhawk 4 in Arduino IDE, since I want to use Pixhawk as a sensor for further data processing. The code given bellow is my trial to read any data from Pixhawk.

The code is given bellow:

#include <mavlink.h>
#include <SoftwareSerial.h>
SoftwareSerial _MavLinkSerial(9, 10); // PIN 9=Telemetry TX->Pixhawk RX, PIN 10=Telemetry RX->Pixhawk TX

// 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 = 60;                      // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

void setup() {
  // MAVLink interface start
  _MavLinkSerial.begin(57600);

  Serial.begin(57600);
  Serial.println("MAVLink starting.");
}

void loop() {

  // MAVLink
  /* The default UART header for your MCU */
  int sysid = 1;                   ///< ID 20 for this airplane. 1 PX, 255 ground station
  int compid = 158;                ///< The component sending the message
  int type = MAV_TYPE_QUADROTOR;   ///< This system is an airplane / fixed wing

  // Define the system type, in this case an airplane -> on-board controller
  // uint8_t system_type = MAV_TYPE_FIXED_WING;
  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

  // Initialize the required buffers
  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);
  mavlink_msg_heartbeat_pack(1, 0, &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 the message with the standard UART send function
  // uart0_send might be named differently depending on
  // the individual microcontroller / library in use.
  unsigned long currentMillisMAVLink = millis();
  if (currentMillisMAVLink - previousMillisMAVLink >= next_interval_MAVLink)
  {
    // Record last HB update
    previousMillisMAVLink = currentMillisMAVLink;


    //Mav_Request_Data();
    num_hbs_pasados++;
    if (num_hbs_pasados >= num_hbs) {
      // Request streams from Pixhawk
      Serial.println("Streams requested!");
      Mav_Request_Data();
      num_hbs_pasados = 0;
    }

  }

  // Check reception buffer
  comm_receive();
}


void Mav_Request_Data()
{
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];


  // To be setup according to the needed information to be requested from the Pixhawk
  const int  maxStreams = 1;
  const uint8_t MAVStreams[maxStreams] = {MAV_DATA_STREAM_EXTRA1};
  const uint16_t MAVRates[maxStreams] = {0x04};

  for (int i = 0; i < maxStreams; i++) {
    mavlink_msg_request_data_stream_pack(1, 1, &msg, 1, 0, MAVStreams[i], MAVRates[i], 1);
    uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
    _MavLinkSerial.write(buf, len);
  }
}

void comm_receive() {
  mavlink_message_t msg;
  mavlink_status_t status;

  while (_MavLinkSerial.available() > 0) {
    uint8_t c = _MavLinkSerial.read();
    Serial.println(msg.msgid);

    // Try to get a new message
    if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
    {
      Serial.print("DEBUG msgid:"); Serial.println(msg.msgid);
      // Handle message
      switch (msg.msgid)
      {
        case MAVLINK_MSG_ID_HEARTBEAT:  // #0: Heartbeat
          {
            // E.g. read GCS heartbeat and go into
            // comm lost mode if timer times out
          }
          break;
      }
    }
  }
}

Parameters from Mission planner are given bellow:

The output from Serial Monitor is given bellow:

As I can see, only Tx light on Arduino UNO is blinking.

I will appreciate any help! Thanks in advance!

Hi Djordje!
why you set system_id and component_id to 1 and 1 in mavlink_msg_request_data_stream_pack function?
in my experience, this doesn’t work. I hope you can solve your problem.

1 Like