Jump to content

Recommended Posts

Posted (edited)

Ok as requested by a number of people heres my little guide (part 1 anyway) on ONE way to export some of data on the radio panels out of DCS onto some 7 segment LEDs. Why? Just because i wanted to try it :)

 

Firstly, im standing on the shoulder of giants, a lot of what im going to talk about has already been done and explained in depth on this forum. Im just bundling it all together and explaining how it links up.. If at any point i tread on someones toes i apologise, let me know and ill amend the post.

 

Second lets explain how we are going to do it.

 

1. Exporting the data from DCS.

 

The data that drives whatever instrument panels you are building needs to come from somewhere. Its coming from DCS but to use it you need to get it out and in a usable format. We're going to use HELIOS to deliver that.

 

2. Modify your data into something that your Arduino sketch can work with.

 

I dont want to do too much coding on the arduino platform so im going to use my desktop (or another if needs be) to model/map any data. DCS exports data that needs to be translated to realworld values. In some cases we are translating switch positions to numerical data. Also this application needs to be able to listen on a UDP port for this data and transmit it out over serial.

 

3. Connect an arduino and write a simple sketch (code) to receive the data being received over the serial interface. Convert that data to electronic outputs (the LEDs).

 

4. Validate the data on your LEDs. Mk 1 Eyeball. Existing software/interface already exists, you shouldnt need to change this :)

 

 

Step 1.

 

Install HELIOS. Get it from here http://www.gadrocsworkshop.com/helios/.

Run the setup.

 

Open the profile editor.

 

 

Click Profile

Add interface

Select DCS A10c.

Capture-1.png

 

When the DCS A10C interface window opens, find the A-10 Setup section and click on Setup DCS A-10C

Capture1.png

This has now created an export.lua file on your file system. For me (Windows 8.1) its in this folder

 

C:\Users\Joe\Saved Games\DCS\Scripts

 

Open the export.lua in a text editor (I use Notepad++ http://notepad-plus-plus.org/download/v6.5.3.html - it has native lua support and will do syntax highlighting, but you can use notepad if you want)

 

This file is the heart of the HELIOS app, it collates a huge amount of data from DCS and formats it for you. Then it sends it out as a UDP packet to a specific IP Address and Port endpoint. We are going to be incredibly cheeky and hitch hike on back of this wonderful script.

 

Navigate to the bottom of the file and find this bit of code

 

function FlushData()

if #gSendStrings > 0 then

local packet = gSimID .. table.concat(gSendStrings, ":") .. "\n"

socket.try(c:sendto(packet, gHost, gPort))

gSendStrings = {}

gPacketSize = 0

end

end

 

Add this line after socket.try.....

socket.try(c:sendto(packet,gHost,65002))

 

so that it looks like this.

 

function FlushData()

if #gSendStrings > 0 then

local packet = gSimID .. table.concat(gSendStrings, ":") .. "\n"

socket.try(c:sendto(packet, gHost, gPort))

socket.try(c:sendto(packet,gHost,65002))

gSendStrings = {}

gPacketSize = 0

end

end

 

Now save the file. ( If you want to send this to another server, change gHost in the 2nd socket.try to socket.try(c:sendto(packet,"192.168.1.5",65002)) Change the ip address to the one you want to send it to.

 

When you start DCS and fly a mission you are now streaming 2 sets of data. One to HELIOS on port 9089, and another to port 65002.

 

*CAVEAT* If you click that Setup DCS A10C button again it will rewrite your export.lua and you'll lose your changes so just remember to update it. You could follow the advice to use the 3rd party scripts function but for the life of me i couldnt get it to reliably work as everytime i used it HELIOS functionality would stop working and this is much easier and quicker for new starters.

 

2. OK next, lets create a UDP listener application. This is NOT hard, well not if you have someone to tell you how to do it :)

 

First if you dont have Visual Studio, lets download it. Its free. http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop

Install and run it.

Select new project

Image1.png

In the New Project dialog, select Visual C#\Windows from the Templates tree, and Windows Forms Application

Image2.png

Enter a name, I called mine UDPListener (WindowsApplication1 isnt very catchy is it?

Click OK.

 

 

Click Toolbox label

Image3.png

 

Click on the pin, it fixes the flyout window.

Image4.png

In the form designer, resize the form dialog. Double its size. Do this by dragging one of the forms edges.

 

In the toolbox click on All Windows Forms

Image5.png

Scroll down until you find Textbox

 

Click and drag onto the Form designer, should look like this

Image6.png

On the right hand side is the Properties dialog.

Click on the textbox you dragged onto the form. The context of the properties dialog changes to textBox1

Image8.png

Using the scrollbar dragdown until you find the Multiline entry. HINT there is a little button icon that allows you to sort all the properties Alphabetically. Look under the letter B in textBox.

Click on False, a dropdown arrow appears, click on it. Select True.

 

Your textbox changed slightly, it now has drag points on the corners

Image9.png

 

Click the bottom right dragpoint and resize the textbox to half the forms width and height

 

 

Ok now find Button in the toolbox and drop it on the form as well.

 

Add three more buttons please.

 

Click on each button in turn, and in the properties window find (name) if you sorted the list its at the top.

Click on button1 and change it to buttonUDPON

Now find the Text Property and set it to UDP ON. Your button has now changed to something a little more friendly.

By amending the (Name) and Text properties do the following.

Change button2 to buttonUDPOFF - UDP OFF

Change button3 to buttonCOMON - COM ON

and finally button4 to buttonCOMOFF - COM OFF

UDP OFF and COM OFF wont fit on the buttonso resize them a touch until the text appears.

 

Underneath the buttoms add another textbox, set the multiline option and resize it.

 

Finally find SerialPort on the toolbox, its in the Components section. Drag that onto the form. You will see

serialPort1 appear at the bottom of the form designer.

 

Should look something like this....

Image10.png

 

In the Form Designer double click on Form1. The editor opens.

Add the following lines (c# code is case sensitive so make sure you copy exactly)

Under Form1() also added the following code

private void SendSerialData(string function, string value)

{

if (COM)

{

string sendthis = "*" + function + "-" + value + "#";

char[] c = sendthis.ToCharArray();

serialPort1.Write(c, 0, c.Length);

}

}

 

private void ProcessData( string data)

{

string[] d2 = data.Split( '=');

 

if (d2.Length != 2)

return;

switch (d2[0])

{

 

case "2251":

// textBoxILS.Text = d2[1].ToString();

switch (d2[1].ToString().Substring(0, 3))

{

case "0.0":

SendSerialData( "101", "108" );

break;

case "0.1":

SendSerialData( "101", "109" );

break;

case "0.2":

SendSerialData( "101", "110" );

break;

case "0.3":

SendSerialData( "101", "111" );

break;

default:

break;

}

break;

default:

break;

}

}

 

 

 

Click on the Form1.cs(design) tab at the top.

 

Double click on UDP ON - this auto generate the click event for the button and open the code editor again.

 

Add the following code so it looks like this.

 

private void buttonUDPON_Click( object sender, EventArgs e)

{

done = false;

UdpClient listener = new UdpClient(listenPort);

IPEndPoint groupEP = new IPEndPoint (IPAddress .Any, listenPort);

string received_data;

byte[] receive_byte_array;

try

{

while (!done)

{

receive_byte_array = listener.Receive( ref groupEP);

received_data = Encoding.ASCII.GetString(receive_byte_array, 0, receive_byte_array.Length);

if (received_data.Length > 0)

textBox1.Text = "";

string[] r = received_data.Split( ':');

foreach ( string s in r)

{

ProcessData(s);

textBox1.Text += s + Environment.NewLine;

}

Application.DoEvents();

}

}

catch ( Exception ex)

{

textBox1.AppendText(ex.ToString());

}

listener.Close();

}

 

Go back to the form editor and double click on the UDP OFF button to generate the click event.

 

This one is easy. Add this line

 

done = true;

 

 

 

Ok this ends part 1, but wait we want to see this in action dont we? To test this start DCS, launch a mission - i normally sit on the tarmac in campaign mode. Once the game is running goto your VS session and click the green arrow. That will compile your code into a debug version. The form will open, click on UDP ON. All going well you're now receving a UDP stream direct from DCS!!!

 

In part 2 i'll expand your app to use a serial port to communicate with your arduino(assuming you have one!)

UDPListener.zip

DCS_OUTPUT_TO_MULTIPLE_7SEG.zip

Edited by Devon Custard
  • Like 4
Posted

Thanks DC, that's a wonderfully detailed explanation of a lot of the basics - certainly helps someone like me who hasn't a clue on the coding front.... ok.. heading out to find myself an Arduino board :)

Posted

A great and much needed tutorial, nice one!

PC spec: i9 9900KS @ 5.1ghz, 32GB RAM, 2 TB NVME M2, RTX 3090

Peripherals: TM Warthog, Saitek Pro Flight Pedals, Rift S, Custom UFC

Posted

Very nice DC. Thanks for the write up. Very informative and I am looking forward for more info.

 

A very small comment. Instead of writtting a listner this one works very nice http://udp-test-tool.software.informer.com/

 

A small question. Is there any special reason for transmiting via serial to the Arduino? I would imagine that using a Ethernet shield on the Arduino is much easier.

 

Really looking forward for the next write up from you :thumbup:

 

All the best

Hans

Posted

Thanks HMA, always appreciate comments :)

 

Why writing a UDP listener? Like i said its only one way to do it, there are many others. But my reasons for doing it this way were...

 

1. No experience with writing UDP code on the arduino. But plenty in C#

2. The arduino comes with a USB interface which provides serial comms already. The serial monitor is easier to use to debug (for me at this point, purely because im still learning the arduino)

3. More component = more cost.

4. Im probably going to run more than one board. At which point i might switch over to Gadrocs EOS bus if he has the libraries to drive 7 seg / alpha numeric displays. Either way using one UDP listener means im putting less strain on the lua scripting engine. I reckon my C# will outperform the lua script as i can multi thread if i need to.

4. lastly but more importantly, I want to translate the exported values on my pc which has spare processing capacity and memory plus its a damn site faster. The arduino is purely a driver to my instruments. I havent hit the arduino limits yet but i reckon i will at some point.

 

 

To be honest in about 6 months i might just rewrite this all and go ethernet shield but im still a n00b. I only started this over the Xmas holidays ( not the coding tho :))

Posted (edited)

Part 2 !!!

 

First we start with a pretty diagram. I hope you have lots of tinned wire :music_whistling:

 

4511amp595toLED-SingleSR.png

 

If that has frightened you off nothing will.

 

Facepalm moment. :doh:

 

Thats actually a 74HC595 not a 75HC595......

and i missed a ground link from the LED CCpin to the 5v ground.

 

List of parts you will need.

 

1 metric ton of equipment in various colours - I jest its only 500 kilos worth

 

2 x 74HCF4511. Actually there are many 4511 chips out there. I just know this one worked.

1 x 74HC595 Apparently this chip is a classic. And before anyone bitches about the limited amount of current it can sink ahhah i have a cunning plan.

14 x 100R Resistors ( 5v supply. Each LED has a 2.5V forward voltage and 25mA so the gurus behind the led resistance calculator tell that a 100R/Ohm resistor will do the job)

2 x 7 Segment LED display of the Common Cathode variety.

 

CAVEAT: My resistor choice is based on the specs of my LED display, you need to verify calcs for whatever you buy. Any questions just ask., Or use this....http://led.linear1.org/1led.wiz

 

Also i deliberately havent shown the full wiring for the LED displays. Simply because i dont know what youre going to use. However its a damn good bet that you will have seven pins a-f, 1 pin called DP and 2 pins called CC or common anode. Pins 1-7 should be matched a-g i.e. 1-a 2-b etc. Ignore DP (decimal point) as the BCD wont use it.

Finally CC needs to be wired to the ground of the external 5v supply (not the arduinos grd)

 

4511-chip.png

 

 

Each segment is a LED in its own right so calculate resistance per segment and put the resistor in front of the led segment. Dont be cheap and place it on the cathode.

 

Go and wire that up.

 

Note the 5V supply thats wired to GRD and VCC pins of the 4511 chips (pins 8 and 16). Thats a seperate power line thats wired to a 5v adaptor (4 x 1.5 batteries in series will do that job). The reason im doing this is the the arduino can only drive so much current before it will blow :helpsmilie: Driving the BCD chips on a seperate loop keeps the power requirements away from the arduino. All you are doing is passing a data signal per pin at little or no current(or so i believe).

 

Once you've wired that up. Upload this sketch

 

#define LATCH_ENABLE 13

#define LATCHPIN 8

#define CLOCKPIN 12

#define DATAPIN 11

int x;

byte data;

byte led1[10];

byte led2[10];

 

void setup()

{

led1[0]=0b00000000;

led1[1]=0b00000001;

led1[2]=0b00000010;

led1[3]=0b00000011;

led1[4]=0b00000100;

led1[5]=0b00000101;

led1[6]=0b00000110;

led1[7]=0b00000111;

led1[8]=0b00001000;

led1[9]=0b00001001;

led2[0]=0b00000000;

led2[1]=0b00010000;

led2[2]=0b00100000;

led2[3]=0b00110000;

led2[4]=0b01000000;

led2[5]=0b01010000;

led2[6]=0b01100000;

led2[7]=0b01110000;

led2[8]=0b10000000;

led2[9]=0b10010000;

x=0;

Serial.begin(9600);

 

pinMode(LATCHPIN,OUTPUT);

pinMode(LATCH_ENABLE,OUTPUT);

 

}

 

 

 

 

void loop()

{

if (x==9)

x=0;

else

x++;

 

data=led1[x]|led2[x];

 

digitalWrite(LATCH_ENABLE,LOW);

 

digitalWrite(LATCHPIN,LOW);

shiftOut(DATAPIN,CLOCKPIN,data);

shiftOut(DATAPIN,CLOCKPIN,data);

 

digitalWrite(LATCHPIN,HIGH);

digitalWrite(LATCH_ENABLE,HIGH);

 

 

 

delay(300);

}

 

// the heart of the program

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {

// This shifts 8 bits out MSB first,

//on the rising edge of the clock,

//clock idles low

 

//internal function setup

int i=0;

int pinState;

pinMode(myClockPin, OUTPUT);

pinMode(myDataPin, OUTPUT);

 

//clear everything out just in case to

//prepare shift register for bit shifting

digitalWrite(myDataPin, 0);

digitalWrite(myClockPin, 0);

 

//for each bit in the byte myDataOut�

//NOTICE THAT WE ARE COUNTING DOWN in our for loop

//This means that %00000001 or "1" will go through such

//that it will be pin Q0 that lights.

for (i=7; i>=0; i--) {

digitalWrite(myClockPin, 0);

 

//if the value passed to myDataOut and a bitmask result

// true then... so if we are at i=6 and our value is

// %11010100 it would the code compares it to %01000000

// and proceeds to set pinState to 1.

if ( myDataOut & (1<<i) ) {

pinState= 1;

}

else {

pinState= 0;

}

 

//Sets the pin to HIGH or LOW depending on pinState

digitalWrite(myDataPin, pinState);

//register shifts bits on upstroke of clock pin

digitalWrite(myClockPin, 1);

//zero the data pin after shift to prevent bleed through

digitalWrite(myDataPin, 0);

}

 

//stop shifting

digitalWrite(myClockPin, 0);

}

 

 

This will drive a simple loop and output 0-9 to both LEDs to test your circuit works.

 

I figure that will keep you busy long enough for me to double check the final bit of code. NEARLY THERE!!

Edited by Devon Custard
  • Like 1
Posted

aaannnnnd..... I feel like the stupid kid in class :) i'll just sit quietly at the back and hope someone lets me copy their homework!

 

Nice work DC, may take me a while and a bit of googling to decipher that little lot but sterling effort in putting it in a format that's accessible and I can (just about) understand.

Posted

Jimbo, i know how you feel. TBH googling was precisely how i conquered this. Dont be afraid to ask, i might not be able to answer clearly (or correctly) but at least someone out there will be able to.

 

A really good place to start is this arduino tutorial

 

http://arduino.cc/en/tutorial/ShiftOut

 

Then read this one

 

http://scuola.arduino.cc/courses/lessons/view/B7xOJzE

 

Dont worry about understanding it at first. Just accept it will work (When wired correctly). Understanding comes later :)

Posted

Jimbo, that is not only the funniest thing I've read in a long time, but the truest for me also! :D

 

aaannnnnd..... I feel like the stupid kid in class :) i'll just sit quietly at the back and hope someone lets me copy their homework!

 

Nice work DC, may take me a while and a bit of googling to decipher that little lot but sterling effort in putting it in a format that's accessible and I can (just about) understand.

Buttons aren't toys! :smilewink:

 

My new Version 2 Pit: MacFevre A-10C SimPit V2

My first pit thread: A-10C Simulator Pit "The TARDIS."

Dzus Fastener tutorial, on the inexpensive side: DIY Dzus Fastener

Posted
Jimbo, that is not only the funniest thing I've read in a long time, but the truest for me also! :D

 

How about i post the UFC master caution sketch and circuit? Its kinda simple, one tactile switch with combined led, but anyone can simulate it with a tactile switch and a seperate led.

Posted

I've been doing my research (homework!?), and as DC says, it isn't all that complicated. I had a bit of a 'penny drop' moment last night and I hope to have all the components arrive in the post today. So I'll be putting this together over the weekend and I hope that'll help solidify the concepts in my mind.

 

DC - the UFC sketch would be cool also, as it involves a physical input. But please don't burden yourself unnecessarily, us (well, me) intellectually challenged lot will catch up eventually :)

Posted

Lol halfway thru a post for the UFC sketch so ill post BOTH. oooh 2 for 1 bargain price :D

 

 

Really nice to hear about your penny drop moment. If i've managed to help at least one person then the effort was worthwhile.

 

Ill finish my other post and upload the sketches

Posted

Ok

 

simple circuit.

 

Take an arduino, wire pin 13 to the anode of an LED with a 100R resistor. Wire the cathode to the arduino's ground. Its one of the most basic arduino circuits there is. This is your master caution LED. I did it with my illuminated tactile switch but thats just an LED on a switch and its a seperate circuit so makes no difference.

 

http://uk.rs-online.com/web/p/tactile-switches/6927005/

 

Now wire a switch to whatever input board youre using. I always use one of the leo bodnar boards BU0836x for my rapid prototyping. I have a brydling board for the final wire up but the bodnar for testing as its really fricking quick to setup.

 

http://www.leobodnar.com/products/BU0836X/

 

Map your switch in DCS to the master caution switch on the UFC.

 

Upload this sketch to your arduino...

 

#define LED 13

String command;

String value;

int start=0;

int mid=0;

void setup()

{

Serial.begin(9600);

command="";

value="";

pinMode(LED,OUTPUT);

 

}

 

 

 

 

void loop()

{

 

if(Serial.available())

{

 

int c=Serial.read();

if (start==1)

{

if (c=='-')

mid=1;

else if(c=='#')

{

ProcessData();

}

else if(mid==0)

{

command=command+char©;

}

else

{

value=value+char©;

}

}

else if(c=='*')

{

start=1;

}

 

 

}

}

 

void ProcessData()

{

 

switch(command.toInt())

{

case 404:

if (value=="1.0")

digitalWrite(LED,HIGH);

else

digitalWrite(LED,LOW);

break;

}

mid=0;

start=0;

command="";

value="";

}

 

 

Here you can see im reading the inbound serial stream from the USB COM port in loop(). I read the stream until i receive a valid command packet of the *xxx-yyy# format where xxx is the argument and yyy is the value. When i have that i call ProcessData and use a switch statement to run the relevant code. In this case im only interested in argument 404 (master caution state) and depending on the value which is either 1.0 or 0.0 i set the state of the LED pin to go HIGH or LOW which is 5v or 0v. LED on or off.

 

Oh wait i forgot to amend my listener to output the UDP stuff over serial didnt i. Lets do that next.

 

Open the UDP Listener solution in Visual Studio.

 

In the solution explorer, click on Form1.cs, right click and select View code. This brings up the code editor (might already be open depending on how you closed the solution).

 

Find the ProcessData function

 

private void ProcessData( string data)

{

string[] d2 = data.Split( '=');

 

if (d2.Length != 2)

return;

switch (d2[0])

{

 

case "2251":

// textBoxILS.Text = d2[1].ToString();

switch (d2[1].ToString().Substring(0, 3))

{

case "0.0":

SendSerialData( "101", "108" );

break;

case "0.1":

SendSerialData( "101", "109" );

break;

case "0.2":

SendSerialData( "101", "110" );

break;

case "0.3":

SendSerialData( "101", "111" );

break;

default:

break;

}

break;

default:

break;

}

}

 

Change it to

private void ProcessData( string data)

{

string[] d2 = data.Split( '=');

 

if (d2.Length != 2)

return;

switch (d2[0])

{

 

case "2251":

// textBoxILS.Text = d2[1].ToString();

switch (d2[1].ToString().Substring(0, 3))

{

case "0.0":

SendSerialData( "101", "108" );

break;

case "0.1":

SendSerialData( "101", "109" );

break;

case "0.2":

SendSerialData( "101", "110" );

break;

case "0.3":

SendSerialData( "101", "111" );

break;

default:

break;

}

break;

 

case "404":

SendSerialData("404",d2[1].ToString();

break;

 

default:

break;

}

}

 

 

The updated code is in red.

 

Finally open the Form Designer, right click on Form1.cs and select view designer.

 

Click on the serialPort1 (at the bottom of the form) and change the property PortName to the COMx port you are connected to your arduino with. HINT, your sketch editor will tell you at the bottom of the editor Should say Arduino on COMx...

 

If you run the above sketch and the UDP Listener you should be able to trigger a master caution in DCS and see a flashing LED. I normally trigger the boost pumps toggle switch whilst sitting on the tarmac. Pressing my tactile switch turns it off(actually it just stops flashing, sometimes it stays on. I need to write a timer to turn it off when the value doesnt change for a second or two)

 

 

 

 

Hmmm this last part of the guide feels a bit rushed. Ill edit it into something more friendly later this week.

Posted

Is there any way to reproduce the same functionality using a lathe and a milling machine rather than witchcraft ? ( sorry, code and microcontrollers ) - I might have a chance then :D

 

Seriously, I'm enjoying this even though it's making my brain hurt. I have an Arduino Uno on order together with several miles of wire and lots of mysterious electric components and will need all the help I can get...

---------------------------------------------------------

PC specs:- Intel 386DX, 2mb memory, onboard graphics, 14" 640x480 monitor

Modules owned:- Bachem Natter, Cessna 150, Project Pluto, Sopwith Snipe

Posted

hahah witchcraft :)

 

Help is here. Im gonna churn out a more complete sketch and version of the Listener this weekend with examples of how to extend it....

 

After that its just the usual Imagination is just your limiting factor (or someone elses if youre nice to them)

 

Oh and someone was really polite and asked me if i was sharing or selling my sketches/code. Sharing obviously. I plan on asking lots of questions myself and figure least i can do is share my own experience if someone is crazy enough to ask my opinions.

Posted

Having fun translating this from breadboard to prototype matrix board at present. Shift registers playing up which is royally annoying.

 

Plus i find everytime i look at the circuit i find myself saying, "oh why dont i do this instead". :)

 

I put the BCDs in to seperate the power supply and making the wiring to LED easier, but actually i think i just complicated it. I might have a newer vesion of the circuit without the BCDs.......

 

Ah well im having fun....

Posted

Ok found the issue, seems using a common latch pin signal doesnt work on the 4511 chips. Will rework the sketch & circuit to use multiple pins, not brilliant but should work until i can resolve why.....

Posted

I'm working on something similar (see the DFDT Cockpit thread).

 

I have written a small bridge application to make communication between DCS and the Arduino easier.

 

attachment.php?attachmentid=93406&stc=1&d=1390551799

 

This application simply transfers the data sent from DCS (via UDP) to the Arduino (via RS232) and vice versa.

Dutch Flanker Display Team | LLTM 2010 Tiger Spirit Award
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...