I did some browsing for inspiration and found other nicely presented widgets, digital vehicle dash displays, helicopter and fixed-wing instruments, and F1 simulator HUDs. I merged these elements into a look that I liked. I knew I wouldn't be able to write the code to make it look exactly as I imagined, so I decided to use a background image and lay out all the information on top of it. This led me back to Blender for the design of the background.
I’m not going to spend a lot of time describing how I did this—there are plenty of Blender tutorials online and nothing I did here was particularly complex. I simply set the resolution to match the TX16S (480 X 272 pixels), added a camera set to orthographic, and positioned it top-dead-center over the design. This way, I got a render that laid out perfectly on the transmitter screen. From there, I placed some circles and rectangles until the composition felt balanced, then refined them into the finished product. I also added a bezel to keep it visually interesting, inserted lighting from right to left, and created some blocks around the gauges to produce a shadowing effect. I set some of the letters and numbers as emitters for a bit of extra "pop" and rendered the background image.
I’ll be the first to admit that when it comes to coding, I’m a little rusty—and to be honest, I was never that good at it. The good news is that Lua is not overly complicated, so I was able to dissect the code and figure out how it was working pretty easily. Re-writing the gauges and graphs wasn't too difficult, but I decided to make some artistic changes and wrap a few gauges around circles, which made filling them considerably more difficult. After a few hours of attempting some "ugly" workarounds, I finally threw in the towel and asked Google Gemini for help. It was a good thing I did; it managed to come up with some great solutions along with suggestions I hadn’t even considered. One of my favorites is a "ghost bar" that tracks peaks and maintains its position for a short period, giving you a chance to see the peak values before it slides back down to match the current position.
Starting with the star of the digital dash: the RPM gauges. I’ve got my Nexus set up to report back both headspeed and tailspeed, so I’ve configured the display to show both. The only things I’m actually drawing onto the background image here are a needle that points to the correct value and a digital readout of the RPM.
This next snippet of code is responsible for creating the needle. One of the problems I had with the original code was uneven widths and an overall "jagged" appearance. This was the first problem Gemini helped me solve, and I was happy with how robust the solution was. I now have options to change the length and width easily, or even change the shape with relative ease.
Once the needle was made, I just needed it to swing to the correct angle. Gemini solved this within the needle shape function as well. All I had to do was define the start and finish points using the retrieved telemetry values. Gemini also suggested using low-pass filters to smooth the needle movement, which turned out to be an excellent addition! It looks so much more natural moving with some perceived "weight." All that was left was to print the RPM value in the rendered box using the lcd.drawText() function. I also wanted to note that the reason there are two separate calls to drawShoulderedNeedle() is that I'm using one of them to create a shadow effect from certain angles.
The battery gauge is where I got into a bit of trouble. I thought it would look sharp if it wrapped around the RPM gauge, but I neglected to realize how difficult that would make the "fill" logic. Luckily, Gemini came to the rescue after several hours of my own failed attempts. It made quick work of this by utilizing the lcd.drawAnnulus() function.
The current consumption gauge is deceptively complex. It seems like a standard bar fill with a color change, but it implements the "ghost bar" suggestion. This is one of the coolest features in the dash. The code creates a ghost bar that shows the peaks, then glides back down to meet the current value. It really helps you catch what kind of values you were hitting mid-flight.
This turned out to be something that I had a lot of fun with. I had this operational before I started working with Gemini, but it made some serious improvements to it, including smoothing the needles and shaping them, along with creating a really neat little triangular pointer that rides the edge of the gauge.
I tied the variometer gauge (VSI) to the altimeter, and this was difficult to get right because the gauge has to "cut out" the circle around the vertical bar fill. In the end, Gemini found a solution that looks very sharp. The variometer also uses the ghost gauge logic.
I’m not going to spend time on the simpler features of the dash. You can find the Lua script and background image below if you’re interested in implementing the Digital Dash on your own TX16S or altering the code to your liking. I hope this inspires you to download Blender and take a shot at making your own custom display!
One last word: keep in mind this was just a weekend project for me, so the code is a bit unpolished, and I ran out of time to clean it up. Feel free to fix it up, make improvements, and create something special!
Enjoy...