MAVLink and Arduino: step by step

Hi @Zain_Siddiqui, can you share your code and more about what you are seeing, then maybe we can help you. Also is your autopilot configured to talk MAVLink on the port you are connected to?
What version of ArduPilot are you using?
Have you checked the recent comments above regarding MAVLink v1 vs v2.
Cheers

hi everyone

I’m new to pixhawk and don’t have much expirience with coding. I am building an autonomous surfboard and I’m using a stepper motor as a steering. I’m using a pixhawk and arduino to do all this and I want a pixhawk to control the stepper motor while its connected to an arduino. The problem is I don’t know how I can do that. anyone who knows how to do that please help.

Hi @fezile_mageba,
That sounds like a cool project.
So from what I can gather you need a way to use the pix hawk with ardupilot to control the Stepper motor, is that correct?
If so then I have a few ideas and will get back to you.
Cheers,
PJ

Hi Paul

Yes that’s correct, thank you very much.

Hi @fezile_mageba,
I think what you need to do is a two step thing.
First you need to use your Arduino to read the PWM signal coming out of the AutoPilot for the steering servo. That should give you a value that is proportional to the Autopilots desired steering angle. There are loads of examples how to read PWM values via an Arduino like How to read RC receiver signal with Arduino | by Ricardo Paiva | Medium
Second you now need to take that steering value and use that to control your stepper motor, again there are many examples of how to do that via Arduino on the net.

You do not need to use MAVLink on your Arduino in this case.

So, just break your testing into the two parts, get each of them working and then combine them.

Hope this helps, please let us know how you go.

Hi Paul

My concern with what you are explaining is that I don’t understand how the pixhawk will be able to control the stepper motor autonomously. Or that will come after doing these two steps?

Fezile

Your essentially converting the stepper motor into a servo for the pixhawk to control.

Hey Fezile,

The Pixhawk usually controls a servo to steer a boat/plane/rover. It does that by putting out a PWM signal on one of the servo connectors on the pixhawk.
But as you are using a stepper motor to control steering on your surfboard, you need to convert the PWM signal coming out of the pixhawk, to something the stepper motor will understand.
So to do that conversion, I’ve suggested you use an Arduino to listen to the PWM signal, convert it to a number which is relative to the steering angle that the pixhawk wants and then take that number as input to how you position your stepper motor.
How does that sound?

Actually I wouldn’t be surprised if someone else has already done something like this. Have a good search around the forum to check.
You are looking for how to convert PWM to Stepper motor or something like that. Or maybe how to use a stepper motor with ardupilot/pixhawk.

I think the problem with using a stepper motor is it has no feed back, so you can tell it to turn 180 degrees but it doesnt know its starting position. In 3d printers they have an end point switch then essentually count the turns to know where it is relative to the switch. So you would have to set your rudder position every time you switched it on or add a potentiometer for feedback, at that point you might as well get a servo.

I tried to use these codes but i just got
16:17:21.046 → Streams requested!

Hi guys
I was looking forward to buying a stepper motor control from pololu, which make it easier to drive a stepper motor using the PWM signal from the pixhawk. But I’ll have to go with what you explained, and I hope everything goes well. I will inform you of every step.

Thank you guys

Can you please explain what you did and which code you are talking about

You can use this code to turn any geared brushed motor into a servo.

#include “mavlink.h”
#include <SoftwareSerial.h>
SoftwareSerial _MavLinkSerial(21, 20);
// PIN 21=Telemetry TX->Pixhawk RX, PIN 20=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 = 2; // # of heartbeats to wait before activating STREAMS from Pixhawk. 60 = one minute.
int num_hbs_pasados = num_hbs;

void setup() {
// 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 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_POSITION};
const uint16_t MAVRates[maxStreams] = {0x02};

for (int i = 0; i < maxStreams; i++) {
mavlink_msg_request_data_stream_pack(6, 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
      }
      break;
  }
}

}
}

16:07:21.758 → Streams requested!
16:07:23.750 → Streams requested!
16:07:25.776 → Streams requested!
16:07:27.769 → Streams requested!
16:07:29.761 → Streams requested!
16:07:31.754 → Streams requested!
16:07:33.780 → Streams requested!
16:07:35.773 → Streams requested!
16:07:37.766 → Streams requested!
16:07:39.760 → Streams requested!
16:07:41.752 → Streams requested!
16:07:43.777 → Streams requested!