I just bought the APM 2.5 together with the Remzibi OSD (not the minimOSD).

Now I try to get the connection from the APM to the OSD with the adapter calbe for telemetry


EDIT:  I want to send a big thank you to Heino R. Pull who send me a lot of informations and the very good working code for the ardurino mini to start the telemetry link and bring the APM 2.5 to send data to the remzibi OSD 3DR.

The original code can be downloaded here: http://www.heino.com/

Use this original Code to use the ardurino pro mini with an XBee.

If you don`t want to use the XBee, you need to do the wiring and code below.

(Tested with APM 2.5,  Arduplane 2.6 and Remzibi OSD 3DR)

Here is the modification from the osdmavlink.pde (I assume he will update it on his page soon, but maybe someone is interested)


// Mavlink to Remzibi OSD converter
// Using Ardustation code written by psmitty
// Heino Pull (heyno@heino.com) httpwww.heino.com
// Mavlink to Remzibi OSD compatible with ACM 2.7.3/2.8
#define MAVLINK10

#include <FastSerial.h>
#include <GCS_MAVLink.h>
#include <avr/pgmspace.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <AP_EEPROMB.h>         // ArduPilot Mega RC Library
//#include <Time.h>

#include <Servo.h>
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))

#undef PSTR
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))

#define SERIAL_BAUD 57600
//#define BUZZERON // is the buzzer on?

// data streams active and rates

// update rate is times per second (hz)
#define GET_PARAMS_TIMEOUT 200 //(20 seconds)
#define TOTAL_PARAMS 37
#define toRad(x) (x*PI)/180.0
#define toDeg(x) (x*180.0)/PI

float altitude=0;
float pitch=0;
float roll=0;
float yaw=0;
float longitude=0;
float latitude=0;
float velocity = 0;
unsigned long gpstime = 0;
int numSats=0;
int battery=0;
int currentSMode=0;
int currentNMode=0;
int droneType;
int autoPilot;
uint32_t custom_mode;
 int tdfix = 0;
int callsignprint = 0;
int waitingAck=0;
int paramsRecv=0;
int beat=0;

int find_param(const char* key)
  char buffer[15];
  for (int i=0; i<TOTAL_PARAMS; i++)
//    get_Param_Key(buffer, i);
    if (strcmp(buffer,(const char*)key) == 0)
      return i;    
  return -1;  

void gcs_update()
    // receive new packets
    mavlink_message_t msg;
    mavlink_status_t status;

    // process received bytes
        uint8_t c = Serial.read();
        // Try to get a new message
        if(mavlink_parse_char(0, c, &msg, &status)) gcs_handleMessage(&msg);

uint8_t received_sysid=0; ///< ID of heartbeat sender
uint8_t received_compid=0; // component id of heartbeat sender

void gcs_handleMessage(mavlink_message_t* msg)
  switch (msg->msgid) {
      mavlink_heartbeat_t packet;
      mavlink_msg_heartbeat_decode(msg, &packet);
      custom_mode = packet.custom_mode;
      droneType = packet.type; // Don't pick up from the heartbeat now since there is some weirdness when the Planner is running
                               // and ArduPlane is running (get packet with type = 1 and type =0 also - confused this logic)
      autoPilot = packet.autopilot;

      beat = 1;

      // decode
      mavlink_attitude_t packet;
      mavlink_msg_attitude_decode(msg, &packet);
      pitch = toDeg(packet.pitch);
      yaw = toDeg(packet.yaw);
      roll = toDeg(packet.roll);

  #ifdef MAVLINK10
          #else // MAVLINK10
          #endif // MAVLINK10
                // decode
          #ifdef MAVLINK10
                mavlink_gps_raw_int_t packet;
                mavlink_msg_gps_raw_int_decode(msg, &packet);
                velocity = packet.vel/100.0;
                latitude = packet.lat/1e7;
                longitude = packet.lon/1e7;
                altitude = packet.alt/1000.0;
                gpstime = packet.time_usec>>16;
          #else // MAVLINK10
                mavlink_gps_raw_t packet;
                mavlink_msg_gps_raw_decode(msg, &packet);
                velocity = packet.v;
                latitude = packet.lat;
                longitude = packet.lon;
                altitude = packet.alt;  
                gpstime = packet.usec >> 16;
          #endif // MAVLINK10
                tdfix = packet.fix_type;
                      numSats = packet.satellites_visible;

      mavlink_gps_status_t packet;
      mavlink_msg_gps_status_decode(msg, &packet);        
//      numSats = packet.satellites_visible;
//      Serial.print(numSats);
      // decode
      mavlink_raw_pressure_t packet;
      mavlink_msg_raw_pressure_decode(msg, &packet);

        mavlink_sys_status_t packet;
        mavlink_msg_sys_status_decode(msg, &packet);
    #ifdef MAVLINK10
    #else // MAVLINK10
      currentSMode = packet.mode;
      currentNMode = packet.nav_mode;
      battery = packet.vbat;
    #endif // MAVLINK10
      // decode
      mavlink_param_value_t packet;
      mavlink_msg_param_value_decode(msg, &packet);
      const char * key = (const char*) packet.param_id;

void send_message(mavlink_message_t* msg)
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
  uint16_t len = mavlink_msg_to_send_buffer(buf, msg);

  for(uint16_t i = 0; i < len; i++)

void start_feeds()
  mavlink_message_t msg;
  mavlink_msg_request_data_stream_pack(127, 0, &msg, received_sysid, received_compid, MAV_DATA_STREAM_RAW_SENSORS, MAV_DATA_STREAM_RAW_SENSORS_RATE, MAV_DATA_STREAM_RAW_SENSORS_ACTIVE);
  // mavlink_message_t msg3;
  mavlink_msg_request_data_stream_pack(127, 0, &msg, received_sysid, received_compid, MAV_DATA_STREAM_EXTENDED_STATUS, MAV_DATA_STREAM_EXTENDED_STATUS_RATE, MAV_DATA_STREAM_EXTENDED_STATUS_ACTIVE);
  // mavlink_message_t msg4;
  mavlink_msg_request_data_stream_pack(127, 0, &msg, received_sysid, received_compid, MAV_DATA_STREAM_RAW_CONTROLLER, MAV_DATA_STREAM_RAW_CONTROLLER_RATE, MAV_DATA_STREAM_RAW_CONTROLLER_ACTIVE);
  // mavlink_message_t msg1;
  mavlink_msg_request_data_stream_pack(127, 0, &msg, received_sysid, received_compid, MAV_DATA_STREAM_POSITION, MAV_DATA_STREAM_POSITION_RATE, MAV_DATA_STREAM_POSITION_ACTIVE);
  // mavlink_message_t msg5;
  mavlink_msg_request_data_stream_pack(127, 0, &msg, received_sysid, received_compid, MAV_DATA_STREAM_EXTRA1, MAV_DATA_STREAM_EXTRA1_RATE, MAV_DATA_STREAM_EXTRA1_ACTIVE);

void setup()

int start_count = 0;

void loop()

  if ((start_count< 3) && (millis() >(3000+(start_count * 2000)))) //send start feed after 3 seconds of powerup - need time for heartbeat to be received - try 3 times with 2 seconds between each try

void pids() // menu 2

void create_Remzibi_output()
//      Distance_Home=calc_dist(Latitude_Home, Longitud_Home, latitude, longitude);
//    Bearing_Home=calc_bearing(Latitude_Home, Longitud_Home, latitude, longitude);
//    SvBearingHome=Bearing_Home;
//    Angle_Home=ToDeg(atan((float)(altitude-Altitude_Home)/(float)Distance_Home));
//    Bearing_Home = 180-(Bearing_Home/2.0);
//    // Offset for servo limit
//    Bearing_Home = Bearing_Home + offset;
//    if (Bearing_Home > 180.0)
//       Bearing_Home = Bearing_Home - 180.0;
//    else
//    {
//        if (Bearing_Home <0.0)
//           Bearing_Home = Bearing_Home + 180.0;
//    }

     if (callsignprint>100) {

int availableMemory() {
  int size = 2048;
  byte *buf;

  while ((buf = (byte *) malloc(--size)) == NULL)

  return size;


Views: 9177


Reply to This

Replies to This Discussion

Hi Heino,

this would be nice. Even if I have to read how to compile it. I assume I can`t use a gcc compiler :) I read something about the ardurino (or something similar) compiler.

Is there any issue with testing different FW versions? I`m a bit afraid to break the device with the wrong Firmware (as I already did with an old iPhone :) )

I tried the Hazy Firmware without success.I had no OSD overlay and no message. Even the configtool was not able to connect to the OSD. I assume that it only works with the original remzibi OSD. Don`t now why because the hardware is the same. It just has some minor modifications.

Arduino uses the GCC computer internally - AVRGCC to be exact.

I've placed the source code to my converter here. This software is loaded onto an Arduino Pro mini ($18) board and converts Mavlink 1.0 (from the APM or ACM) to the Remzibi serial format it normally expects from a GPS module. This approach doesn't require changes to the ACM/APM firmware but does require the purchase of the Arduino Pro mini.

I'm using this with my Arducopter quad and it still works well for me.  

There isn't much of an issue with FW versions since the transition to Mavlink 1.0 happened several months ago. Mavlink doesn't change much from one version of the ACM software to another.


Hi Heino,

thanks for the link. I`ll try to get it running. I assume that I can upload the Firmware with Megaload to the serial link of the Ardurino Mini Prod Board. I just ordered one.

Sorry for all the questions, but I`m not really familiar with all the Firmware stuff on the chips. I`m from the server corner and there we get the Firmware from the vendors on DVD :)

But I think it can`t be that difficult ;)

I did not use the Hazy's frim.

When I did receive my Remzibi and GPS I did keep the original firmware and it worked fine.

Maybe the new firmware installed on GPS is not the good one for Remzibi, try to reset to original setup (I never did this)

The Arduino programming environment has the programming software built in and just requires a serial connection to a PC or MAC. Here is a link to the IDE:


I use a FTDI cable that goes from USB to serial to program the Arduino Pro mini, but any USB to serial adapter should work. 

When you install the Arduino 1.0.1 IDE, you just need to place the 2 folders in the zip into a folder, point the IDE at the containing folder and compile the software. You'll need to set the board type and serial port values in the IDE, and the upload command should communicate with the Arduino boot loader in the Arduino Pro mini. I'll be glad to help you if you have any problems.


Thanks, I`ll try that. I just did it because it is mentioned in the wiki :)

Hi Heino,

thanks a lot for your help. I checked your code and was surprised how simple it is to write such stuff. I`m not yet familiar with the language because I always used perl or bash, but I hope to be able to understand it soon.

HI Heino,

got the ardurino pro mini 5V 16MHZ today and was able to upload your code (after several fails and a lot of reading because I had to hold the reset button until I start the upload)

After connecting and triple checking all connections I`m still not able to get any GPS Signal from the APM 2.5.

The Firmware on the OSD 3DR is OSD_DIY32V1_75.HEX

The LED on the Ardurino is solid red (but it was always red) The green led is just blinking if I reset the Board.

How can I check if your code was successfully written and started by the ardurino board?I assume the board is delivered with a bootloader right?

Do I get any message on the screen during OSD startup?

I powered first the APM and then OSD and ardurino board together.

I opened the osdmavlink file with ardurino 1.0.1 and the remzibi file automatically opened. I compiled then and started the upload.

Binary sketch size was 13.554 Bytes. I included all libraries into the ardurino library folder (without any problems)

DO I need maybe to upload the file OSD Configuration Bin File (be sure to rename to .bin) to the OSD?

Update: I changed a bit in the code to see if it`s loading and I got a result: I used LED13 to check if it loads to void_setup and void_loop with success. Now the green led it`s blinking:)

What I don`t understand are the #ifdef commands. Are they commented out?

I also saw that the OSD should display several information after bootup of the ardurino board, but there is nothing else than the default output of the OSD. Is the problem maybe that I use the diydrones Firmware and Board? It`s not original remzibi but the remzibi OSD 3dr.

Thanks in advance

To see data on the OSD there have to be several things:
1. Mavlink must be started  such as Mission Planner starting the feed. I use the osd always with a ground station of some sort so nothing will show up until I start the feed from the APM.

2. Valid GPS data must be present.  The firmware is triggered by Mavlink GPS messages and then will generate the Remzibi messages. 

3. The software assumes Remzibi 1.75 version software which supports the custom messages displayed on the screen as well as the general NMEA like messages.  I'm not sure what 3DR loads by default on their Remzibi version, but the basic messages should trigger display of the OSD.  On my Remzibi - it will search for the proper baud rate before displaying anything - it will increment the baud rate until it detects traffic.  I start up my quad, get a good GPS fix and then power up my OSD and video transmitter.  I will see the Remzibi lock on at 57600 baud - which your Mavlink transmission should be set to.

I don't have much time to look at this right now, but in a couple of hours I can research what version of Remzibi is in the 3DR version and give your more info.


I did see you mentioned a 1.753DR software - I'll look at this to see - but it sounds like the right version for it to work.  The configuration bin file is only to configure the display to place the various data values in the right spot.  You can tailor this as you see fit, but one user did want to see what I used on my quad.

Also - if you'll never use a GCS with the APM, I can give you code to have the firmware send a start MAVLINK feed command - but you'll have to wire the Pro Mini's xmit back to the APM.

Reply to Discussion


© 2018   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service