Hi,
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
http://store.diydrones.com/Adapter_cable_for_APM_2_5_p/kt-apm25-cable.htm
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)
<code>
// 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>
//AP_EEPROMB ee;
#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?
FastSerialPort0(Serial);
// data streams active and rates
#define MAV_DATA_STREAM_POSITION_ACTIVE 1
#define MAV_DATA_STREAM_RAW_SENSORS_ACTIVE 1
#define MAV_DATA_STREAM_EXTENDED_STATUS_ACTIVE 1
#define MAV_DATA_STREAM_RAW_CONTROLLER_ACTIVE 1
#define MAV_DATA_STREAM_EXTRA1_ACTIVE 1
// update rate is times per second (hz)
#define MAV_DATA_STREAM_POSITION_RATE 1
#define MAV_DATA_STREAM_RAW_SENSORS_RATE 1
#define MAV_DATA_STREAM_EXTENDED_STATUS_RATE 1
#define MAV_DATA_STREAM_RAW_CONTROLLER_RATE 1
#define MAV_DATA_STREAM_EXTRA1_RATE 1
#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
while(Serial.available())
{
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) {
case MAVLINK_MSG_ID_HEARTBEAT:
{
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;
break;
}
case MAVLINK_MSG_ID_ATTITUDE:
{
// decode
mavlink_attitude_t packet;
mavlink_msg_attitude_decode(msg, &packet);
pitch = toDeg(packet.pitch);
yaw = toDeg(packet.yaw);
roll = toDeg(packet.roll);
break;
}
#ifdef MAVLINK10
case MAVLINK_MSG_ID_GPS_RAW_INT:
#else // MAVLINK10
case MAVLINK_MSG_ID_GPS_RAW:
#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;
create_Remzibi_output();
break;
}
case MAVLINK_MSG_ID_GPS_STATUS:
{
mavlink_gps_status_t packet;
mavlink_msg_gps_status_decode(msg, &packet);
// numSats = packet.satellites_visible;
// Serial.print(numSats);
break;
}
case MAVLINK_MSG_ID_RAW_PRESSURE:
{
// decode
mavlink_raw_pressure_t packet;
mavlink_msg_raw_pressure_decode(msg, &packet);
break;
}
case MAVLINK_MSG_ID_SYS_STATUS:
{
mavlink_sys_status_t packet;
mavlink_msg_sys_status_decode(msg, &packet);
#ifdef MAVLINK10
battery=packet.voltage_battery;
#else // MAVLINK10
currentSMode = packet.mode;
currentNMode = packet.nav_mode;
battery = packet.vbat;
#endif // MAVLINK10
break;
}
case MAVLINK_MSG_ID_PARAM_VALUE:
{
// decode
mavlink_param_value_t packet;
mavlink_msg_param_value_decode(msg, &packet);
const char * key = (const char*) packet.param_id;
break;
}
}
}
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++)
{
Serial.write(buf[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);
send_message(&msg);
delay(10);
// 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);
send_message(&msg);
delay(10);
// 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);
send_message(&msg);
delay(10);
// 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);
send_message(&msg);
delay(10);
// 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);
send_message(&msg);
delay(460);
}
void setup()
{
Serial.begin(SERIAL_BAUD);
delay(300);
}
int start_count = 0;
void loop()
{
gcs_update();
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
{
start_feeds();
start_count++;
}
}
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;
// }
print_GPGGA();
delay(30);
print_GPRMC();
delay(30);
print_sonar();
delay(20);
callsignprint++;
if (callsignprint>100) {
print_remzibi_mode();
delay(20);
callsignprint=0;
}
}
int availableMemory() {
int size = 2048;
byte *buf;
while ((buf = (byte *) malloc(--size)) == NULL)
;
free(buf);
return size;
}
</code>
Replies
I've only tried this on the APM. I don't have any 32 bit hardware so although in principle it could work, I'm not sure. Also, there well could be Mavlink changes since this software is so old.
Heino
HELLO, THIS WORKS FOR IO PX4 FMU?
Thank you.
Hi Heino,
thank you very much. It`s working now. I`ve posted the complete code at the start page of this thread and will update the wiring picture ( I`ll can take your picture if it`s ok for you).
If I can help you somehow, just let me know.
/Stefan
I`m back with some more information.
It seems that I don`t get any feedback from the APM.
void gcs_update()
{
mavlink_message_t msg;
mavlink_status_t status;
while(Serial.available())
{
uint8_t c = Serial.read();
// Try to get a new message
if(mavlink_parse_char(0, c, &msg, &status)){
gcs_handleMessage(&msg); // Here we don`t get any messages because if statement is false.
}
}
}
I`ve set the baudrate to 57 which is correct and it even can detect the serial connection to the apm (while serial.available is true)
As far as I understand well, the XBEE is establishing e mavlink connection to the apm and the ardurino pro mini is just listening the traffic. How can I get it running without the XBEE? Is there a function to establish the mavlink connection which we can use on the pro mini?
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?
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.
OK, the second GPS is not connected and the OSD is able to find it BUT:
I don`t get the GPS data on the OSD. altitude, speed, satellites, latitude and longitute are not displayed.
Does anyone have an idea why? I`ve updated the GPS Firmware with the original one to work with the OSD. Do I need to change settings on the OSD?
Thanks in advance
As I know Remzibi OSD 3DR is not compatible with APM, see notice from website "NOTE: This product is not compatible with the APM 2.0."
You are using APM2.5, but I understood the mavlink protocol is the same as APM2.0.
There is someone who makes Remzibi OSD 3DR working with APM2.0, but he use an intermediate board for protocol adapting, I dont have the link, but is on DIYDrones.
I am curios if you can user your Remzibi with APM2.5 with one GPS , I have same setup but using 2 GPS...