Archived Projects
Summary
2017-19 | ArdSimX Interface
2015-17 | ArdSim Library
2014-15 | ARDref Interface
2013-14 | XPData library
2012-13 | Baron 58 program
2011-12 | First Tests with UDP
Here I have collected some of our first "pre-library" Arduino code developments since 2011, related to X-Plane UDP protocol, test code, evolution of algorithms for various input actuators, encoders, early code versions of Baron 58 cockpit program, etc..
Do not consider the samples collected here as practical or finished programs for you cockpit simulator!
These code samples are uploaded here for information purpose, some of them were written as tests programs for familiarizing with Ethernet UDP protocol used in X-Plane to adapt it for Ardino to get data from X-Plane and send data from Arduino to X-Plane.
Some of them ( such as "B58-final") were used in our Baron 58 simulator, before we switched to our later "library-plugin-based" interface.
As you could see, in the earlier program code the "DATA" type message protocol was used, and the size of the program code was huge. Later versions gradually become more compact, the "CMND" and "DREF" type messages was used as primary data protocol. The X-Plane inbuilt Ethernet UDP protocol initially was used in our Baron Arduino/X-Plane interface.
All these programs were tested with Arduino Mega 1280 and Ethernet shield 5100.Later, based on these works we have created Arduino libraries (XPData, ARDref, ArdSim) to replace a mess of single sketches. All these libraries were developed as a simple instrument for cockpit builders and they include several functions for sending input commands and dataref values to X-Plane and receiving data from it for output.
One of the first successful test to receive UDP packets from X-Plane. X-Plane UDP Data Structure analysis.(May 2012)
It receives UDP packets from X-Plane and show it in the terminal in the raw view.
/*
X-Plane UDP Data Structure
Test sketch that receives UDP packets from X-Plane in the raw view.
and prints to Serial terminal data of the group #131 ("ground location")
Check this group in the Data Input & Output Screen of the X-Plane for sending.
Packet size: 41
Xplane Data:
68-65-84-65-60-131-0-0-0-166-138-16-71-193-114-2-195-58-143-139-70-244-238-135-59-61-207-225-58-
0-192-121-196-0-192-121-196-0-192-121-196-
May 2012
Vlad S
http://simvim.com
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 6); // local IP - address of my Arduino
unsigned int localPort = 49001; // local port to listen - default X-Plane port
byte buf = 00; // buffer for UDP packet (BYTE, not char)
EthernetUDP Udp; // An EthernetUDP instance to send and receive packets over UDP
//-------------------------------------------------------------------------------
void setup()
{
Ethernet.begin(mac,ip); // start the Ethernet
Udp.begin(localPort); //..and UDP:
Serial.begin(9600); // init serial port
}
void loop() {
int packetSize = Udp.parsePacket(); // Checks for the presence of a UDP packet, and returns its size
if(packetSize) // UDP packet was received and its size defined
{
Serial.println();
Serial.print("Packet size: ");
Serial.println(packetSize); // Packet Size in bytes
// When Udp.read used without parameters, it returns next char (byte in this case) :
Serial.println("Xplane Data:");
for (int i =0; i < packetSize; i++)
{
buf = Udp.read();
Serial.print(buf);
Serial.print("-");
}
}
delay(10);
}
/*
Test sketch that receives UDP packets from X-Plane
and prints to Serial terminal data by the group index.
Shows - packet size, prefix, index (number) of the group
and eight 4-byte parameters:
********************************
Packet size: 41
Xplane Data:
68-65-84-65-64- - prefix DATA
67 - Index of the Group
72-122-74-62-
Dataref_Value = 0.20
152-38-184-62-
Dataref_Value = 0.36
112-34-224-62-
Dataref_Value = 0.44
0-0-0-0-
Dataref_Value = 0.00
0-0-0-0-
Dataref_Value = 0.00
0-0-0-0-
Dataref_Value = 0.00
0-0-0-0-
Dataref_Value = 0.00
0-0-128-63-
Dataref_Value = 1.00
*************************************
Check this groups in the Data Input & Output Screen of the X-Plane for sending.
May 2012
Vlad S
http://simvim.com
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 4); // local IP
unsigned int localPort = 49001; // local port to listen
byte buf = B10010; //
int ByteGroup;
int ByteVar;
long X[4]; // Byte array
float Dataref_Value; // Float result
int Index;
// Translate 4-byte to float
union u_tag {
byte b[4];
float fval;
} u;
//
EthernetUDP Udp; // An EthernetUDP instance to let us send and receive packets over UDP
//-------------------------------------------------------------------------------
void setup()
{
Ethernet.begin(mac,ip); // start the Ethernet
Udp.begin(localPort); //..and UDP:
Serial.begin(9600);
}
void loop() {
delay(50);
int packetSize = Udp.parsePacket(); // read a packet
if(packetSize)
{
Serial.println();
Serial.println();
Serial.print("Packet size: ");
Serial.println(packetSize);
// If using Udp.read without arguments, it returns next char (byte in this case) :
// in cycle - number of bytes, got from paketSize:
Serial.println("Xplane Data:");
ByteGroup = 0;
ByteVar = 0;
Index = 0;
// allocate DATA
for (int i =0; i < 5; i++)
{
buf = Udp.read();
Serial.print(buf);
Serial.print("-");
}
Serial.print(" - prefix DATA");
Serial.println();
// data reding cycle
for (int i = 5; i < packetSize; i++)
{
buf = Udp.read();
// data not index
if (ByteGroup > 3)
{
Serial.print(buf);
Serial.print("-");
X[ByteVar] = buf;
}
// index number in the group
if (ByteGroup == 0)
{
Index = buf;
}
ByteGroup++;
ByteVar++;
if (ByteGroup == 4)
{
Serial.print(Index);
Serial.print(" - Index of the Group");
Serial.println();
}
// End of Data group
if (ByteGroup == 36)
{
Serial.println();
ByteGroup = 0;
}
// End of variable
if (ByteVar == 4)
{
Serial.println();
ByteVar = 0;
if (ByteGroup > 4 || ByteGroup == 0)
{
u.b[0] = X[0];
u.b[1] = X[1];
u.b[2] = X[2];
u.b[3] = X[3];
Dataref_Value = u.fval;
Serial.print(" Dataref_Value = ");
Serial.print(Dataref_Value);
Serial.println();
Serial.println();
}
}
}
}
}
One of the first practical sketch that receives UDP packet from X-Plane and outputs specific data. (May 2012)
It receives UDP packet, selects a group #67 (Gear) from the packet and sends it to the servo.
/*
Test sketch that receives UDP packet from X-Plane
and controls Servo.
(Servo shows position of the Gear #1 )
May 2012
Vlad S
http://simvim.com
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Servo.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 4); // local IP
unsigned int localPort = 49001; // local port to listen
byte DataBuf[200]; //
float Dataref_Value; // Float result
// Vars
float Gear1 = 0; // Gear #1 position
// Translate 4-byte to float
union u_tag {
byte b[4];
float fval;
} u;
//
Servo GearGauge; // servo object #1
int GearVar; // position variable
EthernetUDP Udp;
//-------------------------------------------------------------------------------
void setup()
{
GearGauge.attach(9); // attaches on pin 9
GearGauge.writeMicroseconds(1400); // set initial position
Ethernet.begin(mac,ip); // start the Ethernet
Udp.begin(localPort);
}
void loop() {
GearVar = map(Gear1, 0, 1000, 2000, 1000);
GearGauge.writeMicroseconds(GearVar);
delay(5);
int packetSize = Udp.parsePacket(); // read a packet
if(packetSize)
{
Udp.read ( DataBuf, packetSize ); // read all packet to Data buffer
for (int i = 5; i < packetSize; i += 36) // check each 36-th byte for group index number
if ( DataBuf[i] = 67) { // -- if index number=67, this is the group "Gear"
u.b[0] = DataBuf[i+4]; // -- read the first 4 bytes after index - Gear #1
u.b[1] = DataBuf[i+5];
u.b[2] = DataBuf[i+6];
u.b[3] = DataBuf[i+7];
Dataref_Value = u.fval; // -- tranlate 4-byte to float ( dataref value)
Gear1 = Dataref_Value*1000; // -- Gear #1 position
}
}
}
/*
Sample code:
Receiving Data from X-Plane
Serial monitor shows Com1 frequency as separate digits (for 7-segment output) and as number (for LCD output)
http://simvim.com
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//-----------------------------
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip; // Arduino IP address
IPAddress ipx(192, 168, 1, 8); // X-Plane IP address
unsigned int localPort = 49001; // port to listen to get UDP packets
unsigned int XP = 49000; // port to send UDP packets
EthernetUDP Udp; // EthernetUDP instance to send/receive packets over UDP
byte DATA_buf[500]; // UDP.read buffer [size] /
int Data_in; // Incoming Data from X-Plane (ret. size of received packet)
char trans[5];
byte dcom1[5];
int com1;
//-------Unions allow the same location of memory to be accessed as different data types.
union { byte bytevalue[4];
float floatvalue; } bf;
//================= setup ===========================================
void setup() {
Ethernet.begin(mac); // start the Ethernet connection:DHCP
ip = Ethernet.localIP(); // Set local IP
Ethernet.begin(mac,ip);
Udp.begin(localPort);
//----------------------------------
Serial.begin(9600);
}
//========= Setup End ===========
//------------------------ Program start ------------------------------------------------
void loop()
{
//========================= RECEIVING DATA FROM X-PLANE ====================================
//---------------------------- UDP-Packet Reading )-------------------
Data_in = Udp.parsePacket(); // Checks for the presence of a UDP packet, and returns its size
// if (Data_in)// UDP packet was received and its size is defined
if (Udp.available())
{
Udp.read ( DATA_buf, Data_in ); // Reads UDP data from the specified buffer.All incoming DATA stores in DATA_buf
// reading Indexes each 36 bytes, begining with byte #5 (following the header "DATA0"):
for (int i = 5; i < Data_in; i += 36)
{ switch (DATA_buf[i]) // find indexes specified below (96)
{
case 96: for (int n=0; n<4; n++) bf.bytevalue[n] = DATA_buf[i+8+n];
com1 = int(bf.floatvalue);
itoa(com1, trans, 10); Serial.print(trans); // option for LCD output
for (int n=0; n<5; n++) dcom1[n] = trans[n] & 15;
Serial.println();
Serial.print(dcom1[0]); Serial.print(" ");
Serial.print(dcom1[1]); Serial.print(" "); // Print 5 digits of com1
Serial.print(dcom1[2]); Serial.print(" ");
Serial.print(dcom1[3]); Serial.print(" ");
Serial.print(dcom1[4]); Serial.print(" ");
Serial.print(" ");
break;
}
}
}
// =================================== END of UDP packed Reading =====================
}
//------------------------ End ---------------------