Jump to content

Connect a PS/2 keyboard to your CDU with an Arduino and DCS-BIOS


FSFIan

Recommended Posts

Someone on my squad's forums asked if this is possible. Since I had a PS/2 connector in my parts drawer and a spare keyboard on my shelf, I just went ahead and did it. Posting it here too in case it is useful to someone.

 

Step 1: Use SAW with BROKEN MOTHERBOARD to get a female PS/2 connector. Alternatively find a sacrificial keyboard and cut the cable.

 

arduino_ps2_keyboard.jpg

(Yes, that's a keyboard connected to the mouse port because that was the one I had already soldered wires to.)

 

Step 2: Connect VCC and GND to your Arduino's VCC (5V) and GND. Connect the CLOCK pin to digital pin 3 and the DATA pin to digital pin 4.

Here's a pinout of the PS/2 connectors.

 

Step 3: Find and install a PS2Keyboard Arduino library

 

Step 4: Adapt the example a bit so you end up with this code

 

Enjoy!

 

It would be great to find (or write) a PS2Keyboard library that does not give you finished upper/lower-case characters but instead passes on the make- and break-codes that the keyboard generates, so you get separate "KeyDown" and "KeyUp" events. Then the button in the cockpit would actually be held down as long as you hold down the real button.

 

It may also be a good idea to map F1 through F6 to the SYS, NAV, WP, OSET, FPM and PREV buttons. Unfortunately, this PS2Keyboard library does not appear to support function keys.

 

Page Up / Page Down: PG rocker switch

Enter: MK button

Backspace: BCK button

Spacebar: SPC button

Left/Right arrow keys: blank rocker switch

Escape: CLR button

Tab: FA button

+/-: +/- rocker switch

".", "/", letters and numbers work as one would expect.

 

Only the LSKs, the SYS/NAV/WP/OSET/FPM/PREV buttons and the non-functional DIM/BRT rocker are missing. With some additional work or another PS2Keyboard library, these could be mapped to the function keys and remaining control keys (Ctrl, Shift, etc).

Link to comment
Share on other sites

what can i say, this is very timely. not exactly what i had planned, but i will be following.

 

i'm working on CDU at the moment. mechanical drawings near complete, still need to test if my back light solution is plausible. for interfacing i'm thinking to use raspberry pi: composit vid out, on-board network and USB host (for keyboard). salvaged a keyboard USB controller from a specimen that sticks due to meeting coffee. traced the leads and constructed CDU oriented matrix, now building PCB for this in kiCAD . was thinking to make something like IRIS, capturing a CDU screen area and displaying on 3.5" rear view camera screen, but your export Ian simplifies things significantly.

 

now i just need to study me some Python...

512952617_kbdmtrxmap.thumb.jpg.80a516cd8f756bbd412a7ed438ce0e4d.jpg

1851637751_cduwip.jpg.e43b861e0311457573ee31658972fe89.jpg


Edited by agrasyuk

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

  • 2 weeks later...

Anton, because the CDU is such a prominent feature in the cockpit, the method of backlighting that you employ will have a huge impact on the visual component of your cockpit. I spent many nights looking at various solutions. What I finally decided upon required a lot more effort but in the end it was worth the extra time and money (not so much money). The final result looked really good.

 

This thread illustrates how I implemented the backlighting. (scroll down halfway)

 

https://www.combined-ops-group.com/forum/viewtopic.php?f=18&t=1341

 

I used 3528 SMD LEDs which can be purchased for almost nothing if you buy Chinese. Unfortunately, I can't show you a pic of it completely assembled because I haven't found a suitable display yet. Ian's DCS-BIOS has made me rethink the selection of displays that I could use considering I no longer need to rely on a graphics card output to display the CDU text.

 

Anyways, it gives you another option to consider and maybe even spark some new ideas or completely different approach.:).

 

Good luck with it. Looking forward to seeing your pics when its complete.

Regards

John W

aka WarHog.

 

My Cockpit Build Pictures...



John Wall

 

My Arduino Sketches ... https://drive.google.com/drive/folders/1-Dc0Wd9C5l3uY-cPj1iQD3iAEHY6EuHg?usp=sharing

 

 

WIN 10 Pro, i8-8700k @ 5.0ghz, ASUS Maximus x Code, 16GB Corsair Dominator Platinum Ram,



AIO Water Cooler, M.2 512GB NVMe,

500gb SSD, EVGA GTX 1080 ti (11gb), Sony 65” 4K Display

VPC MongoosT-50, TM Warthog Throttle, TRK IR 5.0, Slaw Viper Pedals

Link to comment
Share on other sites

John, aside the fact that the site required me to register to view, your stuff looks really good :) indeed lit butrons are a must. Very interesting solution with dual PCB. Maybe I'm going overboard, but i really don't like the feel of those small 6mm tact switches. I went with 8.5mm tacts, they have 1.3mm travel and a nice click at the end of range. For lighting I'm testing LEDs positioned on same PCB in between switches (with mid layer of panel designed to accommodate that).

 

At the moment I'm stuck at routing the PCB.

Button matrix is designed so letters and numbers on keypad match those the keyboard. Since buttons on CDU are not positioned with ordinary querty keyboard controller in mind and routing is just hell. Density and the fact 8.5 tacts don't provide internal connection for jumping over leads is really not helping.

I do wonder however if all this effort is justified though - chances that keyboard controllers are not standart... I'm so close to just make it with proto perfboard and build the connections manually...


Edited by agrasyuk

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

Had a quick look at that library today and you can map the F keys, you just need to set a value for them in the .h file. Also, in would not be too difficult to return the scan code rather than the character code, just do not convert it and save it to the buffer. You could then call the function that converts the scan code yourself. I think a better way though, would be to return the character byte and a second byte that has the bit for key pressed or released and bits for any modifiers.

Link to comment
Share on other sites

  • 3 weeks later...

Ian, following up on our private conv: see attached pic for a quick status update.

In short: I now have capability to print CDU lines with actual .TGA font from the game indicatortextures folder. Library that acomplishes rendering the tiled text is located in git repository i forked from you.

Now I just need map the chars incoming from the sim. 3am over here now.

 

For those wondering: I'm working on displaying a CDU screen on networked raspberry pi board without any viewports. once the code is finalized i will switch over regular monitor to 3.5" display

20150206_024017.thumb.jpg.7cde68258e5158a3e70450ffe16474f5.jpg


Edited by agrasyuk

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

I have updated my example to show how to draw the CDU using Python 2 and pygame.

 

cdu_export_example.png

 

To make it work, you need to copy C:\Program Files\Eagle Dynamics\DCS World\Mods\aircraft\A-10C\Cockpit\Resources\IndicationTextures\font_A-10_CDU.tga to the directory you start the script from.

It should handle all the special symbols correctly (refer to this commit message for the exact mapping).

 

Tested on 64-bit Linux with Python 2.7 and pygame 1.9.1 and on 64-bit Windows 7 using 32-bit Python 2.7 and the (32-bit) pygame 1.9.1 package from pygame.org.


Edited by [FSF]Ian
Link to comment
Share on other sites

Ian,

your example didn't work for me out of the box.

 

as i read through your code i noticed that you configure the socket as such:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((IP, UDP_PORT))

s.settimeout(0)

 

however in my local RPi lister script (tiny script that i use to see whether raw data is being recieved) i have socket configured as

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((IP, UDP_PORT))

 

when i try to revert my listener to "STREAM" mode as in your code, i get socket.error "connection refused". switching your code to use "DGRAM" also didn't make things work, i guess parser relies on exact type of connection . any input on this is very welcome.

 

PS,

not sure if it has anything to do with the fact i run FTP server on the PI( setup so so i can push code to the board faster )

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

SOCK_STREAM for tcp and SOCK_DGRAM for udp, calling connect on a udp socket may be the problem, also trying to connect a tcp socket to a udp socket would also fail. By the sounds of it you are using udp, try deleting the s,connect() call, and use SOCK_DGRAM, that may work.

Link to comment
Share on other sites

i have remarkable ability to waste time looking at less probable approaches and trying less probable solutions first... after i was done messing around sticking debug points around the code, i finally gave up on UDP, looked up the BIOSConfig.lua , created TCP server instead and connected to it from the PI - got the CDU displayed. Turned off mouse pointer. Configured the PI to auto boot and navigate to script folder on start - with the amount of reboots i did this saved some pain.

 

played with character scaling to fill entire screen. apparently despite pygame declaring exactly right screen size for itself raspberry still can default to some strange resolution when going via composite output. overriding resolution in /boot/config.txt solved this. had to adjust overscan to fill stretch the image closer to the screen edges.

 

20150210_004947-vi.jpg

 

 

 

 

response time, clicking on UFC buttons and seeing ltters appear in scratchpad, is very very good, almost immediate.

characters are very readable and image is quite OK for a being displayed over composite. colors of the cheap rear view 3.5 LCD are obviously washed out but for this application i don't think it matters to much.


Edited by agrasyuk

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

Several questions about next steps:

Keyboard input - Ian, code below does not stop the script, or at least doesn't on my side.

event = pygame.event.poll()

if event.type == pygame.QUIT:

sys.exit()

 

since event.poll() stores only the latest event i assumed there were more events that happened after ESC was pressed. I tried looping event.get() with same result. I do have kbd input working in my static screen test script however (can terminate the script gracefully). not yet exhausted and have couple ideas i will be trying out, but any input on this is appreciated

 

UDP vs. TCP

before reverting to TCP i tried to feed the parser byte by byte as you suggested with code below. to my understanding this was supposed to take care of things, but it obviously didn't

try:

wd = s.recv(256) #"s" is UDP bound

for c in wd:

parser.processByte©

 

sticking debug points (with print statements) it looked like each incoming message was being iterated properly - 40-60bytes long on average, i was able to capture individual bytes and then ord() them into charcodes. still the display was 24x10 grid of "?" chars (for unrecognized code).

i don't insist on using UDP, but at this point i'm simply curious on how this should be properly done.

i also wonder if using TCP means there is a limit on numbers of networked devices connected to the server.

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

I copied the event handling stuff from the first pygame beginner tutorial I came across.

After reading the documentation for the pygame "event" module, the proper way to do things seems to be:

  • loop through the results of pygame.event.get()
  • and call pygame.event.pump() in the main loop

 

I have updated my example on GitHub to handle events in this manner. I have also added example code that shows how to connect using UDP.

 

UDP is the preferred method, because it does not care about the order in which things are started.

 

Each UDPSender in BIOSConfig.lua and each TCP connection will add some small performance penalty, but I don't think a handful of them will make any noticeable difference. Performance-wise, the best option is multicast UDP, which also requires no configuration, but I would only rely on that as long as the receiving application is on the same computer as DCS.

Link to comment
Share on other sites

Needed a change of pace, put the keyboard away and did some hands on stuff

 

Anton, because the CDU is such a prominent feature in the cockpit, the method of backlighting that you employ will have a huge impact on the visual component of your cockpit.

 

still kind off on CDU topic:

testing my approach to making and iluminating CDU buttons. one led per two buttons, letters/numbers are more or less evenly lit. I will need to do several more layers of paint on the sides - was to anxious to try it out and one layer of black on layer of white is clearly not enough to stop the light bleed from the sides.

 

20150213_10433-vi.jpg

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

Needed a change of pace, put the keyboard away and did some hands on stuff

 

 

 

still kind off on CDU topic:

testing my approach to making and iluminating CDU buttons. one led per two buttons, letters/numbers are more or less evenly lit. I will need to do several more layers of paint on the sides - was to anxious to try it out and one layer of black on layer of white is clearly not enough to stop the light bleed from the sides.

 

]

 

 

Keep at it Anton. Your getting close. Backlighting is a tricky thing. I am still experimenting with different approaches that are relatively easy to implement but more importantly cost effective. As a matter of fact I just trashed the NMSP Korry switches I made. After all of that time and effort they just were not up to my standards of acceptable backlighting. I just finished rebuilding them and I finally have backlighting that looks great for that particular component.:)

 

Anton, how are you applying the paint and what kind of paint are you using for the push buttons?

Regards

John W

aka WarHog.

 

My Cockpit Build Pictures...



John Wall

 

My Arduino Sketches ... https://drive.google.com/drive/folders/1-Dc0Wd9C5l3uY-cPj1iQD3iAEHY6EuHg?usp=sharing

 

 

WIN 10 Pro, i8-8700k @ 5.0ghz, ASUS Maximus x Code, 16GB Corsair Dominator Platinum Ram,



AIO Water Cooler, M.2 512GB NVMe,

500gb SSD, EVGA GTX 1080 ti (11gb), Sony 65” 4K Display

VPC MongoosT-50, TM Warthog Throttle, TRK IR 5.0, Slaw Viper Pedals

Link to comment
Share on other sites

just a usual canned spray-paint. coat of white and then several coats of black.

 

Have you ever considered using an airbrush and Tamiya model paint. Both are available at hobby stores. The Iwata Brand of airbrushes are really easy to use and clean. This is what I use...

http://www.iwata-medea.com/products/iwata-airbrushes/eclipse/hp-bcs/

 

An airbrush gives you very precise control over how much paint you apply and the thickness of each layer. It makes the fiinished product so much better than using rattle cans. And when using an airbrush you have available a huge selection of good quality model paints by Tamiya or Modelmaster. Your choice of colours is so much greater. For instance, lots of panel parts need to be painted flat black but in fact there are several colors of flat black, all a little different. For cockpit parts I use Modelmaster aircraft interior black which is the matching black for what we are doing apposed to just plain old flat black. That small difference in color is quite astonishing.

 

Anyways, it's something to chew on.:)

Regards

John W

aka WarHog.

 

My Cockpit Build Pictures...



John Wall

 

My Arduino Sketches ... https://drive.google.com/drive/folders/1-Dc0Wd9C5l3uY-cPj1iQD3iAEHY6EuHg?usp=sharing

 

 

WIN 10 Pro, i8-8700k @ 5.0ghz, ASUS Maximus x Code, 16GB Corsair Dominator Platinum Ram,



AIO Water Cooler, M.2 512GB NVMe,

500gb SSD, EVGA GTX 1080 ti (11gb), Sony 65” 4K Display

VPC MongoosT-50, TM Warthog Throttle, TRK IR 5.0, Slaw Viper Pedals

Link to comment
Share on other sites

thank you for the suggestion John. i actually do have all the equipment for airbrushing (my other hobby is scale modeling). but its all still packed from the move. but more importantly i do need to build a spray-booth to use all those nice fuming solvent based paint stuff inside. i actually have a plan for a vent/hood/booth for my workplace , will be venting out the window (and will be helpful with soldering fumes too).

eventually i will build that too, for now its quick can spraying in freezing garage :)

 

 

 

ADD:

after some trial and error I got the script to respond to keyboard commands and found the proper way to send the CDU input to DCSBIOS server. so now i can key in cdu scratchpad data from the keyboard attached to the PI! response time, from the moment key pressed, string sent to DCS-BIOS, updated CDU screen text recieved and displayed is as if typed locally - perfectly appropriate. :)

 

what will be a challenge still is the fact that even pygame doesn't recognize all the keys. wrote a quick script to display pygame constant names of keys it sees as being pressed. Media keys not being seen i guess could have been expected, but both WIN keys recognized as L-ALT and Capslock as "Unknown" is really surprising. which means i can't connect my buttons to kbd controller arbitrarily and remap later...

 

and before i know its that time of day again, 2AM...


Edited by agrasyuk

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

what will be a challenge still is the fact that even pygame doesn't recognize all the keys. wrote a quick script to display pygame constant names of keys it sees as being pressed. Media keys not being seen i guess could have been expected, but both WIN keys recognized as L-ALT and Capslock as "Unknown" is really surprising. which means i can't connect my buttons to kbd controller arbitrarily and remap later...

 

and before i know its that time of day again, 2AM...

 

According to the pygame docs, those keys should be K_LSUPER and K_CAPSLOCK. I assume this is not a pygame problem (try running your program on another PC, for example locally on your DCS machine).

 

On the RasPi, open a terminal, type "xev" and press return. (You might have to install xev using the package manager). The xev program ("x events") will print all input events it receives to the console. With the input focus on the xev window, press the keys.

 

On my linux laptop, the output looks like this when pressing the left windows key:

 

KeyPress event, serial 33, synthetic NO, window 0x1a00001,
   root 0x7e, subw 0x0, time 280767109, (570,155), root:(571,156),
   state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
   XLookupString gives 0 bytes: 
   XmbLookupString gives 0 bytes: 
   XFilterEvent returns: False

KeyRelease event, serial 33, synthetic NO, window 0x1a00001,
   root 0x7e, subw 0x0, time 280767205, (570,155), root:(571,156),
   state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
   XLookupString gives 0 bytes: 
   XFilterEvent returns: False

 

If that says L_META or something (Alt key) on your system, the error / misconfiguration is outside of pygame (and you might want to google "Xmodmap").

Link to comment
Share on other sites

thanks Ian, now i know what is the "x" in xev stands for :). i also found its command line counterpart - "showkey" command. all those media keys are perfectly visible to RPi. not sure if doing raspbi-config and switching from generic104 keyboard dell multimedia had any part in it, i did it before trying xev.

 

looked at xmodmap, found but again, the "X" in it's name probably means it applies to GUI, while i'm trying to make a pure command line script. at the moment i'm looking at using loadkeys solution.

 

and while i'm at it i imported GPIO lib into the script. i think i will have AAP connected to the PI as well.

will be testing if those additional event callbacks affect performance

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

  • 4 weeks later...

Nice work Anton. Now a question for both Anton and Ian, Probably a numpty question, I'm good at the missing the obvious, but is there a particular reason why you haven't used a joystick input? (As opposed to keystroke?)

 

Also if you are looking for a reasonably simple to use PCB drawing and layout package, Diptrace is free to 300 pins. I struggled with Kicad, and found Diptrace works a treat.

 

Cheers

 

Peter

Link to comment
Share on other sites

thanks Peter, those i had to order, hopefully someday laser to cut 2mm aluminum in household garage will be a reality. I'm not sure i'm tracking your thought with a joystick. i went with keyboard since it is instant 100 buttons matrixed at cost of 10$ or below. but RPi has more USB connections so it can easily have a joystick as well. as the mater of fact i'm also working on AAP panel that will connect to RPi CDU board to share that that networked connection, and in case GPIO interupt code going to degrade CDU screen refresh times i will revert to using Joystick via onboard USB.

 

as far as EDA software hint thank you. kicad indeed is making me feel stupid. after several tries i did manage to build it properly, but the mentality of workflow I just can't get used to. while i could create a PCB example i still don't understand how to import DXF with physical button sizes and locations.

will be trying Diptrace

Anton.

 

My pit build thread .

Simple and cheap UFC project

Link to comment
Share on other sites

  • Recently Browsing   0 members

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