Yes, I think so but I have no clues about how Mobiflight works internally.
Most of my code is written in SIOC, that is very powerful and fast and act as a perfect bridge between FSUIPC and MF.
Most of the variables connected to the switches and annunciators are custom datarefs handled by SIOC and only sent to MF in form of 1 and 0 values.
This makes it easy to add transform functions, because they handle only 0 and 1, while the “hard and dirty work” with FS offset is done by SIOC.
I have found that this combination is very effective and easy to implement and expand.
I have currently 2 Arduino Mega, one for MIP and one for overhead, and a Pokeys 56U for throttles (just because Mobiflight don’t want to include analog axis in its capabilities… !)
All the rest (MCP, EFIS, RADIOS) is from Opencockpits.
I had this stupid idea that i wanted two oled displays in my switchbox. These seem to be very very slow. Now i have to pay for this by writing most of the low-level code on my own.
Wow… they surely look great, and after all, technical challenges are one of the pleasures and pain of the most “hardcore” cockpit builders…
I realized that for me, even if I ever had the money to buy all ready to use, plug and play components, is much more fun to face and solve problems and get things working after studying, reading and testing different solutions, build myself parts and experiment new technologies in order to improve my cockpit.
…well, to be true, if someone proposed me a complete, full-motion, 180 degrees view simulator for free, I could take under consideration the possibility of having fun also with that…
I use Oi4FS from rksoftware that let me control all GA airplanes from my Opencockpits MCP, COMs, NAVs, ATC and ADF modules. Oi4FS is Plug and Play.
Thanks for letting me know. Also do I need to plug my Mega in a powered USB when I keep adding things to it?
Reading all the discussion between @Airmax514 and you about all the interfaces I am lost ha ha ,
I have no knowledge of all these things. If you don’t mind me telling briefly what do these stand for: Opencockpit, SIOC, Interrupts for encoders probably I too can start this way instead of other interfaces. I hope I am not trying to run without learning to walk here.
mostly Airmax514 was talking about all these fancy things. I am still in the more early stage like you:
That is my current project i am working on. 8 momentary push buttons are missing. It will mostly be the AP controls for small aircraft.
EDIT: yes powered USB is a good idea a Mega might draw some power.
Hi Oxbow wellcome to the headaches and exaltation/cold showers we are so happy to undergo with our great hobby! Probably you are kidding me, but I want to summarize some points anyway:
Opencockpits is a spanish company producing interesting and sometimes good priced parts for home cockpits, and SIOC is the language they developed to control their products, mostly using another program called FSUIPC that gets the flight data from the simulator and makes them available in an easy form.
If you want you can have a look at their site:
https://www.opencockpits.com/catalog/
Encoders are very interesting sort of rotative switches that can tell a program how many “steps” you have done rotating the knob in one direction or in the other, eg. for selecting the AP altitude.
I leave to others the diffcult task of explaining interrupts!
Thanks Voss1917, I’ve never heard about Oi4FS before, seems very interesting.
According to what the producer says in its site this utility works with the default planes of MSFS 2020 and should require no customization or complicated configuration.
Does it requires FSUIPC 7 to run ?
It seems to be able to control all of the OC modules, so MCP, EFIS, radios, and - eg. changing parameters on the EFIS selectors, it can make the MSFS displays to change accordingly.
Price is reasonable, so, considering the lack of updated support from OC up to now (at least AFAIK) seems to be a great help for people who have no idea (or will, or time) about writing their own SIOC code.
It requires SIOC in any case.
Very good! So you are displaying the autopilot parameters on the OLED displays ?
I have the OpenCockpits MCP but I would like a lot to use OLED for a multi-radio panel (currently I only own an OC NAV1 radio module) - the idea is to have a selector to switch between NAV1-2, COM1,2 ADF and transponder.
Sorry if I missed this if you said already, are you using Mobiflight or else ?
Yes i am using it for the autopilot settings but also for some the current hdg and altitude. Once i have this going (which i have right now) i will also build a nice radion panel. I am using homebrewed stuff. I tried mobiflight which is great, but it does not support the oleds and there was no way to customize things. At the moment i am more busy with figuring out how i would like the software to run.
Oh sorry, Oxbow i forgot to explain the interrupt thing. The rotary encoders really need the attention of the processor to check based on the signal, how you are turning the knob. There are two options: the main loop takes care of that and checks them in every iteration or the pins connected to the encoders are able to fire an interrupt which essentially says that the processor has to stop doing what he is doing and deal with the signal right away when it changes.
A few details more about interrupt, to give a more complete idea. When you want to monitor some event that you don’t know when it’s going to happen (for example, the pressure of a button), you have two ways: polling or interrpupt.
Polling is the easiest: you have a task that periodically checks what you need to monitor and repeats itself during the execution of the program.
So, for example, your program will do something like:
MonitorTask()
Task1()
Task2()
…
TaskN()
This works fine when what you monitor is long enough to be sure that you “get it” during the execution of a full cycle.
But now imagine that your event lasts 10ms and each of your tasks last 100ms. This is what you get:
Time = 0
MonitorTask() 100m
Task1() 200ms
Task2() 300ms <— your event happens here
Task3() 400ms
restart
So in this case you miss the event that you want to monitor and it’s like it never happened for your program.
So, with the rotary encoders, you have to monitor one or more lines to detect a lot of fast pulses, depending on how fast you rotate it.
Here is where interrupts help.
Interrupts are special funcionalities which -as the name suggest- interrupt the normal execution of the program and are executed by stopping the normal flow of tasks, executing a simple quick function that is specified for the interrupt, and then restoring the previous operations.
In this case, what the program is doing is not important, because a pulse from your encoder will take priority and be counted wherever the execution of the program is.
This looks very nice, but on the other hand it requires specific hardware, so depending on what is the purpose of the microcontroller, different devices can have different number of pins assigned to interrupt or entire modules dedicated to input capture designed for these kind of operations.
This should give a basic idea of what interrupts do and how they work.
That is correct but in many cases you simply check if something changed. That should not take more than a few ms
Tsk1() - check change (5ms)
if yes, perform YY (100ms)
Tsk2() - check change (5ms)
if yes, perform zz (100ms)
Tsk3() - check change (5ms)
if yes, perform gg (100ms)
.
.
.
In cases like this, you’re basically focusing on doing one thing, maybe two at the same time (changing the STD BY radio frequency of a radio), etc. so the other tasks in reality are not triggered. I do agree that interruptions are a much more efficient way but it also would mean that you need to finish the interruption code to do something else, because as it implies, the process is ‘interrupted’ and nothing else can be done…
I believe, unless you have 10+ encoders and other controls, the speed of the Mega should help do things.
Now, also think that you can simply send raw data to the PC and let a Ryzen 3700x or an i9 make the rest of the calculations and apply the events you need. I believe the power of the PC processor is a little better than of the microcontroller…
Happy Flying!!!
Sorry mate, i tried it. And it doesnt work very well without interrupts. I have four standard encoders with 20 steps per turn, each step generating 4 different signals. And from time to time if have to turn that heading bug quickly, this gets annoying. Sending things to the PC makes things worse, because you increase the load on the board with an extra task.
I have spend quite some time on this problem, because we all know interrupt pins on an arduino are precious. My solution at least for the Mega and my four encoders was to put 8 of the analog pins (which i do not need anyway) into onChange interrupt mode. They are not as nice as real interrupt pins, since they fire as a group and you do not know which pin fired the interrupt. Lazy solution: process every encoder once that event happens. However, the code is lightweighted and only updatsa global offset for each encoder and does not invoke fancy things like display updates or serial communication.
Indeed, I confirm, it can’t work. Especially with an encoder that works on edge detection.
It’s not a matter of how long what you have in the interrupt function takes to be done (good programming rule says, just set a flag and leave as quickly as possible, but that’s the ideal case, there nothing tragic in doing a few more things), it’s matter of how long it takes to do everything else.
Maybe we can share some ideas @NoPiggies… I have 2 dual concentric encoders with buttons and also a standard encoder with button sending signals to 3 LCD displays also connected to the Mega and from there to the PC.
The two in the upper part are controlling the NAV1 and COM1 radios and the lower one is to control the HDG and CRS bugs (I select which one with the encoder’s button)
It works really fine for me, no lags, no 10+ header bug jumps… they simply work…
Here are a couple of pics for reference…
Very interesting debate here!
My experience is sligthly different, as I said I use SIOC for most of the calculations and other potentially slow tasks, so Arduinos have just to deal with reading switches status and send output to leds.
They also control 2 stepper motors for the moment, and all is very smooth.
The encoders are all on the opencockpit side, but all controlled via SIOC.
My cockpit has currently 3 OC modules, 2 Arduino Mega, and 1 Pokeys 56U. controlling about 100 button/switches/encoders and 40 leds, plus 2 stepper, many 7 segs displays (on MCP and radios).
I don’t know if Mobiflight and/or SIOC use interrupts, but I presume so because otherwise encoders will not react so quickly and precisely to high speed rotation (as when I realize that I have to change 12.000 fts altitude because I passed the descent starting point and the airport is getting too near to descend properly!!!)
Sorry for the late reply. Thanks for this information.
Can you explain something to me:
Well, today I plugged in a Rotary encoder switch (3 pole 4 positions) as a flap(used a mechano set to make a flap handle ) did the coding (I am using HID Interface) and plugged the 4 pins to analog. It worked fine but then the other digital components did not function properly. I unplugged the rotary flap switch everything was normal. Are we not supposed to mix the analog and digital in one sketch ?
@Airmax514 Thanks for clarifying this. I am not kidding, I am learning a lot from these forums with @Airmax514, @NoPiggies and others. Yes it is a headache and there is immense satisfaction when you see your airplane being controlled by those encoders !!! Will keep posting as I advance slooooowly. Thanks
Regarding interrupts, you could have a list of scheduled events for the future, stored in time order. As local time moves on, and time matches, the next event in the scheduled list can be popped and processed to evaluate inputs.
That time ordered schedule list was at the heart of a logic simulator I developed back in the 80s. Outputs of logic gates were scheduled for the future based on their speed. For encoders after an interrupt you can schedule an event to check the encoder state in the future.