Hi Everyone,
I'm started to develop a Plugin for X-Plane (a well known flight simulator) which should send data from instruments to my Arduino which then should display it. In a second step the Arduino also should send back data.
I took the existing XHSI X-Plane plugin as a base, because it contains everything i need for my plugin and some more stuff.
There i have the functions which get the data and sends it to an IP address by UDP.
The Arduino receives the data, thats good so far. But then i can't get out the data correctly.
Because the XHSI plugin used a struct, i wanted to keep that. It looks like this (in Visual C++):
struct SimDataPoint {
int id;
float value;
};
struct SimDataPacket {
char packet_id[4];
int nb_of_sim_data_points;
struct SimDataPoint sim_data_points[150];
};
And the code part which constructs the packet and sends it to Arduino:
struct SimDataPacket sim_packet;
int createAvionicsPacket(void) {
int i = 0;
int packet_size;
strncpy(sim_packet.packet_id, "AVIO", 4);
sim_packet.sim_data_points[i].id = custom_htoni(SIM_COCKPIT_AUTOPILOT_HEADING_MAG); // id=154
sim_packet.sim_data_points[i].value = custom_htonf(XPLMGetDataf(autopilot_heading_mag)); // 0-359
i++;
// now we know the number of datapoints
sim_packet.nb_of_sim_data_points = custom_htoni( i );
// packet size : char[4] + int + ( # * ( int + float) )
packet_size = 8 + i * 8;
return packet_size;
}
// This is sent to the Arduino in another function:
res = sendto(sockfd, (const char*)&sim_packet, packet_size, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr));
The code to parse it on the Arduino:
// Defined the same struct
struct SimDataPoint {
int id;
float value;
};
struct SimDataPacket {
char packet_id[4];
int nb_of_sim_data_points;
struct SimDataPoint sim_data_points[150];
};
byte DATA_buf[500];
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize) { // UDP packet was received
Udp.read(DATA_buf,packetSize);
// Output everything received
for (int i = 0; i < packetSize; i++) {
Serial.print(DATA_buf[i]);
}
Serial.println();
// Read the received data into struct
SimDataPacket* recv_data = (SimDataPacket*)DATA_buf;
Serial.print("Type: ");
Serial.print(recv_data->packet_id);
Serial.print(" - Datapoints: ");
Serial.print(recv_data->nb_of_sim_data_points);
Serial.print(" - ID: ");
Serial.print(recv_data->sim_data_points[0].id);
Serial.print(" - Value: ");
Serial.println(recv_data->sim_data_points[0].value);
}
}
But if i look at the output, i get wrong values.
All values from the output below, except “Value”, should be the same on all packets:
Type: AVIO
Datapoints: 1
ID: 154
Value: 0-5
0 // The expected value
6586737900010001540000 // Received data
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00 // Values from struct (Type - Datapoints - ID - Value)
1
6586737900010001546312800
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00
2
65867379000100015464000
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00
3
658673790001000154646400
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00
4
6586737900010001546412800
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00
5
6586737900010001546416000
Type: AVIO - Datapoints: 0 - ID: 256 - Value: -0.00
The first value in the struct (the Type) is correct, but i even wasn't able to display the second value (Datapoints) correctly.
While searching around for many many hours, i saw posts that using structs on different systems to transfer data could be complicated. Also that f.ex. the number of bytes for an "int" is different on Visual C++ and the Arduino (also tried "long" instead of "int" on the Arduino, no success). Tried around a lot of stuff but nothing made it better.
Also recognised that the received data has different lengths depending on the value sent, no idea why...
Maybe there is a better and simpler way to submit data from Visual C++ to Arduino?
I have no more ideas at the moment and every hint would be appreciated.
Thank you very much
Urs