Skip to content
View in the app

A better way to browse. Learn more.

The AVSIM Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

SIOC and how it works

Featured Replies

I am not an expert on this. But I thought it might be useful to give some very very basic examples on how to get started with SIOC. Questions and comments are of course welcome, I might very well overlook something or perhaps this is just unclear and hard to understand. So ask. Lets try to help each other with this :)SIOC Tutorial

Very simple SIOC tutorial. Stuff between 3 dashes ("---") are example code.Everything works via *variables*.A variable can be:* a FSUIPC offset (1):  ---  Var 2, Link FSUIPC_OUT, Offset $0BE8, Length 4 // 0/16383   ---* a IOCards switch (2):  ---  Var 3, Link IOCARD_SW, Input 89 // Landing gear switch   ---* a IOCards LED output (3)  ---  Var 4, Link IOCARD_OUT, Output 15 // "Gear in transit" LED   ---There can be more (stepper, ac motors etc, but they are outside the scope of this simple tutorial.What was the hardest thing for me to understand at first, was the fact that this sioc code is never "run" from beginningto the end. Instead, it consists of several small snippets:---  Var 3, Link IOCARD_SW, Input 89 // Landing gear switch   {	** Hi! I'm a snippet of code! **  }---Basically what this means, is: We have a variable "V3" (yes, its silly to call them by number instead of a real name, but this is how it is now) - and there is a corresponding piece of code, enclosed in culy brackets after the variable. This is the very simplest SIOC program.Whenever the value of V3 changes, and it can happen when we toggle the switch that is connected to iocards input 89, the code inside the brackets is being run. Whatever you put in a line after two slashes ("// blah blah") is regarded as "comment" and is ignored by SIOC - you should put some comments there as to what does what etc.. to make it easier to remember what the code does.For most things, it can be as simple as this:---// ** Pitot Heat ** Var 2, Link FSUIPC_OUT, Offset $029c, Length 1 // Pitot Heat Var 3, Link IOCARD_SW, Input 88 // Pitot heat switch {   V2 = V3 } ---A switch variable can be zero (switch is off) or 1 (switch is on) - and the FSUIPC pitot heat offset $029c, according to the "fsuipc for programmers" reference doc also varies from 0 (pitot heat off) to 1 (pitot heat on). Thus our goal can be accomplished very easily: Offset should have the same value as the switch. In other words: V2 = V3.This is just a very simple example, but it shows the basic idea. More complex things can naturally be created.---Var 7, Link IOCARD_OUT, Output 17 // GREEN led for RIGHT main landing gear// RIGHT landing gear position, when 0, gear is up, when 16383, gear is down Var 8, Link FSUIPC_IN, Offset $0BF0, Length 4 {   IF V8 = 16383   { 	V7 = 1   }   ELSE   { 	V7 = 0   } } ---So.. if you have done any programming, IF .. ELSE is familiar to you. Basically, we check whether variable 8 is 16383 (which, according to the document, means "right main landing gear is down"). Again, ourcode is run *when the fsuipc offset value changes*, ie, when the gear moves, in this case.We also have an iocards led (output) defined as variable 7, and V8 is the FSUIPC offset we monitor (FSUIPC IN). Whenever V8 is 16383 it means gear is down and we can light up the green led (V7 = 1). In every other case (ELSE) gear is not down and locked, thus we must turn the green led OFF (V7 = 0)Hopefully this clears up the very basic syntax and structure of how SIOC works. I can add more later, and if you have questions, lets try to answer them. Of course remember that in the iocards forum, on www.opencockpits.com there is a LOT of SIOC example code in the SIOC forum.

//TuomasReferences:(1) - see www.schiratti.com/dowson.html and the FSUIPC SDK, it has a document called "FSUIPC for Programmers.doc" - it lists all the offsets you need and their lengths and what values they might get.(2,3) IOCARDS variables can be switches or leds, the number corresponds to the physical pin number of the switch. This can be figured out via CONTROLADOR.EXE, part of IOCards software.

  • Replies 70
  • Views 24.8k
  • Created
  • Last Reply

Top Posters In This Topic

Great , dear ToumasYour tutorial defintly puts me on trackAlready saved , printed and framedAny additions to that are most welcomeTnx a lot for your efforts

  • Author

Goody. So it was useful :)Another very nice function is CHANGEBIT / SETBIT etc.. This all is nicely found in the english help of SIOC too.

// *** Aircraft lights *** Var 18 Link FSUIPC_OUT, Offset $0D0C, Length 2 // FS-Light // this is a variable with a lot of *bits*, each corresponding to// one type of light in fs. Think "0011101010100110" and you get// the idea.// our beacon light switch is on pin 103 (my 2nd master card)Var 19, Link IOCARD_SW, Input 103 // Beacon lights is bit #1{   // we change bit 1 = V19 (1 or 0, depending on switch position)  V18 = CHANGEBIT 1 V19 } // this is a bit funny. On the excellent Dreamfleet Cessna 310, the // landing lights are coupled to the spoiler animation, since// they extend from the wings. Just turning the lights on// will just lighten up the asphalt under the wings :))// So to turn on landing lights, I want to both extend spoilers// and then turn on the light. The spoilers in this aircraft// of course do not have any effect on flight characteristics.// You naturally do not want to use this code in your B737 :)))Var 20, Link FSUIPC_OUT, Offset $0bd0, Length 4 // SPOILER, 0 - 16383 Var 21, Link IOCARD_SW, Input 102 // landing lights switch{   // again we use the V18 defined before, since that offset takes  // care of all lights.. bit 2 is landing light.  V18 = CHANGEBIT 2 V21  // then we also extend the spoiler if landing light is on   // (1*16383 = 16383, if it is off, 0*16383 = 0)  V20 = V21 * 16383 } Var 22, Link IOCARD_SW, Input 101 // Taxi lights, bit 3 {   V18 = CHANGEBIT 3 V22 } Var 23, Link IOCARD_SW, Input 100 // LIGHT Navi {   V18 = CHANGEBIT 0 V23 // nav lights  // I also turn on panel lights since I dont have a separate panel   // lights switch..  V18 = CHANGEBIT 5 V23 } Var 24, Link IOCARD_SW, Input 99 // LIGHT Strobes {   V18 = CHANGEBIT 4 V24 }

Pretty much like that. It's not very hard really (I'm not a programmer really, far from that) - but it takes a bit of time to get used to. I personally rather write this like this:Var $FuelPump, Link FSUIPC_OUT, Offset $3125, Length 1Var $SWFuelPumpL, Link IOCARD_SW, Input 105 // Fuel Pump L{ $FuelPump = CHANGEBIT 0 $SWFuelPumpL}and I have a small script that changes $FuelPump to "52" for me. But Nico seems to be happy with an numbering scheme like one where switches are 100, 101, 103, leds are 200, 201, 202,... and so on. Helps to organize them in your mind. Whatever works for you is fine..//Tuomas

Thanks TuomasA lot of us need this sort of information.

>But Nico seems to be happy with an numbering scheme like>one where switches are 100, 101, 103, leds are 200, 201,>202,... and so on. Helps to organize them in your mind.>Whatever works for you is fine..Hi Tuomas,Good contributions to the community!Just for clarification: Ofcourse I'de like to get rid of variables numbers too. For the time being I use a numbering scheme in which the var numbers are related to the section in FSCONV where they are defined. For example the Electrical Information is defined in section 2.5 so these vars are in the range 2500-2599. On top of that I map the leds in the ..80 range, fsuipc output vars count from ..99 backwards, and so on. This way keeps me organised. You must know that I have a program of 5725 lines with 595 vars (and counting ;-) )But more imortant I use the option to give a Var a symbolic name. You have not touched that topic yet in your examples so here it is:Var 9110, name ColdAndDarkNow anywhere in my program where I want to refer to this state I usethe symbolic name, like thisIF &ColdAndDark (in stead of IF v9110 )Which is: 1. more readable 2. when you renumber the Vars you only have to do this at one place! 3. a language feature, so no extra tools needed (simplicity)For my symbolic names I use a prefix scheme. If I see the symbolic name FI_Electrical, I know that it is a Fsuipc Input variable. More on that in my LevelD767.txt file on my site (downloads, LevelD sioc sources)Cheers!Nicowww.nicokaan.nl1704.png

  • Author

>But more imortant I use the option to give a Var a symbolic>name. You have not touched that topic yet in your examples so>here it is:Yep. and I probably never will, since I wrote myself a small script in Perl (a scripting language) that does the job for me. But your symbolic variable example complements my part very nicely :)//Tuomas

>Yep. and I probably never will, since I wrote myself a small>script in Perl (a scripting language) that does the job for>me. But your symbolic variable example complements my part>very nicely :)I guess someday Manuel will relieve us from the var numbers. Building a compiler for a langauge with symbolic names is a little bit more difficult then one with absolute numbers. I guess that's the reason. Keep the language simple, so the compiler can be simple, and less prone to errors. It's a matter of time, I hope.Nicowww.nicokaan.nl1704.png

  • Author

Here's how I do my audio panel. It's based on the default Cessna's one, but probably should work the same on most planes in FS.http://www.tigert.com/aviation/vatsim/cock.../audiopanel.jpgAudio panel in FSUIPC is done using one "big" offset that has eight bits (00000000) - they are as follows:7 COM1 transmit 6 COM2 transmit 5 COM receive both 4 NAV1 sound 3 NAV2 sound 2 Marker sound 1 DME sound 0 ADF1 sound Now, when everything is OFF you have (00000000). In FS actually the COM1 vs COM2 switch seems to be more like a toggle, as one of them seems to be ON at all times. So if you have everything else OFF but your NAV1 switch is ON to listen to the VOR ident, your bits are like this: 00001000.

Here's the SIOC code. This again is done with one offset and lots of bits..// First we define our IOCards LEDs here, nothing special.// Just mapping each green led to a variable.Var 55, Link IOCARD_OUT, Output 25 // COM1 Audio Var 56, Link IOCARD_OUT, Output 24 // COM2 Audio Var 57, Link IOCARD_OUT, Output 23 // BOTH Audio Var 58, Link IOCARD_OUT, Output 22 // AUX Audio Var 59, Link IOCARD_OUT, Output 21 // NAV1 Audio Var 60, Link IOCARD_OUT, Output 20 // NAV2 Audio Var 61, Link IOCARD_OUT, Output 19 // MKR Audio Var 62, Link IOCARD_OUT, Output 18 // ADF Audio // This is the interesting part. We know that everything works via // events in SIOC. So the "meat" of the code is here. Whenever// something happens in the audio panel, we know the bits in this// FSUIPC offset change and we get an event. Our challenge is to // "split" this variable to separate variables for each item. //// Thus we do this big assignment of values. We test each bit and// set its value to our own variables.//// The trick here is to understand, that when "NAV1 sound" is // turned on in FSUIPC, our bit 4 turns from 0 to 1. Hence, we // get a chain of events here in the code: V59 also becomes 1.// Then SIOC looks whether we have defined code for variable 59 and// runs that. So remember this: whatever changes, creates an event // and causes code to be run. If that code in its turn changes // something else.. you get the idea. It's like a waterfall effect.// One thing to keep in mind is to try to be careful of circular// references: A changes B and B changes A creates an infinite// loop... :-)//// In our own case here though, the variables are just leds, thus// they light up accordingly, and we dont need to add any code to// them. We could do it of course if we wanted. Like to play a small// chime wav when a light turns on for example. Or one could// do the master warning sound alert this way, combined to the led // itself.// Anyway, back to the code:// We just map each bit to our own LED variables.Var 63, Link FSUIPC_IN, Offset $3122, Length 1 // Radio Audio Bits {   V55 = TESTBIT V63, 7 // COM1   V56 = TESTBIT V63, 6 // COM2   V57 = TESTBIT V63, 5 // BOTH   V59 = TESTBIT V63, 4 // NAV1   V60 = TESTBIT V63, 3 // NAV2   V61 = TESTBIT V63, 2 // MRKR   V62 = TESTBIT V63, 0 // ADF } // The above is all we need to do to make the leds work! :)http://www.tigert.com/aviation/vatsim/cockpit-stuff/audiopanel4.jpg// Then the pushbuttons.. we use FSUIPC_OUT since we want to // write values here.Var 64, Link FSUIPC_OUT, Offset $3122, Length 1 // Radio Audio Bytes // Then we define our inputs (pushbuttons) - pin 37 in the master// card is soldered to "COM1" button.. This is a "type P" which means// it is a pushbutton, not a toggle switch. So it is "0" most of the time and becomes "1" when one pushes the button.Var 65, Link IOCARD_SW, Input 37, Type P // COM1 Audio {   // So we can assume that whenever I get an event on this switch,  // it is "1", and we can just set the bit 7 to "1" here.  V64 = SETBIT 7   // Since this is COM1 audio, and FS's audio panel is a bit   // strange, we must clear COM2 audio bit here. The FS audio panel  // seems to have more like a flip-flop switch between COM1 and COM2  V64 = CLEARBIT 6 } Var 66, Link IOCARD_SW, Input 38, Type P // COM2 Audio {   V64 = SETBIT 6   // ditto, clear COM1 bit here..  V64 = CLEARBIT 7 } Var 67, Link IOCARD_SW, Input 39, Type P // BOTH Audio {   V64 = CHANGEBIT 5 V67 } Var 69, Link IOCARD_SW, Input 41, Type P // NAV1 Audio {   V64 = CHANGEBIT 4 V69 } Var 70, Link IOCARD_SW, Input 42, Type P // NAV2 Audio {   V64 = CHANGEBIT 3 V70 } Var 71, Link IOCARD_SW, Input 43, Type P // MKR Audio {   V64 = CHANGEBIT 2 V71 } Var 72, Link IOCARD_SW, Input 44, Type P // ADF Audio {   V64 = CHANGEBIT 0 V72 }

That's it for my audio panel :-)//Tuomas

  • Author

>I guess someday Manuel will relieve us from the var numbers.>Building a compiler for a langauge with symbolic names is a>little bit more difficult then one with absolute numbers. I>guess that's the reason. Keep the language simple, so the>compiler can be simple, and less prone to errors. It's a>matter of time, I hope.Yeah. I think its also because the IOCP protocol is kept very simple by using numbers.But I mean, I do this variable name -> number mapping with my script, SIOC could have a similar preprocessor. It could even make a "mapping file" for variable -> number that IOCPConsole could then load, so you would never see the numbers as a user, ever. And SIOC would crunch them happily behind the scenes. :)//Tuomas

  • Author

This was fairly interesting. Basically, an altitude encoding transponder usually displays the encoded altitude also in the unit display itself. I have 3 digits of 7-segments for this. The trick is, it always encodes it in "flight levels", with a pressure setting of QNE (1013mbar / 29,92 InHg). The trick here is to figure out the difference between current QNH / altimeter value and the standard setting, and compensate the indicated altitude with that. So, a nice weird piece of code that demonstrates a bit of what SIOC can do. http://tigert.1g.fi/avsim/xpdr-fl-display.jpg

// This is the 7-segment output, 3 digits. Here we display the final// value..Var 73, Link IOCARD_DISPLAY, Digit 4, Numbers 3 // altitude // This is the current altimeter pressure setting.Var 74, Link FSUIPC_IN, Offset $0ec6, Length 2 // QNH * 16 // This is our real altitude, in meters. Whenever this changes,// the value displayed in the transponder needs to change too. // Thus the code within brackets does it for us..Var 75, Link FSUIPC_IN, Offset $6020, Length 8 {  // the fsuipc value, millibars * 16, so we need to divide by 16.  // "L0" is a local "handy" variable we can use that only exists   // inside this code block. Useful for assigning temporary values..  L0 = V74 / 16   // We need to know how many millibars the current altimeter setting  // differs from the standard (1013 mbar). So we subtract the   // standard value from the current setting. If the result is  // negative, the pressure is below 1013, and vice versa.  L0 = L0 - 1013  // One millibar difference equals to 27 feet in altitude.  // The PPL theory lessons were not in vain! :)  // This converts the pressure difference into difference-in-feet   // After this, L0 contains the value we need to compensate our   // "real" altimeter value with, to get it show whatever the   // altimeter would show if we set it to 1013 mbar  L0 = L0 * 27  // L1 is another local "temp" variable - we can have L0, L1 and L2.  // We convert our altitude in meters to our current altitude in  // feet and assign it to L1..  L1 = V75 * 3.2808399  // we subtract our "offset" (L0) from the altitude,   L1 = L1 - L0  // The transponder display shows "flight levels" which means   // we divide the result by 100 (8000ft becomes Flight level 80)  L1 = L1 / 100  // "Trunc" just cuts off the part after the decimal point, which   // we do not need.  V73 = TRUNC L1 }

So this was some really weird stuff, eh? The above *seems* to work, it could well contain errors, as I am far from a programming expert. It might not even work right. But it probably helps you to understand how sioc works, by example.Questions are welcome of course, the idea of this thread is to explain how this stuff works.//Tuomas

Toumas, you have a talant to explain complicated things simple wayTnx again for those two additional great tutorialsCould you explain timer usage and purpose ,often used in SIOS?Regards

  • Author

>Toumas, you have a talant to explain complicated things>simple wayThanks! ;-)>Tnx again for those two additional great tutorials>Could you explain timer usage and purpose ,often used in>SIOS?I don't understand it yet myself either :-)But once I do, I'll try! //Tuomas

Hi guys,Here's some explanation about the TIMER construct (a very powerful feature of SIOC).Have a look at the following two statements: V1 = 0 // 0 = begin value V1 = TIMER 10, 1, 30 // 10 = end value // 1 = increment // 30 = interval (*10ms)Note the statement V1 = TIMER 10, 1, 30 is executed 10 times, due to the begin value of V1. Each time V1 gets a new (higher) value.So: V1 will get values from 0 to 10 in steps of 1. Between these steps the program will pause for 30*10ms = 0.3 seconds.Of course you can also count down. You then need a negative increment and a higher begin value then the end value.Here's a counting down example: a led that will be on/off (blink) in periods of half a second for a duration of 5 seconds.Var 0, value 0{ &O_Led = 0 &BlinkLed = 10 // Begin value &BlinkLed = TIMER 0, -1, 50 }Var 1, name BlinkLed{ L0 = MOD &BlinkLed, 2 // a so called Modulo 2 test: if even result is 0, // if odd result is 1 IF L0 = 0 { &O_Led = 0 } ELSE { &O_Led = 1 }}Var 2, name O_Led, Link IOCARD_OUT, Output 77// Have Fun! :-)Nicowww.nicokaan.nl1704.png

  • Author

OK.How would you do a led that blinks *while* some condition is true. Like, blink "gear in transit" led until the gear is up or down and locked? Just put the timer to be long enough (100 times or such) and then just assign "BlinkLed = 0" when it is no longer needed?//Tuomas

>Just put the timer to be long enough (100 times or such) and>then just assign "BlinkLed = 0" when it is no longer needed?Almost TRUE, you should set BlinkLed to a value close to the end value (not the end value itself) so the timer will end normally (quickly), a value of 1 will do I guess.Otherwise the timer might fall through zero, so to speak. It would decrement 0, end up with -1 and not detect the 0 end value till it has counted through 32 bit integer, which may take quite a while with increments of half a seond ... ;-)Nicowww.nicokaan.nl1704.png

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.