miniAVX v3.0.0 (FINAL) - DIY Arduino Mini Avionics Panel

Hold on. I am not the Bits and Droids developer. You have to reach out to him and see if he can code this feature. In essence though, the BitsandDroids app will need to be running on the PC and acts as intermediary between MSFS 2020 and your arduino. As it stands right now, you can receive values for simulation variables into your arduino for display on attached LED’s etc , and fire events in the simulation based on switches and knobs attached to the arduino.

I am working on my own solution just for fun. However, can’t really promise a stable or complete product. For one thing, it’s my first time coding Windows Form, and I am using pointers.

Chris

I can verify that Speech Synthesis is available in Windows Form. But its a generic computer voice.

Basically, your copilot is a robot.

Chris

Yes, more or less plug and play. A separate application, the BitsAndDroidsConnector needs to run as an interface between the Arduino and SimConnect. It configures the COM ports and selects the variables to be received.

1 Like

Finally finished “The Box”.

Now just need to adjust the digit display in the library and try out Form1 beta test.

Interestingly, the 12th led button blinks on boot and sketch upload. I found out that IO pin 13 was connected to the onboard LED Blinky by default. Also found an awesome implementation of button debouncing.

Chris

How is performance? No lags?

I have played with my MiniAVX the last couple of months and added a ton of new features which make flying much more “hands on”.

Please refer to Github for the latest version.

Pontiac51/miniAVX: MSFS Radio and AP panel with Arduino (github.com)

UPDATE 1.87 (BitsAndDroids v0.8.7)

  • NEW TRIM percentages for elevator, aileron and rudder, main button switches elevator and aileron
  • NEW Elevator trim has coarse/fine setting (turn slowly on coarse); left button to switch (. means coarse)
  • NEW Autopilot Master ON is displayed with an “A” on HDG page (no function to switch OFF/ON, display only)
  • NEW VS rates at -1000 and below display a thousands seperator, e.g. VS at -1200 feet would read as “-1.20”
  • NEW All autopilot modes display a dot after the last digit, e.g. HDG “350.” means HDG autopilot is active
  • CHANGED Menu order: TRIM - ALT/SPD - Autopilot (HDG, GPS, ALT, VS, OBS) - Radio (COM, NAV, ADF, XPNDR)
  • CHANGED Moved baro setting to ALT - SPD page, press left button to show QNH
  • CHANGED Moved GPS course to HDG page
  • FIXED Renamed ALTs and SPDs to proper abbreviations

And already the next BIG update. A friend of mine moaned abouth the font on the OLED being too tiny to read. So I have exchanged that for a MASSIVe 16x16 pixel font. :wink: Redesinged the menu as well, no more cursor. And redid the logic behind the ALT-SPD page (now SPD-ALT), which does allow to display all settings (IAS, GS, MSL, AGL, QNH) independently.

UPDATE 1.90.087 (BitsAndDroids v0.8.7)

  • NEW BIG font for menu items (BigFont.c; ADD to OLED_I2C library)
  • NEW Selected item now shown inverted, Cursor “>” removed
  • NEW Version number now shows BAD version as well
  • CHANGED Altitude can now be switched between MSL and AGL with main button independently
  • CHANGED Speed can now be switched between IAS and GS with left button independently
  • CHANGED QNH can now be switched ON/OFF with right button on SPD-ALT page
  • CHANGED Redesign of UI for better readability

1 Like

You could use a different knob with a pointer.

Seems to be doing fine. I am testing nav1 and com1 radio. The ingame change when I turn the encoder is near instantaneous. However, the propwash encoder takes two detents before firing the simevent to increase or decrease the nav or com values. I read that this is how they were designed.

I am currently pulling 8 data values while engaging all 5 encoders which are all part of the main loop, in addition to 12 buttons in a keypad matrix, and the respective encoder switches and the nav/gps toggle, and a 5 position rotary switch. I have no simevent functions mapped out to the buttons yet but pressing the led buttons lights up and turns off the switch led.

Some arduino code considerations:

  1. I realized the encoders will be the point of failure with regards to how the user perceives the speed of the effects so i decided to pull the encoder function in the foreground. Basically, once the encoder is turned and detected in the loop, it calls a function that remains open basically stalling the rest of the loop. There will be no display updates until the function returns. The function will keep resetting an internal timer while the encoder is being turned, listening ONLY to this particular encoder and hence able to fire simevents. The in game change is visible right away, but the button box display will only update after the timer expires. ( I don’t think any user will attempt to turn two encoders simultenously). I plan on using a timer interrupt to refresh the LED panels but I don’t know the effect on encoder responsiveness yet.

UPDATE: While the method above works reliably once you have detected the encoder and launched the function, encoder detection in the main loop is still not reliable. It seems the limit is 4 display updates per loop. Any more and encoder detection could be missed. Plus need to get used to letting the timer expire before doing anything more. A simple check for odd or even counter values and alternating between 2 sets of 4 displays to update seem to be working better. Doing one display update every loop is even better.

Somehow I broke SimVoice, but I got it fixed again.

  1. The simrequest function will only update the LED panels if it detects a change in the value from the game. This gets rid of unecessary refreshes to the LED panels.

I had to modify Form1 to put in a serial data opening id byte along with the data bytes and a closing data byte. So serial port transfers per simrequest is now up to 4 bytes. This was necessary because without this, using any buttons messed up the sequence of the serial data so that one led panel was receiving data for another led panel.

Next step:

  1. Try a timer interrupt for LED panel updates so they will update while an encoder is in the foreground.

UPDATE: No Good. I think LED segment display updates take too long. The timers are so far good only for blinking leds.
2. Map out simevent functions to buttons and see how it performs.

It’s rather fun. I have created derived classes of most libraries that I am using in order to add some specific features. I am using lambda functions and mapping them out to function pointers in the class objects so there is an automatic mapping of button/encoder to function when the button/encoder object is created. The digit displays also have a function pointer to a lambda function for the simrequest function that they need to call to update.

I also derived a class from TM1637_6D which displays digits one offset to the Right for the digit displays on the left side of the button box. This is because these are actually 6 digit 7 segment displays where on the Left side of the button box, the first segment is covered. On the right side, the 6th segment is covered. So they effectively function as a pair of 5 digit 7 segment display. This is to allow them to fit in the Propwash face plates.

I did mention I come across an excellent button debouncing strategy in software. And I derived a class from MD_REncoder which uses a state machine to debounce the encoders. Simply checkng DT and CLK yields the wrong turn direction every now and then.

I hope I don’t mess anything up going forward.

I just realized I can receive data even without a capacitor with an arduino mega 2560.

Chris

1 Like

Not sure what you are implying/referring to? Why should I do that?

You are doing GREAT! Did I understand correctly you are pulling 8 values now? And you are using different hardware for sending and receiving? No wonder it performs well. :+1:

The miniAVX pulls a bit more now (28) and that’s were the troubles start. It seems some values have more “performance” then others. E.g. the QNH is really quick to respond to user input, were as the transponder lags in such a way its nearly unusable.

I am in contact with BitsAndDroids to improve the app further. He has a plan to improve performance overall and also make it possible to create switchable receive sets. That would help greatly in performance. For example, on the SPD-ALT page, I would only have to receive 5 values (IAS, GS, MSL, AGL, BARO) instead of all of them.

I am using a refresh function for the LEDs. Not sure if you have something similar? Currently REDRAW_INTERVAL is at 100ms, giving 10fps in theory. Might go to 50ms for 20fps. Not sure if it would help or hinder performance tough …

void redrawLED() {
  if ((millis() - lastRedraw) >= REDRAW_INTERVAL) {
    if (drawLED != NULL) {
      drawLED();
      lastRedraw = millis();
    }
  }
}

That was a response to sehnsedahamses regarding usage in VR.

I like your led redraw function. I was previously updating one display per loop. This is much better. I am putting all the led status displays on it also.

I am only using one comm port. Decided against the complexity of an i2c pair. But I kept the i2c pins free just in case.

I thought I wouldn’t need any more than 50 Simvars or Simevents. Currently I have about 60 SimEvents and 40 sim vars.

I still think it was a good idea to reduce the size of serialport transfers and make them all the same size. That may be where the lag is coming from if you percieve a difference between different connector retrieve functions. If all the connector functions transferred the same size data, they should behave the same.

Although not implemented yet fully, my idea to solve the issue of latency would be to have the app keep stats on which simvars are being used and to unsubscribe those that have not been requested by the arduino after a certain amount of time and to resubscribe them if there are a minimum number of requests initiated. That way, the arduino controls the app settings. However this only solves the latency between simconnect and the app.

I am building the Cessna 152 Autopilot functionality. Only have ARM and BARO left . Need to put in a way to adjust ADF and put functions in the nav/gps and rotary switch.

You can go as complex as you want when you are the one coding. I have one button which I configured to display both nav radios on the top 4 panels. Then press the button again and it changes to the OBS1 and OBS2 readings which I can change with the encoder.

The LED lights in the switches are in the display loop constantly checking if the game changed the status of AP, HDG, NAV, APR and turn on/off accordingly.

If I engage ALT, then it toggles VS and it displays altitude lock and vertical speed set in the AP both of which I can change with an encoder and with two buttons ( cause on the actual AP, there is an up and down button for changing values for vs).

I implemented the nav and com radio swaps using the encoder switch.

On the last row, I can modify the transponder value by using the encoder at the same level which if the switch is pressed will cycle throughout the 4 digits which can be modified.

Maybe by the weekend I can fly a plane. Perhaps I will have SimVoice tell me when I am at '1 20, 15, 5 feet retard ’ before landing. Oh and I have all three Microsoft Voices available for selection: David, Hazel and Zira.

Actually did a short test flight. Awesome!. Things were fast. Only thing i did not like is the Propwash encoder requiring two detents to effect.

I will have to see if Form1 is going to run stable for a few hours.
Just for kicks, below 2000 feet, simvoice is warning that I might crash if i don’t climb up.

Chris

Yes, that is what I thought. Using Strings when a long would suffice sure hinders smooth transfer.

But BitsAndDroids is evolving in that direction.

Also, it would help if the app only pulls the variables that are displayed. That is also in development.

Got hung up on the arduino toggle code. Got it done though. Toggles and latching switches have the advantage of their visible state indicating the state they track in the game. You don’t need any LEDS to indicate status. Just look at the switch. However, you have to constantly check the state or variable they are controlling and not allow the game to change it. Otherwise, the state of the toggle “up or down” or switch “latched or unlatched” becomes meaningless because it could indicate either of its dual state in the game. Code that detects toggle or latching switch state change from OFF<>ON is not necessary therefore since you have to have code that checks whether it’s state is continuously ON or OFF.

Just some musings.
Chris

I found some really great optimizations. My box led segment displays are now near instantaneous when using the encoder. Water Flowing! According to the app, I am pulling 22 values from Simconnect.

  1. #define REDRAW_INTERVAL 50
  2. Setup a display priority for each encoder. Basically, each encoder is attached to a specific LED segment display. When the encoder is used, that LED display is preferentially updated for that redrawLED instance.
  3. Put the encoder detection twice in the main loop function.

Chris

Released!

1 Like

Hey, that sounds interesting about preferring Led displays. I only have two but might try that out.

Found out it was generating a serialport backlog over time on the PC side. Got it fixed in version 0.62 so SimEvent processing should stay responsive.

Chris