Jump to content

How To: Build an A-10C Caution Light Panel with an Arduino Ethernet


Recommended Posts

Posted (edited)

The contents of this thread will eventually make it into the Wiki I started with Devon Custard but during the process of experimentation and for discussion purposes I have started a thread to explain the steps and process I will go through to get this going.

 

My goal is to make a working Caution Light Panel using an Arduino Uno Ethernet variant and have DCS send data to it over the LAN (using UDP). I want this because I want to avoid the "middle man" code that so many have written to glue an Arduino to DCS.

 

There are pros and cons to both approaches for what it is worth, this thread will capture the journey down the Ethernet only and no middle man code approach.

 

Here is a video showing the early stages of progress.

 

Components:

  • Arduino Uno
  • Arduino Uno Ethernet Shield
  • Adafruit NeoPixel Shield

 

Edited by TigersharkBAS
  • Like 3

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Excellent, TigersharkBAS :thumbup: I am really looking forward to reading more in this as I would like to go down the same path. My Arduino code skills are limited and the C# are non existing. Therefore it would be very intersting as you mention yourself, to avoid the "middle man".

 

Which Ethernet shield are you using, W5100?

 

I got a Uno with W5100 that I had been using for Gremlins CMSP export, which also uses UDP. But have gotten stuck on how to handle the string from the export.

This is really going to be interesting. Thanks a lot for sharing :thumbup: And subscribed

 

Cheers

Hans

Posted

Thanks HMA. Yes. I am using the 5100.

 

I will post the provisional (and unfinished) code later tonight when I get home. It isn't very complicated.

 

Basically, I have used some of Devon Custard's work and modified an export.lua file that exports only the Master Caution and Caution Panel lights. It sends the status of all of these in a single string like this (lets assume 404 is master caution light and 405 is Seat Not Armed for this example)

*404-1.0:405-1.0#

The '*' means the string is beginning. The "-" separates a command (master caution) from a value (1.0 meaning ON). The ":" means a new command/value pair and the "#" means end of UDP message.

 

I pick apart this string sequentially using some simple code I will post. Then pass each command/value pair to a case statement that turns on the appropriate light.

 

This does require some more experimentation though. In the example in the video I was only sending 2 values from DCS to the Arduino. The Master Caution light and the Seat Not Armed light. Peformance was great.

 

After making the video I enriched the export.lua to send a string with 13 lights. This caused a delay of about 2-3 seconds between unarming the seat and the Arduino lights activating.

 

So the next experiment for me is to see whether it is better peformance wise to send a large string from DCS or to simply send each command/value in succession to the Arduino. I am almost certain it is the Arduino causing the bottleneck as it iterates through the string. Perhaps just being sent a pair of data in quick succession works better.

 

Also note that the Caution Panel is a matrix of 4x12 lights. Unfortunately the NeoPixel shield will only have 8 rows for me to test with but it gets the ball rolling.

 

Once the DCS to Arduino code is stable and working I will be connecting this to custom made LED matrix using a Max7219 and ditch the NeoPixel shield.

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Excellent!

 

I'd be interested in the UDP protocol, as I am trying to make Hempstick support the SAM4E XPLAINED Pro board, which has Ethernet on it. I have a much bigger plan for the Ethernet with Hempstick and will define a protocol for it as well. But if you have a protocol ready, why not supporting it? Saves me time to write the script bridge software module.

 

BTW, I am not quite sure I understand what you mean by "'*' means the string is beginning, ..., and '#' means end of UDP message." A UDP packet is just one packet... and the payload is just one continuous bytes stream with length indicated by the UDP packet payload length. There is no need to mark beginning and end with special characters. I must have misunderstood something.

Posted (edited)

IT might become more obvious when I post the code. They are basically markers to let my code know when to stop processing each packet.

 

SOP = Start Of Packet (*)

EOP = End Of Packet (#)

PAYLOAD = the characters between SOP and EOP

PACKET = SOP + PAYLOAD + EOP

 

You might see a better way to do it in which case I am all ears :-)

Edited by TigersharkBAS

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Arduino code can be found here:

https://github.com/jvanlint/UFC_CautionPanel

 

Export Lua is as follows. Note this is not a complete set of lights yet. Just the beginnings of a prototype. Only contains 13 lights including the Master Caution.

 

--IP address of the computer that is going to receive this
Host="192.168.1.5"
--And UDP port that the computer is listening on.
Port=8888

--This function is called at the start of every mission
function LuaExportStart()
   --Tell Lua we're going to use sockets
   package.path  = package.path..";.\\LuaSocket\\?.lua"
   package.cpath = package.cpath..";.\\LuaSocket\\?.dll"
   --define the socket class
   socket=require("socket")
   --create the socket we're going to use throughout the script
   c=socket.udp()
   c:setsockname("*",0)
   c:setoption('broadcast',true)
   c:settimeout(.001)
end

--This function is called at the end of every mission
function LuaExportStop()

   c:close()

end


function LuaExportBeforeNextFrame()


end


function LuaExportAfterNextFrame()
--This function is called every time a simulation frame finishes. We are going to put our export function here

   --GetDevice(0) returns the main panel from which "MOST" gauges and data can be obtained.
   local Device = GetDevice(0)
   --Get the state of 404 which is the master caution lamp
   local masterCaution = Device:get_argument_value(404)
   local engineStartCycle = Device:get_argument_value(480)
   local leftHydPress = Device:get_argument_value(481)
   local rightHydPress = Device:get_argument_value(482)
   local gunUnsafe = Device:get_argument_value(483)
   local antiskid = Device:get_argument_value(484)
   local leftHydRes = Device:get_argument_value(485)
   local rightHydRes = Device:get_argument_value(486)
   local oxyLow = Device:get_argument_value(487)
   local elevDiseng = Device:get_argument_value(488)
   local seatNotArmed = Device:get_argument_value(490)
   local bleedAirleak = Device:get_argument_value(491)
   local ailDisengage = Device:get_argument_value(492)
   
   
   --Format the data into something a little more usable
   local packet=string.format("*404-%d:480-%d:481-%d:482-%d:483-%d:484-%d:485-%d:486-%d:487-%d:488-%d:490-%d:491-%d:492-%d#",masterCaution, engineStartCycle, leftHydPress, rightHydPress, gunUnsafe, antiskid, leftHydRes, rightHydRes, oxyLow, elevDiseng, seatNotArmed, bleedAirleak, ailDisengage)
   --Finally send the data 
   socket.try(c:sendto(packet,Host,Port))
   socket.try(c:sendto(packet,"192.168.1.40",12345))

end

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Part 2 showing more LEDS working and the slight delay I experience.

 

 

Part 3 showing that you SHOULD NOT send caution panel light info individually from DCS but stick to the "all commands in one string" method.

 

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

So gentlemen....I think this needs to be optimised.

 

I can see 2 possible solutions:

 

1. Someone better at Lua than me figures out how we can send a string to the Arduino via UDP that only contains only values that are changing.

 

or

 

2. We figure out a better way to pull apart the string in the Arduino code.

 

I am not quite sure what causes the delay...whether it is the receiving of the string over UDP or the processing of it in the Arduino.

 

Any ideas???

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Here's the regular C code to receive a UDP datagram.

 

recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);

 

The receiver already knows the length of the payload. Thus, no need to mark the beginning and the end with marker chars... offset 0 is the beginning, offset recvlen - 1 is the last char.

 

With TCP, stream-based socket, you do need to mark the beginning and the end (or send the length as part of the payload), with UDP datagram... no need for that. No big deal, if it helps you parse the string, I can always skip offset 0 and offset recvlen - 1 chars.

 

 

 

IT might become more obvious when I post the code. They are basically markers to let my code know when to stop processing each packet.

 

SOP = Start Of Packet (*)

EOP = End Of Packet (#)

PAYLOAD = the characters between SOP and EOP

PACKET = SOP + PAYLOAD + EOP

 

You might see a better way to do it in which case I am all ears :-)

Posted

OK...that saves 2 cycles of the For loop.

 

We need a better way to process that string though. Or is this as good as it gets?

 

Unfortunately I'm not sure if compressing the string will help as I don't think the problem is receiving the string...it is processing it....I think :helpsmilie:

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted
OK...that saves 2 cycles of the For loop.

 

We need a better way to process that string though. Or is this as good as it gets?

 

Unfortunately I'm not sure if compressing the string will help as I don't think the problem is receiving the string...it is processing it....I think :helpsmilie:

 

It's a structured data... I would avoid string processing altogether... i.e. design the protocol so that it requires no string processing... particularly, string processing is not the strong suit of embedded processors.

 

What I mean is that the data is a simple name/value pairs. And due to the size limitation of UDP datagram, if you wish to control many devices (or indicators), you have to send multiple datagrams anyway. So, why not do this.

 

1. Each datagram is for one device only.

2. First 2 bytes is the destination device id (2 bytes gives you 65536 devices, might want to reserve device #0 as the broadcast).

3. The next byte indicate the total number of name/value pairs.

4. each name is 2 bytes, and value is 2 bytes.

 

No parsing is needed. But the receiver decoding code do have to be carefully written so that it doesn't do buffer overrun in case the total number of name/value pairs is maliciously bigger than the actual.

 

This way, you can send more than one value to each devices, and it's a little extendable -- for now, you only have a couple of name/value pairs.

1. Name = 0x0000 (Red)

2. Name = 0x0001 (Green)

3. Name = 0x0002 (Blue)

4. Name = 0x0003 (Brightness, perhaps PWM control of brightness?)

 

And, later on, you can define more attributes to send. Not only that, each device number can have different legal name/value pair definitions.

Posted (edited)

Forgot that it will also need the 5th attribute.

5. Name = 0x0004 (LED #).

 

Also, since each name and each value is two bytes, you do have to specify whether it's big endian or little endian... I would go with the network byte order, i.e. big endian. But it doesn't really matter that much, as long as it's specified.

Edited by Hempstead
Posted

Hempstead...this is great......but I might need some more practical examples from you. I'm not sure I'll be able to implement what you are talking about.

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted
Hempstead...this is great......but I might need some more practical examples from you. I'm not sure I'll be able to implement what you are talking about.

 

Ok. say we define the format as the following struct. Note that, these are pseudo code to demonstrate the concept, so forgive me for the possible syntax errors; I ain't no compiler.

 

#define DEVICE_NET_TARGET_DEVICE_LED 0x0001
#define DEVICE_NET_DEVICE_LED_ATTR_R 0x0000
#define DEVICE_NET_DEVICE_LED_ATTR_G 0x0001
#define DEVICE_NET_DEVICE_LED_ATTR_B 0x0002
#define DEVICE_NET_DEVICE_LED_ATTR_INTENSITY 0x0003
#define DEVICE_NET_DEVICE_LED_ATTR_NUM 0x0004

struct {
   uint_16_t name,
   uint_16_t value,
} attribute;

struct {
   uint16_t target_device,
   uint8_t num_attrs,
   attribute *attributes
} device_datagram;

 

Then, a device_datagram example would look like this.

 

{DEVICE_NET_TARGET_DEVICE_LED, 0x0005, DEVICE_NET_DEVICE_LED_ATTR_R, 0x0000, DEVICE_NET_DEVICE_LED_ATTR_G, 0x00CA, DEVICE_NET_DEVICE_LED_ATTR_B, 0x00FE, DEVICE_NET_DEVICE_LED_ATTR_INTENSITY, 0x8888, DEVICE_NET_DEVICE_LED_ATTR_NUM, 0x0000}

 

or translated to all hex without symbols.

 

{{0x0001, 0x0005, 0x0000, 0x0000, 0x0001, 0x00CA, 0x0002, 0x00FE, 0x0003, 0x8888, 0x0004, 0x0000}

 

Meaning, the target device control is LED control, and give me the color 0x00CAFE for LED # 0, with 1/2 intensity.

 

 

So, the processing loops becomes something like this (assuming network byte order and the machine is big endian to simplify the pseudo code).

   len = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
   if(len > 0) {
       device_datagram data_gram = (device_datagram)buf;
       target_num = data_gram->target_device;
       uint8_t num_attrs = data_gram->num_attrs;
       for(uint8_t i = 0; i < num_attrs /* && needs to guard against buf overrun here */; i++) {
           uint16_t current_attr_name = data_gram->attrs[i].name; // needs to store these to somewhere or use them immediately.
           uint16_t current_attr_value = data_gram->attrs[i].value;
       }
       
       switch(target_num) {
            case DEVICE_NET_TARGET_DEVICE_LED:
                 // do something with the stored attrs against LEDs.
            break;

            /* to support more devices, just add more cases here. */

            default:
                printf("Unsupported device num = %d, damn it, are you trying to crash me?\n", target_num);
            break;
        }
   }

 

 

See? No string parsing nor scanning. Just go take the data out.

Posted

The trouble with this protocol is that you can only send uint16_t integers over. You can't send anything else.

 

To be able to send something else, you'd need to extend this and add encoding, like string type, int type, float type, double type, etc. etc.

Posted

Man...this be some heavy duty shit Hempstead. And whilst I might be able to figure out the Arduino code the Lua part escapes me.

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

You could use a typedefed struct and cast a pointer of that type to your buffer, easiest way as long as the structure of your data does not change.

Could also use an id, value pair, where the id of the value is used in a switch statement, I have used this before and it works ok, like below-

 

BYTE *b; // pointer to buffer

short id; // id of value

short numVals; // the number of id, value pairs in buffer, first item in buffer

int iVal; // integer value - maybe a frequency

short sVal; // short value - maybe airspeed etc

 

b = buffer; // buffer received from sim

numVals = (short*)b; // get the number of id, value pairs to process

b += sizeof(short); // increment buffer pointer to start of data

 

for( int i = 0; i < numVals; i++)

{

id = (short*)buffer;

b += sizeof(short); // increment buffer pointer to value

 

switch(id){

case 1: // int - maybe a frequency

ival = (int*)b; // do something with iVal

b += sizeof(int); // increment buffer pointer to next id

break;

case 2: // short - something like airspeed

sval = (short*)b; // do something with sVal

b += sizeof(short);

break;

case 3: ...

}

}

Posted (edited)
Man...this be some heavy duty shit Hempstead. And whilst I might be able to figure out the Arduino code the Lua part escapes me.

 

I don't know nothing about Lua. But the thing is... nobody says you have to implement the full capability of what the protocol can do. Do just the LED part. You can cheat while still conforming to the protocol. ;-)

 

Let's say, you just want to turn LEDs on and off, with no control of intensity with PWM. NeoPixels won't let you do PWM control anyway.

 

So, your first byte will always be 0x0001. 2nd byte will be the 0x0004, then send the 4 attributes (not 5!). Each pair will be 4 bytes.

 

The order of attributes don't matter, but let's simplify it further by fixing the order, and still conforming to the protocol.

 

1st pairs is always R attribute. 1st byte is always 0x0000, 2nd is always 0xFFFF to turn it on, 0x0000 to turn it off. 2nd attr and 3rd are similar.

 

4th attr has the first byte always be 0x0004, 2nd byte is the LED number you wish to control.

 

No need to send intensity attr.

 

 

You can cheat even further, by getting a fixed byte buffer with the following 2 byte arrays.

 

{0x0001, 0x0004, 0x0000, 0xFFFF, 0x0001, 0xFFFF, 0x0002, 0xFFFF, 0x0004, 0x0000} // the on datagram

{0x0001, 0x0004, 0x0000, 0xFFFF, 0x0001, 0xFFFF, 0x0002, 0xFFFF, 0x0004, 0x0000} // the off datagram

 

Now, to turn an LED on, take the on datagram, and modify byte 10, with the LED #. And then send the whole datagram over. Repeat this for every LED you wish to control.

 

To turn off an LED, take the off datagram modify byte 10....

 

In essence, you cheat by taking advantage of the fixed format of only the functions you wish to implement, i.e. only LEDs, by using two template datagram.

 

Well, the protocol is capable of much more, but you only implement what you need, and claim done for only the LED control.

Edited by Hempstead
Posted (edited)

For future proof, I would change the protocol to prepare for the possibility of sending other types of values other than uint16_t by changing the attribute struct as the following.

 

struct {
   uint_16_t name,
   uint8_t value_type;
   uint16_t value_len; // in bytes.
   char* value,
} attribute;

 

Then, of course, we'd need to change the processing code accordingly, but currently implement only value_type 0x00, i.e. uint16_t, and ignore everything else for now. Meaning, the C code on the server side (C++ in the Arduino case) completely ignores the value_type and value_len for now and assumes the value is of type uint16_t by casting it to uint16_t. (The safer way is to check if the value_type is 0x0000, i.e. uint16_t. If not, ignore it, so that if a newer version of client sends the a datagram with other value_types to an older version of server that does not support other value_type, it won't crash the server. Speaking of that, it's probably safer to put a protocol version at the very beginning of the protocol. But it's not really critical to have; just that I would sleep better. ; -).

 

For full implementation of other types, it's best handled with union, etc. But no need to do that now.

 

Then, the Lua datagram templates for on/off need add 3 more bytes for each attr, but these 3 bytes are always fixed for your LED control anyway.

 

That is, we put in the provision for the future, in case we need to send other types, like string or floating points. But we don't implement them now. And implement only uint16_t type. And, if we do implement other types in the future, it's backward compatible so the existing client code don't need to change.

Edited by Hempstead
Posted

Finished reading page one, flipped to page two about ready to describe more or less what Hempstead described, although less sophisticated. Read Hempstead's post, learned some things that should have been obvious about protocol design.

 

Thanks for the thoughtful posts, Hempstead!

Posted

Hey TigersharkBAS - great work so far!

 

I have a quick question for you reguarding the wiki post you made here -

 

Connecting DCS to Arduino

 

I have gone through all of the steps (even copied and pasted the code from the updated version like you said o at the bottom, but I keep getting an error when trying to connect to DCS. (The test harness worked fine and connected to Arduino).

 

The error that comes up is -

 

System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex
  at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
  at System.String.Substring(Int32 startIndex)
  at UDPBridge.Form1.ProcessData(String data) in c:\Users\shaun\Documents\Visual Studio 2013\Projects\UDPBridge\UDPBridge\Form1.cs:line 119
  at UDPBridge.Form1.buttonUDPON_Click(Object sender, EventArgs e) in c:\Users\shaun\Documents\Visual Studio 2013\Projects\UDPBridge\UDPBridge\Form1.cs:line 46

 

Any ideas on how I can fix this? :cry:

 

Cheers!

 

Smirks

 

PS - Here is my UDP code (copied straight fro the github post)

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO.Ports;
using System.Threading;

namespace UDPBridge
{
   public partial class Form1 : Form
   {
       private bool done = true;
       private int listenPort = 65002;

       public Form1()
       {
           InitializeComponent();
       }

       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();
                   Thread.Sleep(500);
               }
           }
           catch (Exception ex)
           {
               textBox1.AppendText(ex.ToString());
           }
           listener.Close();
       }

       private void buttonUDPOFF_Click(object sender, EventArgs e)
       {
           done = true;
       }

       private void buttonCOMON_Click(object sender, EventArgs e)
       {
           string[] ports = SerialPort.GetPortNames();
           string query = "*9999-0#";
           foreach (string port in ports)
           {
               SerialPort p = new SerialPort();
               p.BaudRate = 9600;
               p.PortName = port;
               try
               {
                   p.Open();
                   if (p.IsOpen)
                   {
                       p.Write(query);
                       string s;

                       Thread.Sleep(500);
                       s = p.ReadExisting();
                       p.Close();
                       try
                       {
                           if (s.Contains("<ident:"))
                           {
                               int i = s.IndexOf("<ident:");
                               s = s.Substring(i + 7);
                               i = s.IndexOf(">");
                               s = s.Substring(0, i);
                               if (s == "BORIS")
                               {
                                   serialPort1.PortName = port;
                                   serialPort1.Open();
                               }

                           }
                       }
                       catch { }
                   }
               }
               catch (Exception ex)
               {
                   ;
               }
           }
       }

       private void buttonCOMOFF_Click(object sender, EventArgs e)
       {
           if (serialPort1.IsOpen)
               serialPort1.Close();
       }

       private void ProcessData(string data)
       {
           data = data.Substring(9);
           string[] d2 = data.Split('=');
           if (d2.Length != 2)
               return;
           if (d2[1].Substring(d2[1].Length - 1) == "\n")
               d2[1] = d2[1].Substring(0, d2[1].Length - 1);
           switch (d2[0])
           {
               //Master Caution Switch
               case "404":
                   SendSerialData("404", d2[1].ToString());
                   break;

               default:
                   break;
           }
       }

       private void SendSerialData(string function, string value)
       {
           if (serialPort1.IsOpen)
           {
               string sendthis = "*" + function + "-" + value + "#";
               char[] c = sendthis.ToCharArray();
               serialPort1.Write(c, 0, c.Length);
           }
       }
   }
}

Cheers,

 

Smirkza

Posted

Hey smirkza. DevonCustard wrote that article (I am no C# sharp expert). I'll alert him to this post and see if he can help.

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

Posted

Superb, thanks TigerShark!

 

I'm actually going through his forum post now (only just found it) although I've reached a stumbling block when trying his shortened caution light blinky. Getting errors galore when trying to change things as he suggest...

 

This is bugging me as I can handle the arduino fine, but it's all the PC based stuff that's getting to me. If only there was a simple, stand alone program that sent data out to arduinos for you, life would be great!

 

Back to the testing! :thumbup:

Cheers,

 

Smirkza

Posted

[sIGPIC][/sIGPIC]

 

Creator of:

 

F-18C VFA-195 "Dambusters" 1998 CAG Livery

https://forums.eagle.ru/showthread.php?t=213788

 

F-18C VFA-195 "Dambusters" July 2001 CAG Livery

https://forums.eagle.ru/showthread.php?t=215950

 

Pilot avatars for DCS Logbook

https://forums.eagle.ru/showthread.php?t=221160

 

How to make a DCS A-10C Panel

http://forums.eagle.ru/showthread.php?t=65998

  • Recently Browsing   0 members

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