Jump to content

My KSP control panel


stibbons

Recommended Posts

After a month of busyness at work and then Christmas shenanigans, I finally got a chance to get back to working my controller hardware. Earlier this month I did manage to laser cut a final panel for the display. Today I got almost all of the work done actually mounting it.

Started by soldering the arduino, controller and other bits on to protoboard. While trying to figure out how I'd hold the board on to the back of the display, I discovered that I'd accidentally managed to make the mounting bolts fit very closely to the 0.1" pitch on the protoboard. So I was able to just drill out a couple of holes and slip them over the bolts. Very handy!

Testing the board after reconnecting everything was a little bit stressful. I started out running an Adafruit test sketch, which resulted in nothing but a blank screen. Took a good half hour of hair pulling and line tracing before I realised that the Adafruit library doesn't play nicely with Teensy. Switched to my other test code and the whole lot fired up first try, much to my relief.

SSGi0Wm.jpg WkdIP4Y.jpg

Then came mounting the display panel in the controller. I used the bamboo test panel I cut last month as a template to mark mounting holes and an outline on the controller. Then, heart in mouth, drilled out the holes and finally cut a new hole through with a jigsaw. This was done without removing the other panels, which was a little bit awkward. That's why I managed to end up with some scuffs and dings in the paintwork, and some awkward MDF dust wedged under the cover of the annunciator panel. Luckily I bought way too much of the metallic paint - touching it up shouldn't be a problem.

rUkto9x.jpg os9fX7c.jpg

Looking carefully makes it pretty obvious I'm getting worse at keeping my edges straight. But apart from that I'm super happy with how this the controller is looking now. Can't wait to fire up the display again soon.04RfgvG.jpg

Edited by stibbons
Link to comment
Share on other sites

I've had a little more time this month to work on software. Refactored a lot of the display sketch. It's a little neater, a little bit faster, and has less duplication and seedy hacks.

I was still struggling to figure out how to reduce the size of the KSPSerialIO data packet though. Right now all of the axes that are sent (15 of them!) are 4 byte floats holding a number that can be either 0-360 or -180-180. My first thought was to convert those to a smaller fixed point representation, so I spent a fair bit of time wrapping my head around how fixed-point calculations work. Eventually got a prototype working using 10.6 fixed point numbers, but the accuracy seemed abysmal. I was getting random variations that could go to more than 0.1 away from the original floating point number, unacceptably high. So I put the problem to one side while Christmas happened.

Eventually hit upon a possible solution based on how things are done in the real world, while reading Frank O'Brien's The Apollo Guidance Computer: Architecture and Operation in a tent in an outback South Australian town over Christmas. The Inertial Measurement Unit in the PGNCS sends pulses to the AGC indicating rotation around each axis, and it's up to the AGC to count them to measure rotation. A full revolution around an axis contains 32768 pulses, which makes sense seeing as the AGC uses 15 bit data words. Essentially, angle on an axis is measured as a number between 0 - 32767.

At first I found it curious that the AGC's angular resolution of just over 0.1 degree was quite close to the error I was seeing in my fixed-point representation. But then I realised that if KSPSerialIO maps each axis' angle to a signed 16 bit number then I'd have a range of -32767 - 32767. It'll be a constant error, much better than the variable floating-point gumpf I had to deal with before, and at twice the resolution of the 8balls the Apollo astronauts used. In your face, Neil Armstrong!

Now that I'm back home I guess I'll be spending some time reworking my vector code in KSPSerialIO again, converting it to use a standard integer rather than sending degrees. And then reworking my display code to deal with the new format. Hopefully shouldn't take long to restore functionality though.

Link to comment
Share on other sites

  • 2 weeks later...

Quick update full of pretty pictures now that I've finished assembling all of the hardware.

Started by cutting a bezel from thin blue cardboard, and a cover from a sheet of thin clear PVC. Took a few attempts to get this right, and a lot of fiddling around. But I'm super happy with how it looks. And it was great to finally remove the protective sheet on top of the display. :D

0cuA7Bl.jpg

From the back, my 3D printed brackets sandwich the display, bezel and cover in place. Above that, the display controller and teensy are mounted on a prototyping board, along with header pins to connect the switches, and terminals to connect power and the i2c bus hooking it up to the rest of the system. I'm really really proud of how the front and back of this panel look, to be honest. Probably my favourite part of this build.

iWpuuns.jpg

The final step, screwing this panel in to place and hooking it up. Boom.

Tm6RDxh.jpg

The Arduino code and my KSPSerialIO changes to drive all of this is still in a fairly broken state. I've been putting off tying all of the pieces back together until I had the hardware fully assembled. But I've now run out of excuses. Back to software hacking!

Edited by stibbons
Link to comment
Share on other sites

I spent a very late night last week fixing the buttons on my navball display. I'm using hardware pulldown resistors for every switch on this build, and I'd forgotten to connect the pulldowns on my navball buttons to ground. That left all of the buttons floating and some very confusing inputs to my test code. But after I fixed those I was able to implement the GUI for the mode switching to emulate the on-screen display.

I also uncovered a bug in the RA8875 display library. Attempting to use customised fonts leads to the user icons becoming corrupted and not rendering properly. So all of my text is being written with the single built-in font. Luckily after trying it I absolutely love the single built-in font, and am very happy with the overall retro look of the navball. This is seriously one of my favourite photos from this build.

VkWUVjD.jpg

There's a good chance I'll increase the navball rendering size, and probably move it to the right a little. But it looks awesome.

The rest of my current work lies in completely overhauling the vessel attitude code in KSPSerialIO, and adding a lot of code to send orbital vectors. The current code sends floats showing pitch, heading and roll as straight degrees. But I'm trying to save space by converting all of those to unsigned integers. I've had to tweak all of the conversions a lot to make sure I had something that was still accurate and backwards compatible with the old system with minimal effort.

I develop both my arduino code and my plugin code on a tiny Mac Air. I have a large Linux gaming rig that I run KSP on, and the controller is plugged in to that. So the way I'm verifying all of my code is to have the laptop SSHed in to the gaming rig and streaming KSP logs. At the same time, I have a serial connection from my laptop to the arduino that runs the navball rendering and it's dumping its interpretation of the KSPSerialIO data. And finally I've started using the kOS terminal to set the orientation of my test vessel, so I'm using the telnet console through my laptop as well. It's a wonderfully bizarre workflow.

q2WIFdB.jpg

It's taken a few attempts at modifying how I'm converting numbers back and forth, but I think I've finally got a system that is reliable and easily backwards compatible with the old KSPSerialIO directions. Anybody who was using the old stuff will need a new function added to their arduino code, but nothing too onerous I hope.

The first time these two images consistently lined up tonight was super satisfying.

nDhJv2x.jpg

My KSPSerialIO patch is sending prograde, normal, radial, as well as surface prograde and target direction and prograde in the same format. In theory I just need to use my existing code to transform each of those back to degree rotations, then use those to rotate a (0, 0) point to get the coordinates to draw the appropriate icon. But that's a job for next time.

Link to comment
Share on other sites

  • 3 weeks later...

I gave a short talk on some of this build at the open hardware miniconf at linux.conf.au last week. It was also the first time I've been able to get some feedback on the layout from experienced KSP players having a crack at using it, which will be very useful when I get around to re-doing how the displays are organised.

https://www.youtube.com/watch?v=AVXr9tLTQEE

Progress on the navball is still slowly grinding along. I've realised that the way I'm calculating relative pitch and heading is OK for yaw/AoA readouts, but completely unsuitable for rotating a navball. Got something that I think works, but haven't really had time to properly test this stuff yet. Hopefully soon.

Edited by stibbons
Link to comment
Share on other sites

14 hours ago, Sputnix said:

I seriously need to look into sharing the processing load with a separate arduino!

I love the idea of using I2C to shunt packets off to separate display controllers. But like I said, you really, really don't want to try to use the standard Arduino libraries to do that. I really should clean up the AVR I2C libraries I've been working with and release them properly.

Also, thanks. :D

Link to comment
Share on other sites

  • 3 weeks later...

This just makes me realize how far off I am with my hardware version... :(
I know how to do the hardware, but I just do not have the programming side of it down. I have a LOT to learn to get this up and running! :confused:

It is an inspiration though to keep moving forward! :)

Edited by richfiles
Link to comment
Share on other sites

  • 1 month later...

This project isn't dead, it's just resting.

Real life hasn't been leaving me with a lot of time or energy for hard hacking in my own time. So, apart from some light poking to see if KSPSerialIO will work properly in 1.1, I haven't really been involved in any development for this project at all. That's going to continue for another month or two. :(FtSVOV9.jpg

What I have been thinking about, though, is replacing my current Arduino Mega arrangement. Right now it consists of an Arduino board, with a multiplexer shield stacked on that, and a protoshield above it containing a handful of IDC sockets and a hilariously awful mass of connecting cables. It's an excellent working prototype, but gosh.

The multiplexer made sense when I started and didn't really know the size of what I wanted to do. But now I realise that what I've got is well within the scope of native handling for a Mega, it makes sense to remove it from the equation. That should save me a lot of time - each multiplexer pin requires four pin writes before I can read it, and right now my input loop does this twenty times every few milliseconds. Using native inputs means I can read an entire port in to bitfield variable in one or two cycles, super convenient as my code is already set up to debounce and handle these bitfields.

So I've started idly working on a replacement PCB for all of this, similar to my current display controller, but embedding a bare ATmega 2560 rather than plugging in a separate Arduino board. Should be pretty fun. :)

 

Link to comment
Share on other sites

  • 1 month later...

wtf ... are you doing there ... that's exactly the same i wanted to do ... but i'm just building crap :ugly: ^^ - The only thing i do not like is this eye cancer blue light irradiation :cool::wink: ...

... but : That  is awesome ! ... especially the NAVball-thingy ... I WANT ! -In my project i wanted to distribute RX data to other uC's to distribute workload, just by listening to Arduino#Master DIO 0. That worked, but failed sometimes, too bad to keep.

Now i'm wondering, are you doing your whole cockpit just by one MEGA ¿?

 

 

Link to comment
Share on other sites

4 hours ago, Gemini0915 said:

The only thing i do not like is this eye cancer blue light irradiation

Hah. :P I don't remember why I picked blue way back at the start of this project. I think it came down to which colours the big seven segment displays were available in, and the blue one looked nicest. I still have plans to add a display brightness control, but so far I've found that the hard wired brightness I have set now seems to work well under all lighting conditions I play the game in.

5 hours ago, Gemini0915 said:

In my project i wanted to distribute RX data to other uC's to distribute workload, just by listening to Arduino#Master DIO 0. That worked, but failed sometimes, too bad to keep.

Now i'm wondering, are you doing your whole cockpit just by one MEGA ¿?

No. A single Mega would probably be OK for this many controls and LEDs, but definitely can't drive the display as well. I'm using three different microcontrollers

  • An Arduino Mega for the serial connection to my computer, and it has all of the inputs connected to it.
  • An Arduino Leonardo (a pro micro board), which controls all of the LEDs and outputs.
  • A Teensy that just drives the TFT screen. Rendering the navball takes some pretty serious processing.

I'm using I2C to send data to all three controllers. The Mega acts as an I2C master, and whenever it receives a data packet from the game it sends that packet to all of the slaves. The slaves then display information out of the data packet in their own time.

Link to comment
Share on other sites

On 31.5.2016 at 0:01 AM, stibbons said:

add a display brightness control

I think it's quite hard to achieve that, except you are using exclusively  matrix drivers like the MAX7219 with a digital brightness control feature. A hardware solution with a main PWM signal controlling a bunch of transistors connected by much more wires could also work ... but i think wearing sunglasses in a space capsule is the most convenient way :)

 

On 31.5.2016 at 0:01 AM, stibbons said:

I'm using I2C to send data to all three controllers. The Mega acts as an I2C master, and whenever it receives a data packet from the game it sends that packet to all of the slaves. The slaves then display information out of the data packet in their own time.

Sounds like the solution i will use too, are you using the 'EasyTransfer' library ¿?  ... actually building a real NAV ball with 3D printed parts is my final goal for my cockpit project. This thread inspired me, has said to me build me ^^

Link to comment
Share on other sites

4 hours ago, Gemini0915 said:

 

On 5/31/2016 at 8:01 AM, stibbons said:

add a display brightness control

I think it's quite hard to achieve that, except you are using exclusively  matrix drivers like the MAX7219 with a digital brightness control feature. A hardware solution with a main PWM signal controlling a bunch of transistors connected by much more wires could also work

 

Yeah, for the MAX7219 drivers I'm already setting a very low brightness. And the other LEDs are also under digital control and driven using the FastLED library. FastLED does the hard work scaling colour values down for lower brightness.

I'm already driving most of the displays with quite low brightness, and then use photographic tricks to make the colours appear brighter in pictures. :D Tempted to redesign the displays a little to include dim covers.

4 hours ago, Gemini0915 said:

Sounds like the solution i will use too, are you using the 'EasyTransfer' library ¿?

Nope, I hadn't heard of it before, but it looks pretty nice.

I had a lot of problems getting I2C to work, because the built in Arduino libraries for it aren't well suited to the data rates KSPSerialIO needs. I wrote my own I2C driver libraries instead. See this post for a longer explanation about how and why. 

 

Link to comment
Share on other sites

  • 4 weeks later...
  • 2 weeks later...

Inspiration struck this week and I started planning a new enclosure for this build. Now that I know all of the hardware that's in it, I can build something that's a lot more compact and I'm planning on taking the time to do a better job of it.

Spent some time this week sketching up ideas and figuring out a new layout for the instruments I have. Today, with required dimensions sorted out, I was able to draw up designs and attempt to start cutting them.

I'm planning on a split sloped and angled design. The left and right sides cut from the same MDF I used for the first enclosure, like this:

wMX00ww.png

The left and right are slightly larger, and the blue lines will be cut as grooves for the other faces to slot in to. The front and top faces will almost certainly be aluminium composite (Dibond). I was impressed with the finish Mulbin was getting on his panels, and am pretty sure it's rigid enough for large panels without sagging. The back and bottom will be MDF, but much thinner than the sides. The 12mm stuff I used for the last enclosure was massive overkill.

The rest of the day was spent learning how to use the CNC at my maker space. These things are a lot more complicated than a laser cutter, but really really fun.

6ia18Eu.jpg

It... did not go especially well. A couple of failed attempts, one very nearly broken spindle motor, some creative swearing. I learned a lot though! Hoping to get the side panels cut properly in the next few days.

Link to comment
Share on other sites

13 hours ago, stibbons said:

6ia18Eu.jpg

It... did not go especially well. A couple of failed attempts, one very nearly broken spindle motor, some creative swearing. I learned a lot though! Hoping to get the side panels cut properly in the next few days.

Learning is the main objective of anything, especially kerbal-related :D

Now, that huge 18mm(?) MDF on the base, is that what you're carving the panel out of, or is that just there to sit your piece of wood on? :huh:

Link to comment
Share on other sites

2 hours ago, Sputnix said:

Now, that huge 18mm(?) MDF on the base, is that what you're carving the panel out of, or is that just there to sit your piece of wood on?

Top to bottom, there's a sheet of 12mm MDF that I was trying to cut my part from. Under that is a 3mm sheet of scrap material. The big 18mm sheet below that is the CNC's spoilboard.

Link to comment
Share on other sites

On the hardware side, I've been struggling all week to cut the parts I need for my enclosure. Have learned an awful lot about CNC milling in the process, and haven't slept nearly enough. Go figure.

On the software side, I've been reading up on how C# does serial port access, and attempting to streamline the currently fairly kludgy way the cross-platform KSPSerialIO fork polls for new data. I've written a new asynchronous serial receiver for the plugin, that handles the serial receive side of things in a background thread instead of polling for new data every frame. It looks like I'll be able to get that working on OS X and in Linux. But my testing in Windows 10 is currently looking super weird, so my goal of having a single serial method across all platforms is still not quite there.

Hoping to push out a new version of the KSPSerialIO cross-platform plugin by the end of the weekend.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...