Jump to content

Major Announcement: New software to to connect panels to DCS


Recommended Posts

Posted

@Ian:

 

Thank you, problem solved, indeed it was baud rate related. Everything working to spec now.

 

For the benefit of anyone not reading the whole thread:

 

IF you use the DCS-BIOS library unmodified

AND you are seeing weird characters, irregular update rates etc. in Arduino app

AND

shows the correct live data

 

THEN

reduce your baudrate from 500000 to 115000 in:

1. the Arduino setup() code: Serial.begin(115000); and in the

2. connect-serial-port.cmd script:

...mode COM%COMPORT% BAUD=115000 PARITY=N DATA=8 STOP=1 TO=off DTR=on...

 

 

 

I love it. Thank you Ian !

Your library really makes building cockpit panels very straightforward (once I got the bug squashed :)

 

 

Next, I will research how to get the stream of data into a mobile browser (Android, iOS, likely Chrome) so I can show a plane icon and some telematics on an iPad/Nexus kneepad app. Maybe websockets...

Oh sigh, no UDP support :( And WebRTC with a raw data channel & UDP might work, but support still pretty sketchy on mobile. Maybe I need to write something like Ian's node server (which would update/keep current state data on the PC and allow http access to it, polled from a web page's js)

Also looking forward to the extra information which might be exposed by DCS-BIOS in the future.

Working on an open source "kneeboard" app (browser based, so runs everywhere) for DCS world: maps, checklists, reference, glossary, calculators.

  • Replies 398
  • Created
  • Last Reply

Top Posters In This Topic

Posted

Hey Ian just a trivial mistake I noticed:

 

In the UHF section of the control reference you mislabeled the 0.25mhz selector as a UHF 10MHz Selector. It's just the title that's wrong, the message itself is correct so it has no ill effect. :)

Posted

Unfortunately I didnt get enough time to test the shift registers. the circuit is ready but no code yet. hopefully I'll have a few hours here and there during the week to try and get them to send data to dcs bios. Otherwise next weekend.

Posted

Hey Ian could you please give me a couple pointers on how to go about getting the shift registers to work with dcs bios? I mean just the general logic/steps behind the process. you don't need to go into super detail. Just a little something to get me started in the right direction :)

Posted
Hey Ian could you please give me a couple pointers on how to go about getting the shift registers to work with dcs bios? I mean just the general logic/steps behind the process. you don't need to go into super detail. Just a little something to get me started in the right direction :)

 

Learn how shift registers work.

Learn how DCS-BIOS works (Developer Guide, "Input Interfaces" section in the User Guide).

 

For output, use onDcsBiosWrite() to store the info you want in a global state variable. Shift the contents of that state variable to your shift registers somewhere in your main loop.

 

For input, read the information from your shift registers into a global state variable in your main loop. Implement modified versions of the classes in the Arduino library (Switch2, etc.) that read from the global state variable instead of Arduino pins (so instead of a pin number, you'd give them a pointer and a bitmask).

Posted
Ian;2295268']

For input, read the information from your shift registers into a global state variable in your main loop. Implement modified versions of the classes in the Arduino library (Switch2, etc.) that read from the global state variable instead of Arduino pins (so instead of a pin number, you'd give them a pointer and a bitmask).

 

Great that's what I meant by general advice. I'll get to it, thanks!

Posted (edited)

Felm: Thanks for the bug reports, the UHF .25 MHz selector description and the partial frequency string exports ("3 " -> " 3") are fixed now.

 

I released the changes as v0.2.3.

 

I could not reproduce glitches in the exports when changing the VHF frequencies. If it still happens after the updating, could you make a video?

 

 

CodeToad: glad the lower baudrate resolved your problem. 115200 can be safely used with the default settings of DCS-BIOS. The reason 500000 is the default is that for a typical update of about 150 bytes, it reduces the transmission time to 3 ms compared to 13 ms for 115200 bps.

So far, I did not experience any problems running at 500000, but I am still thinking about changing the default to 115200 because that is more widely used, more tolerant of clock drift and more likely to be tested by the manufacturers.

 

Next, I will research how to get the stream of data into a mobile browser (Android, iOS, likely Chrome) so I can show a plane icon and some telematics on an iPad/Nexus kneepad app. Maybe websockets...

Oh sigh, no UDP support And WebRTC with a raw data channel & UDP might work, but support still pretty sketchy on mobile. Maybe I need to write something like Ian's node server (which would update/keep current state data on the PC and allow http access to it, polled from a web page's js)

 

I spent some time throwing different pieces of code from my hard drive together and stirring. Here is an example of a node.js server that provides a websocket connection to DCS-BIOS. It is accompanied by a version of the control reference documentation that uses this websocket connection.

 

After installing the required node.js modules, run "node websocket-server.js", then point your browser at "localhost:7780".

Edited by [FSF]Ian
Posted

I use 250,000 on all of my arduinos and RS-485 for that reason. The only down side is 250,000 is a non-standard baud rate, so some PC hardware/software has problems with it. That is a very small subset though.

Posted (edited)

The same holds true for 500000 bps.

 

Lowering the bit rate, even if it happens to increase the relative error in accuracy for the combination of Arduino clock frequency and bit rate, still gets you a larger absolute margin for error and more resilience in the face of interference and parasitic capacitance on the transmission lines.

 

500000 is the default because it is the highest that the Arduino can handle and as long as it works as well as the other settings (which it did in all of my personal tests), we might as well reduce latency if we can.

 

If more people report problems, DCS-BIOS should default to a lower bit rate (probably 115200, because even badly designed USB-to-Serial converters are unlikely to **** that one up).

Edited by [FSF]Ian
Posted
Ian;2295604']

CodeToad: glad the lower baudrate resolved your problem. 115200 can be safely used with the default settings of DCS-BIOS. The reason 500000 is the default is that for a typical update of about 150 bytes, it reduces the transmission time to 3 ms compared to 13 ms for 115200 bps.

So far, I did not experience any problems running at 500000, but I am still thinking about changing the default to 115200 because that is more widely used, more tolerant of clock drift and more likely to be tested by the manufacturers.

 

My bet is the problem was actually buffer overrun, and not signaling error. The buffer on default arduino serial library is only 63 bytes. So at 500,000bps if your work between each serial.read is over 1.5ms, the buffer will loop and you will be missing data. This is very plausible with how the Arduino library is structured right now. It polls all inputs, parses data, interrupts data and bit bangs it out to the LCD before coming back to reading the next character.

Posted

I managed to get get input working somewhat with the shift registers. Although I think I'm not doing it correctly because I'm relying on if statements within the sketch rather than on the library pointers. It also only sends the input once, I have to restart the listener for it to work again. I'll look into it tomorrow, it's stupid late right now.

Posted
My bet is the problem was actually buffer overrun, and not signaling error. The buffer on default arduino serial library is only 63 bytes. So at 500,000bps if your work between each serial.read is over 1.5ms, the buffer will loop and you will be missing data. This is very plausible with how the Arduino library is structured right now. It polls all inputs, parses data, interrupts data and bit bangs it out to the LCD before coming back to reading the next character.

 

If that was the reason, wouldn't my first suggestion of only updating once the "end of update" write access to 0xfffe has been received have fixed it? I doubt that all combined display updates take longer than 30 ms.

Posted

Possibly, but he's defined 6 string buffers as well. Each string buffer and onDcsBiosWrite is called for every other byte of every message. It might be fine, but seems like a lot unnecessary calls getting made. Might be better to only call onDcsBiosWrite once per message and let the callbacks handle indexing into the message.

 

I'm in the middle of getting my environment set up to test / code for DCS Bios. Once I get it going I'll put in a pin toggle before and after processChar and then drop a scope on that pin to get some timings of how fast that's happening.

Posted
Might be better to only call onDcsBiosWrite once per message and let the callbacks handle indexing into the message.

 

Buffering the entire update can require 746 bytes of memory (full initial update after entering an A-10C). That's almost half of the RAM in an ATMega328, so we should avoid doing this if we can.

(After things have settled down, the typical update size is about 80 to 120 bytes.)

 

 

Now that I am back in my dorm room, I have looked at CodeToad's original sketch with a logic analyzer. I am too tired to properly reason about this right now, but the code is definitely too slow to sustain keeping up with a 500000 bps data stream.

 

processChar() seems to take 8 microseconds in the typical case. Together with the other overhead (serial RX interrupt, etc.) that is too long if you only have 20 microseconds to receive and process one byte.

250000 bps should be doable though if we fix some of the existing problems with the Arduino library.

Posted

Verified. I measured CodeToad's code on the scope by modifying the following code:

 

void setup() {
Serial.begin(500000);

lcd.begin(20,4);
lcd.clear();
pinMode(2, OUTPUT);
digitalWrite(2,LOW);
}

void loop() {
while (Serial.available()) {
digitalWrite(2,HIGH);
parser.processChar(Serial.read());
digitalWrite(2,LOW);
}
DcsBios:: PollingInput::pollInputs();
}

 

I then dropped my scope on pin 2 and set it up to trigger on any pulse where it sat low for over 3ms. Sure enough there is a pattern.

 

There will be 6ms where things process normally with it taking between 20-60us inside processChar and 20-40us between calls to processChar. Then there will be a 30ms delay where processChar is not called. This cycle is repeated over and over again. During that 30ms pause between calls to processChar you'll loose approximately 10 sets of data assuming the 3ms transfer rate you quoted earlier.

 

Running the same thing using 250kbps. A similar pattern appears 7ms of normal processing followed by a call to processChar that takes 16ms followed by 16ms pause before calling it again.

 

Running again at 115.2kbps, we see 11.8ms of normal processing, 17ms processChar call followed by a 16ms pause.

Posted
During that 30ms pause between calls to processChar you'll loose approximately 10 sets of data assuming the 3ms transfer rate you quoted earlier.

No data is lost here because in that 30 ms no data is being transmitted. DCS-BIOS aims for 30 updates per second regardless of framerate.

 

Running the same thing using 250kbps. A similar pattern appears 7ms of normal processing followed by a call to processChar that takes 16ms followed by 16ms pause before calling it again.

Are you maybe confusing ms and µs here? A 16 millisecond call to processChar() would surprise me unless there is a very long display update going on.

 

Another interesting place to instrument is lines 55 and 56 of DcsBios.cpp. If you toggle a GPIO pin before line 55 and toggle it back after line 56, you can see how much time is spent in onDcsBiosWrite() calls.

Posted
Ian;2295940']No data is lost here because in that 30 ms no data is being transmitted. DCS-BIOS aims for 30 updates per second regardless of framerate.

 

 

Are you maybe confusing ms and µs here? A 16 millisecond call to processChar() would surprise me unless there is a very long display update going on.

 

Another interesting place to instrument is lines 55 and 56 of DcsBios.cpp. If you toggle a GPIO pin before line 55 and toggle it back after line 56, you can see how much time is spent in onDcsBiosWrite() calls.

 

Nope us and ms are quoted correctly. Yes it's possible that here is no data in the pause or its how long polling inputs takes. I'll throw a few more pins and see what's happening tomorrow evening.

Posted

Did some more timing this morning using CodeToads sketch.

 

processChar takes about 13-14us in when not calling onDcsBiosWrite

processChar takes about 60-66us when making a call to onDcsBiosWrite (w/o LCD update)

processChar takes about 16ms when making a call to onDcsBiosWrite (w/ LCD Update)

pollingInputs takes about 11-13us

 

I have to do the math to figure out max baud rate without loosing data on that one... 250k still seems to miss some things on the initial load.

Posted

Ian I'll try the radios again tonight and let you know how it goes with the new version.

 

I'm still banging my head against the shift registers. I'm not sure how to get a pointer to a specific bit in the variable (to see if its 0 or 1). Should I make some sort of array?

Posted

Probably best to post those kind of questions onto a programming / microcontroller forum. You'll progress faster if you break down problems. If you're trying to learn shift registers separate that task from the cockpit. The forums over at arduino.cc are a great source for questions like how to use a shift register. You might also try checking out the AVR Freaks site (http://www.avrfreaks.net).

 

Once you know how to read and process shift registers come back and combine that with the DCS-BIOS library. The same goes with anything else related here. If you want to do an LED output, make sure you understand how to do an LED safely with out DCS-BIOS first (You can't just connect one with out some math unless you want to possibly fry it or your arduino board.)

 

That being said you need to learn and operator (&), or operators(|) and bitmasks.

Posted

Pointers have byte granularity. You need to look up bitwise operators.

Here are a few examples that you should try to understand:

 

unsigned char foo = 42;  // (00101010 in binary)
if (foo & (1<<0)) {...} // is bit 0 set? (no)
if (foo & (1<<3)) {...} // is bit 3 set? (yes)
foo |= (1<<2); // set bit 2 (foo is now 00101110)
foo &= ~(1<<5); // clear bit 5 (foo is not 00001110)
foo &= ~(1<<7); // clear bit 7 (nothing happens, it is already 7)

 

foo: 0 0 1 0 1 0 1 0
bit# 7 6 5 4 3 2 1 0

Posted
Probably best to post those kind of questions onto a programming / microcontroller forum. You'll progress faster if you break down problems. If you're trying to learn shift registers separate that task from the cockpit. The forums over at arduino.cc are a great source for questions like how to use a shift register. You might also try checking out the AVR Freaks site (http://www.avrfreaks.net).

 

Once you know how to read and process shift registers come back and combine that with the DCS-BIOS library. The same goes with anything else related here. If you want to do an LED output, make sure you understand how to do an LED safely with out DCS-BIOS first (You can't just connect one with out some math unless you want to possibly fry it or your arduino board.)

 

That being said you need to learn and operator (&), or operators(|) and bitmasks.

 

I will probably do that (post in another forum) if I dont figure it out by myself. I managed to send inputs to dcsbios with shift registers but it's at a very primitive state right now. I am making progress but very very slowly. I probably should just bite the bullet and start from zero rather than trying to understand other peoples' code and modify it.

 

You mean about the 7seg screens code I wrote a few days before? I didnt do the math ( I actually did quite some time ago and misplaced the paper) but an external power supply (nothing crazy just a couple Amps or so) will be necessary if your are connecting a lot of them. USB is limited to 500mA and the ptc fuse will pop if you try to pull more than that. I just got a 2A 9v supply and a 5v regulator from ebay they are very cheap. I'm using a 68k resistor on the max7219 and they are bright enough. Depending on the led you can usually get away with driving them at 50% current.

 

Yup I am reading up on the bitmasks. Biggest problem for me right now is to understand the bigger picture of how to send the data where I want it.

 

Ian;2297624']Pointers have byte granularity. You need to look up bitwise operators.

Here are a few examples that you should try to understand:

 

unsigned char foo = 42;  // (00101010 in binary)
if (foo & (1<<0)) {...} // is bit 0 set? (no)
if (foo & (1<<3)) {...} // is bit 3 set? (yes)
foo |= (1<<2); // set bit 2 (foo is now 00101110)
foo &= ~(1<<5); // clear bit 5 (foo is not 00001110)
foo &= ~(1<<7); // clear bit 7 (nothing happens, it is already 7)

 

foo: 0 0 1 0 1 0 1 0
bit# 7 6 5 4 3 2 1 0

 

Thanks! I understand the first 4 lines but I didnt yet encounter the ~ so I'll study that now and see if I make any progress.

Posted

hmmm well the code works better now with your bitmask advice but I seem to be flooding the listener with inputs. almost as if my switches are floating. probably messed something up somewhere, I look into it tomorrow.

 

thanks again for the pointers

  • Recently Browsing   0 members

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