SimVimCockpit Interface Baron-58 sim Blog About

Arduino to X-Plane code development archive

First UDP tests (2011-2012)

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);
}


  
   




One of the first tests to analize UDP packets from X-Plane (May 2012).
It receives UDP packets from X-Plane, splits them into the groups and shows all 8 4-byte parameters in the group and their values.
Check this groups in the Data Input & Output Screen of the X-Plane for sending.


/*
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.



Video of this test with 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
            }
        } 
          
    }
  


  
   




One of the practical sketch that receives UDP packet from X-Plane and outputs specific data. (2012)
It shows Com1 frequency as separate digits (for 7-segment output) and as number (for LCD output). Auto IP detection




/*
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 ---------------------     
  
   







© Copyright 2012-2016 - SimVim