| SimVimX System | | HARDWARE CONFIG TOOL TECH TIPS | | Panels | Baron 58
menu

Main Configuration and Conversion Tool

Baron-58 panel, Data Input/Output

Arduino code

When starting this project a lot of test code for Arduino was written, to clarify all aspects of data exchange between Arduino and X-Plane, using inbuilt UDP protocol of X-Plane. Here are some of these code samples - Evolution of Arduino I/O interface.

In the earlier test 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 are now used as primary data protocol. The "DATA" type is used only for reading data from X-Plane. (More info about X-Plane's UDP data input structure here: http://www.nuclearprojects.com/xplane/xplaneref).

Later, since summer 2014 all this work and test sketches were revised and organized in a single Arduino library that includes functions for network interaction between Arduino and X-Plane, functions of receiving and decoding any of X-Plane incoming data, functions for transmitting data to X-Plane. It makes Arduino programming for users as simple as possible - you only need to define the pin number and its function (button, switch, encoder, axis, etc.).

The Arduino program monitors all inputs in each cycle, but if no changes were detected, it does not transmit anything to X-Plane. if the program detects that the position of any of the controls was changed, it immediately sends the specific packet via Ethernet. In general, the whole process of data sending (in newest B58 code editions) takes 1-5 milliseconds in one cycle.

In the last versions of the Baron code the XPData library is used and data from X-Plane is received using ARDref plugin (no need to define data groups for output in the "Data Input/Output" X-Plane menu).

 


About X-Plane Data Input/Output structure

You can read about the structure of UDP used in X-Plane in its documentation, located in the folder "X-Plane/Instructions/Sending Data to X-Plane.html", or the same one on this page: http://www.nuclearprojects.com/xplane/xplaneref. Here I present a description of the four formats of data that I have used in Baron project : DATA, DREF, CMND and CHAR.

Each UDP packet to be transmitted to X-Plane has a Header. It consists of 5 bytes. The first four bytes are ASCII (decimal) code for one of the key words: DATA, CHAR, DREF (and many others types of data described in the documentation). The fifth byte should be "0" (decimal 48) when sending to X-Plane, or "<" (decimal 60) char when used by X-Plane (though both are working when sending).

68 65 84 65 48(60)header DATA< Used when X-Plane sends data selected in the "Data Input/Output screen"
68 82 69 70 48(60)header DREF
67 72 65 82 48(60)header CHAR
77 79 85 83 48(60)header MOUS
77 79 85 83 48(60)header MENU
--...and so on

Structure of the "DATA" packets in X-Plane (sending/receiving)


This format is used by X-Plane to send data to other networked computers. A minimum one group that includes 8 parameter values can be sent.

HeaderIndex32 bytes of Data - 8 sim parameters in the format of 4-byte floating point numbersNext index
68-65-84-65-60131-0-0-0166-138-16-71193-114-2-19558-143-139-70244-238-135-5961-207-225-580-192-121-1960-192-121-1960-192-121-196133-0-0-0

The next four bytes following the header are the index of the Group in the Data Input & Output screen in decimal from 0 to 133 (only the first byte is used):

13 00 00 00group index #13 - trim/flap/slat/s-brakes

The next 32 bytes represent the data of 8 parameters of one group (4 bytes x8 ) . Each 4-byte block is a floating point value of one parameter.
Even if this parameter is not such numeric value as speed, but only a boolean 0 or 1, it is also represented as 32-bit floating point number split into 4 bytes.

Three useful numbers in the 4-byte f/p

0 0 0 0 0"0"can be used as a numeric 0 and a boolean "0"
0 0 128 63"1"can be used as a numeric 1 and a boolean "1"
0 192 121 196"-999"the number -999, send when the parameter in this group should not to be changed

See the - IEEE 754 floating point converter

To control X-Plane using this DATA method, Arduino should send data to X-Plane in the same format as the simulator sends it (program should form the same packets of data, i.e. [header DATA0]+[Number of the group]+[8 float Data parameters] ). That is a highly inconvenient way.

In our first tests with X-Plane UDP code I have used the "DATA" format, but quite soon we threw it away in favor of other formats (DREF, CMND). "DATA" was used only for receving data from X-Plane.

Structure of the "DREF" packet sending to X-Plane

To be correctly received by X-Plane, the whole string length should be 504 bytes (4-bytes Value + dataref string + ending string)
I.e. for dataref for com1 - "sim/cockpit2/radios/actuators/com1_standby_frequency_hz[0]" (58 bytes) we need to add 500-58=442 "space" char(char 32).
501st byte should be "ending NULL char" (char(0)).

DREF HeaderValue (10920Hz)Dataref stringending fields
"DREF0"0, 160, 42, 70"sim/cockpit2/radios/actuators/com1_standby_frequency_hz[0]""                      "

When using UDP DREF method, Arduino sends data in the format: [header DREF0]+[Value in float]+[X-Plane dataref string]+[End sequence].

If you're using our XPData Arduino library, you don't need to add all the ending "space" characters manually - the library function will do it for you.

 

Structure of the "CHAR" packet sending to X-Plane

CHAR is easiest way of sending commands to sim, but this method is limited by the number of keyboard symbols and we need to assign each command a key in X-Plane.

CHAR Headercharacter
"CHAR0""D"

 

Structure of the "CMND" packet sending to X-Plane

(added in november,2013)

Another very convenient way to send control parameters to X-Plane. After all, I've chosen this method for most of the controls, after reading the article "DataRefs Vs. Commands" on "X-Plane Developer". CMND combines both simplicity of CHAR method and usability of DREFs

CMND HeaderCommand string
"CMND0""sim/flight_controls/landing_gear_down"

 


Data received by Arduino

When DATA format was used to receive data from X-Plane for this Baron-58 simulator Arduino received 18 parameters ( 11 groups of DATA chosen in the "Data Input & Output" menu of X-Plane), to output them to indicators/annunciators and servos (fuel and bus gauges).

A listing of the UDP data groups is located at the Data Input & Output screen in X-Plane. Currently there are 133 channels/groups, each of them may contain up to 8 parameters, or up to 1064 data refs altogether.
To find out what of the parameters each channel includes, select some groups for output to the Cockpit View when flying. Using the Datarefs Editor, we can correlate this parameters with corresponding datarefs.

DATA groups received from X-Plane by UDP (checked in the Data Input & Output Screen):

 

Parameters in the DATA groups used by Arduino for :

 

(In the latest versions of the code the XPData library is used and all DataRef values from X-Plane are received using ARDref plugin (no need to define data groups for output in "Data Input/Output" X-Plane menu).

Floating point values

UDP protocol is targeted to the transfer byte (char) stream, so, in order to transmit a 32-bit floating point value, before submitting it just splits into 4 binary bytes and then transmitted as 4 separate symbols.

Take for example the number 4500 feet. Its floating point representation is the next sequence of bits (first left is the sign bit):

01000101100011001010000000000000 - floating point number +4500
01000101100011001010000000000000 - split into 4 bytes
691401600 - ASCII (decimal) representation

So, X-Plane will send the value 4500 as a 4-byte block 0-160-140-69.

Upon being received by the controller these 4 bytes must be read back as a floating point value. This does not need to be a transformation of variables, we only need to unite 4 bytes back to the 32 bits, which must be a variable of floating point type.

The best way to do it is to use a special data type structure of C, that called union.

The union is building such a memory structure where two or more members can share the same location in the memory. It means the program can access it as different data types, e.g. assign as bytes and read as floating, and vice-versa. A union variable represents the value of only one of its members at a single moment.

 union {
        char name1[4];        // --- first variable -  char or byte array 
        float name2;          // ---- second variable - float
        }  proc;              // ---- put the 4 bytes in proc.name1, get the float from proc.name2 (or backwards)

As written above, if a parameter is presented as boolean 0 or 1, it is also transmitted as a 32-bit floating point number. But in this case we may omit the union use. All we need is just to check if the 3rd or 4th byte is 0 or not.

Support the project by subscribing to our Patreon

dwn dwn dwn
RealSimControl / SimVim / SimVimX 2012 - 2023