Mavlink communication between Arduino UNO and Pixhawk Mini

I am currently using PX4 1.8.2 stable version for my Pixhawk Mini. I am able to read the data transmitted from Pixhawk Mini to Arduino Uno but sending command from Arduino Uno to Pixhawk Mini seems does not work for me. This causes me the problem to change from Loiter mode to Offboard mode using the RC. I just constantly getting the message, “Offboard Rejected”. My code is attached below. Can anyone take a quick look what is happening because I believe that the Pixhawk MINI cannot receive the target setpoints from Arduino Uno and this causes the “Offboard Rejected” issues. I try to debug for many days but no luck for me. I am coming here for some suggestion if anyone knows what happens.
///////////////////////THIS IS MY CODE//////////////////////////////////
#include <SoftwareSerial.h>
SoftwareSerial pxSerial(9,10); // RX, TX
#include “mavlink.h”

// Mavlink variables

int target_system_id = 1;
int companion_id =20; // Arduino UNO id (I set it randomly from 1-255 except 1 since Pixhawk using 1)
int component_id = 1; // Can be 0 or 1? I just set 1.
int target_component_id = 1;

void setup() {
Serial.begin(57600);
pxSerial.begin(57600);

}
void loop() {
mavlink_message_t msg;
for(int x = 0; x<100; x++)
{
send_HB(msg);
delay(100);
Serial.println("Sending HeartBeat");
}
while(true)
{
//Serial.print("Time:");
//Serial.println(current_time/1000);
previous_time = current_time;

float velxx = 1.5;
set_Position(msg,velxx);
delay(100); // Setpoints sent run in 10Hz.

}

}
void send_HB(mavlink_message_t &msgg){
int sysid = 20; ///< ID for my companion board
int compid = 1 ; ///< The component sending the message, either 0 or 1
int type = MAV_TYPE_QUADROTOR; ///< This system is an quadrotor

uint8_t autopilot_type = MAV_AUTOPILOT_PX4; //< PX4 firmware
uint8_t system_mode = MAV_MODE_MANUAL_ARMED; ///< Booting up
uint32_t custom_mode = 0; ///< Custom mode, 0 since not using this
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, &msgg, 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);
pxSerial.write(buf,len); // Write the message through the serial port I sent
}
void set_Position(mavlink_message_t &msg, float velx)
{
mavlink_set_position_target_local_ned_t sp;

sp.type_mask= 0b110111110111; // Only velocity_x is set for testing.
sp.coordinate_frame = MAV_FRAME_LOCAL_NED;
sp.vx =velx ; // unit: m/s
sp.target_system = target_system_id; // Target_sysid = 1 since I am sending command to pixhawk
sp.target_component = target_component_id;// Target_compid = 0 or 1, but I use 1.
mavlink_msg_set_position_target_local_ned_encode(companion_id,component_id,&msg,&sp);
send_Message(msg); // passs the msg to send_Message in order to write message to pixhawk via serial port
Serial.print("Velocity x: ");
Serial.println(sp.vx);

}

Ok, first thing, if you could edit your post and put the code inside ``` that would make it a lot easier to read.

Another thing is to check the type mask against what is done in the Dronecode SDK, check this:

@JulianOes

Thanks for your reply. Appreciate it so much! I did solve the problem I have. The arduino was sending command.
I have couple of questions which I hope to get answered by you if possible.

  1. I am now working for state machine. I am trying to output the vehicle mode (Stabilized,Manual,Loiter,Offboard and etc) and vehicle arming status (armed,disarmed) but I could not find any mavlink msg function which does that. Do you know which function I can use to do that?

  2. How do you define the system id and component id for the Arduino board? Can the system id and component id be any number between 1-255 except 1 since 1 is used by Pixhawk?

-zimin

  1. Check this code: https://github.com/Dronecode/DronecodeSDK/blob/ac0c1fde587c22411bdca84fdc19cb955a59e052/plugins/telemetry/telemetry_impl.cpp#L475-L482

  2. Yes, system ID you can choose anything but 0, 1. And component ID you can choose something that fits according to: https://mavlink.io/en/messages/common.html#MAV_COMPONENT

@JulianOes,

Thanks for your help. I am sorry that I did not reply immediately what I have accomplished. Anyway, everything works fine for me right now and thank you for your time and efforts for helping me.

PS: You can close this discussion post if needed.

Regards,
Zi Min Er

1 Like

Great, thanks for the feedback.

which library that you use because i have hard time to read message from pixhawk to arduino

Hi Ruhaizah,

I am sorry for the late reply. Just in case you haven’t solved your problem. This might help you.

1st step: download the mavlink library version 2
https://github.com/mavlink/c_library_v2

2nd step: you do not need all folders that you downloaded. Copy the “common” folder inside your “c_library_v2” folder and paste to your arduino library

3rd step: copy “protocol.h” inside your “c_library_v2” folder and paste to the “common” folder (your “common” folder should be in arduino library now )

4th step: edit the “mavlink.h” file inside your “common” folder and add this line include "protocol.h". Then save and close.

5th step: In your arduino ide, type include "mavlink.h". You now can use the mavlink library to communicate between pixhawk and arduino.

P/S: Look through this to understand the messages definition. https://mavlink.io/en/messages/common.html

I didnt really go through again the steps. So the steps might not work. In case it does not work, please let me know.

Hey, you know how to use an Arduino our Stm32, ESp32 link a telemetry with Lora? Did see you any project like it to build a telemetry 915Mhz with Arduino?

hi @gadaavid,

I couldn’t get what you meant. Anyway, I have never dealt with stm32 and esp32 before. If you just wanted to bridge connection between arduino and flight controller(which contains px4 firmware)using mavlink, you can follow the steps: https://discuss.px4.io/t/mavlink-communication-between-arduino-uno-and-pixhawk-mini/10428/8?u=ziimiin14

Hi @ziimiin14

I was having that problem and I did the steps you said. Now, I can get some messages, but not all. I believe that the ones I am not getting are the newer (ODOMETRY, OPTICAL_FLOW_RAD, etc). At least, these that I am getting are the same ones that I received with an older library.
It’s very odd because they are all in the library, in the same folder, but I can get some but the ones I want I can’t. The “common” folder of the “c_library_v2” is the only folder that I have there.

Why is this happening?

So i have a similar problem. I have a pro mini with lora transmitting the rc control data to my uno with lora.

The transmission is showing the values in the UNO serial monitor.

I just now need to k ow how to communicate that from my Arduino to the pixracer.

When i use the RCin port, the pixracer fails to detct the channels.

Is there a simple way to do this as my Mavlink attempt keeps throwing MSG errors.

Here is the code below.

#include <SPI.h>
#include <LoRa.h>

#define LORA_SCK_PIN 13
#define LORA_MISO_PIN 12
#define LORA_MOSI_PIN 11
#define LORA_SS_PIN 10
#define LORA_RST_PIN 9
#define LORA_DIO0_PIN 8
#define LORA_BAND 433E6 // Change this to your region’s frequency

#define TX_PIN 3 // Arduino TX pin

void setup() {
Serial.begin(9600);
pinMode(TX_PIN, OUTPUT);

// LoRa setup
SPI.begin(); // Initialize SPI bus
LoRa.setPins(LORA_SS_PIN, LORA_RST_PIN, LORA_DIO0_PIN);

if (!LoRa.begin(LORA_BAND)) {
Serial.println(“Starting LoRa failed!”);
while (1);
}
}

void loop() {
// Receive data over LoRa
int packetSize = LoRa.parsePacket();
if (packetSize) {
String receivedData = LoRa.readString();
Serial.println(receivedData);

// Send the received data via the TX pin
digitalWrite(TX_PIN, HIGH);  // Set TX pin HIGH
delayMicroseconds(100);  // Adjust delay if needed
digitalWrite(TX_PIN, LOW);  // Set TX pin LOW

}

delay(100); // Add a small delay between LoRa receptions
}