Hi all,
I'm writing a program to control APM 2.6 (running Arducopter 3.2.1) via the telemetry port. I can receive heartbeat packets from the APM, but whatever MAVLink packets I send to the APM simply get echoed back to me. See attached screenshot for what I mean.
Even heartbeat packets from my program to the APM are being echoed back to me. My system has system ID of 255, while the APM has system ID of 1. You can also see the parameter list request (message ID 21) and data stream request (message ID 66) being echoed back to me, and ignored by the APM. I've tried this with several APM 2.5 and 2.6 modules, all exact same result. I've also tried it with motors armed, same result.
This code is running on an Arduino Mega 2560. The 2560 is connected via UART1 to the APM's telemetry port.
This is my code on the Arduino Mega for sending out the heartbeat, parameter list and data stream request packets to the APM:
void send(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++)
Serial1.write(buf[i]);
}
void CArdGCS::requestDataStream(uint8_t target_system, uint8_t target_component, uint8_t req_stream_id, uint16_t req_message_rate, uint8_t start_stop)
{
mavlink_message_t msg;
mavlink_msg_request_data_stream_pack(255, 0, &msg, received_sysid, received_sysid, MAV_DATA_STREAM_RAW_SENSORS, 1, 1);
send(&msg);
}
// Request parameter list
void CArdGCS::requestParamList(uint8_t targetSystem, uint8_t targetComponent)
{
mavlink_message_t msg;
mavlink_msg_param_request_list_pack(255, 1, &msg, 1, 1);
send(&msg);
}
This is the code for processMessage, which gets called whenever a character comes in from Serial1:
void CArdGCS::processMessage(mavlink_message_t msg)
{
// Empty
#ifdef MYDEBUG
char buffer[64];
#endif
switch(msg.msgid)
{
mavlink_heartbeat_t heartbeat;
case MAVLINK_MSG_ID_HEARTBEAT:
mavlink_msg_heartbeat_decode(&msg, &heartbeat);
#ifdef MYDEBUG
sprintf(buffer, "Heartbeat: Status: %d from system %d component %d\n", heartbeat.system_status, msg.sysid, msg.compid);
received_sysid=msg.sysid;
received_compid=msg.compid;
Serial.print(buffer);
#endif
break;
case MAVLINK_MSG_ID_STATUSTEXT:
mavlink_statustext_t statustext;
mavlink_msg_statustext_decode(&msg, &statustext);
#ifdef MYDEBUG
sprintf(buffer, "Status: Severity %d Text %s\n", statustext.severity, statustext.text);
Serial.print(buffer);
#endif
break;
default:
#ifdef MYDEBUG
sprintf(buffer, "Unknown message id: %d from system %d component %d\n", msg.msgid, msg.sysid, msg.compid);
Serial.print(buffer);
#endif
break;
}
}
Finally this is the event loop that polls for characters from Serial1, parses it and calls processMessage:
// The event loop. We never exit from this.
void CArdGCS::eventLoop()
{
char ch;
mavlink_message_t msg;
mavlink_status_t status;
while(1)
{
if(Serial1.available())
{
ch=Serial1.read();
if(mavlink_frame_char(_stationNum, ch, &msg, &status)!=MAVLINK_FRAMING_INCOMPLETE)
processMessage(msg);
}
}
}
I've been stuck on this for days.. I would really appreciate any help!
Many thanks!
Colin.