• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

FSX Stop the timer!

Messages
97
Country
sweden
Howdy again,

I have a new little problem to solve involving a oxygen gauge and I have been trying various code but to no avail.
I have a timer that should start when the airplane leaves the ground and stop when the airplane is on the ground. When the time have expired the timer should stop and so should the needle movement (oxygen depleted). I do not want the needle to start over again at 100 like it is doing now. Here is the code without the (A:SIM ON GROUND, bool) code or anything else....just the timer and the needle.
Code:
<Element>
        <Position X="0.000" Y="0.000"/>
        <Image Name="needle.bmp" PointsTo="North">
            <Axis X="0.000" Y="0.000"/>
        </Image>
        <Shift>
           <Value Minimum="0" Maximum="100">(P:Local time,minutes) flr 100 %</Value>
                                <FailureTable id="FailureTable">
                        <Failure id="Failure">
                        <Fail_Key>SYSTEM_ELECTRICAL_PANEL</Fail_Key>
                        <Fail_Action>Zero</Fail_Action>
                        </Failure>
                    </FailureTable>
            <Nonlinearity>
                <Item Value="100" X="80" Y="662"/>
                <Item Value="50" X="214" Y="662"/>
                <Item Value="0" X="332" Y="662"/>
            </Nonlinearity>
        </Shift>
    </Element>

How do I prevent the needle from starting at 0 again?

Any suggestions?

Regards,
John
 
Messages
1,564
Country
thailand
John,

Right, the expression (P:Local time, minutes) flr 100 % repetitively counts upward to 99 and then starts over at 00. It's similar to the expression you started with in your previous post, and again, I don't think it is a good approach for an elapsed time counter.

However, if you still want to, you can 'stop' your needle movement from going back to zero by using something like:

Code:
(P:Local time, minutes) flr 100 % s0
99 == if{ 1 (>L:TimerReached99, bool) }
(L:TimerReached99, bool) 0 == if{ l0 (>L:OxygenTimer, enum) } els{ 99 (>L:OxygenTimer, enum) }
  • Line 1 stores the value of your expression in memory register 0
  • Line 2 checks if that value is equal to 99 and if it is, stores "1" into (L:TimerReached99, bool)
  • Line 3 checks the value of (L:TimerReached99, bool). If it is still "0", then the value of your expression is stored into (L:OxygenTimer, enum). But if it is not zero, then 99 is stored into (L:OxygenTimer, enum).
and your needle movement is controlled by (L:OxygenTimer, enum).

A big disadvantage of this timer is that it will only infrequently start with the value 00. Depending on the Local Time, it could even start at 99 in which case your oxygen gauge needle would never move.

Additionally, you don't need Minimum="0" Maximum="100" because your expression will always return a value between 0 and 99 (inclusive).

Bob
 
Messages
58
Country
netherlands
I use:

18x60x10=10800 tics in 10 minutes (time necessary to descend below 10000ft)
300 pass a 3l O2/min=900
So store 900x10800=9720000 in the oxygen cylinders (just a number!)
Then when cabinalt exceeds say 10000ft the O2 flow starts:
Code:
(L:oxygen cylinders,number) 900 - 0 max (>L:oxygen cylinders,number)
The flow stops auto at 10000 ft or when cylinders are empty, followed by "blackout".....
Simplified you can use 100 and 0,01, so the formula would be:
100 in cylinders before take off ( some "groundservice")
flow:
Code:
(L:oxygen cylinders,number) 0.01 - 0 max (>L:oxygen cylinders,number)
That makes it easier to shift or rotate a needle in a gauge.
Hope it helps,

jan
 
Messages
97
Country
sweden
John,

Right, the expression (P:Local time, minutes) flr 100 % repetitively counts upward to 99 and then starts over at 00. It's similar to the expression you started with in your previous post, and again, I don't think it is a good approach for an elapsed time counter.

However, if you still want to, you can 'stop' your needle movement from going back to zero by using something like:

Code:
(P:Local time, minutes) flr 100 % s0
99 == if{ 1 (>L:TimerReached99, bool) }
(L:TimerReached99, bool) 0 == if{ l0 (>L:OxygenTimer, enum) } els{ 99 (>L:OxygenTimer, enum) }
  • Line 1 stores the value of your expression in memory register 0
  • Line 2 checks if that value is equal to 99 and if it is, stores "1" into (L:TimerReached99, bool)
  • Line 3 checks the value of (L:TimerReached99, bool). If it is still "0", then the value of your expression is stored into (L:OxygenTimer, enum). But if it is not zero, then 99 is stored into (L:OxygenTimer, enum).
and your needle movement is controlled by (L:OxygenTimer, enum).

A big disadvantage of this timer is that it will only infrequently start with the value 00. Depending on the Local Time, it could even start at 99 in which case your oxygen gauge needle would never move.

Additionally, you don't need Minimum="0" Maximum="100" because your expression will always return a value between 0 and 99 (inclusive).

Bob


Hello again Bob,

Do you suggest that I use Absolute time instead of Local time? Can I just change the (P:Local time,minutes) to Absolute time and that will work or do I have to re-work the code entirely?

John
 
Messages
97
Country
sweden
I use:

18x60x10=10800 tics in 10 minutes (time necessary to descend below 10000ft)
300 pass a 3l O2/min=900
So store 900x10800=9720000 in the oxygen cylinders (just a number!)
Then when cabinalt exceeds say 10000ft the O2 flow starts:
Code:
(L:oxygen cylinders,number) 900 - 0 max (>L:oxygen cylinders,number)
The flow stops auto at 10000 ft or when cylinders are empty, followed by "blackout".....
Simplified you can use 100 and 0,01, so the formula would be:
100 in cylinders before take off ( some "groundservice")
flow:
Code:
(L:oxygen cylinders,number) 0.01 - 0 max (>L:oxygen cylinders,number)
That makes it easier to shift or rotate a needle in a gauge.
Hope it helps,

jan

Thank you Jan,

Good information to know. I will test this in a gauge as well.

John
 
Messages
1,564
Country
thailand
Hello again Bob,

Do you suggest that I use Absolute time instead of Local time? Can I just change the (P:Local time,minutes) to Absolute time and that will work or do I have to re-work the code entirely?

John

Absolute Time vs Local Time isn't the issue. An elapsed time calculation needs to know when it starts, then compares the current time to the start time to measure elapsed time (subtracts start time from current time). For your oxygen bottle depletion, you could follow similar logic suggested in your I dont want flashing text thread.

Another common elapsed time approach is to count gauge update cycles. The default gauge update rate is 18 update cycles per second, so a half second interval uses 9 update cycles. And a 10 minute elapsed time would be 10 x 60 x 18 = 10800 cycles. This is the method Jan uses, above.

Bob
 
Messages
1,468
Country
italy
One thing to remember regarding oxygen depletion is that if the system has been activated (i.e. either cannisters activated or gaseous oxygen) it is a no go situation for the pilots. So from the realism point of view it is more realistic to allow the oxygen system to reset to 100% once back on the ground.
vololiberista
PS Have you also modelled gas masks and hypoxia?
 
Messages
58
Country
netherlands
I have a groundservice routine to check all gases and fluids, oil, hydraulics, oxygen, fireextinguishers etc..
When one of them is at or below a "no go" level a refill will take place from a service panel.
Of course you can automate that.
Hypoxia will give tunnelvision and finally blackout.
Just a matter of rectangles with diminishing transparancy, which show up depending the O2 levels.
And yes,
Code:
(L:oxygen masks,bool)
will restore vision to normal....
 
Messages
1,468
Country
italy
I have a black 'hypoxia' screen which activates if you don't don your mask in time!! It clears at about FL150 assuming you had time to put the a/c into a dive. Hopefully one comes out of the hypoxia without the nose pointing straight at a mountain!!

Here's a snippet of my oxygen procedures. The VC10 has gaseous oxygen plus a cockpit/cabin split supply system all controlled by a manual panel. When the mask is donned there is a 'heavy breathing' wav file

Code:
<!-- Hypoxia settings-->
   <Element>
      <Select>
         <Value>(L:Cabin_Alt_Ind, number) 27000 &gt; (L:Cabin_Alt_Ind, number) 30000 &lt; and (L:Oxy_Charged,bool) 1 == and
(L:oxygen mask not pulled,number) 0 == and
if{ 1 (>L:emergency,bool) (P:local time,seconds) 180 + (>L:oxygen mask not pulled,number) }</Value>
      </Select>
   </Element>

   <Element>
      <Select>
         <Value>(L:Cabin_Alt_Ind, number) 30000 &gt; (L:Cabin_Alt_Ind, number) 35000 &lt; and (L:Oxy_Charged,bool) 1 == and
(L:oxygen mask not pulled,number) 0 == and
if{ 1 (>L:emergency,bool) (P:local time,seconds) 90 + (>L:oxygen mask not pulled,number) }</Value>
      </Select>
   </Element>

   <Element>
      <Select>
         <Value>(L:Cabin_Alt_Ind, number) 35000 &gt; (L:Cabin_Alt_Ind, number) 40000 &lt; and (L:Oxy_Charged,bool) 1 == and
(L:oxygen mask not pulled,number) 0 == and
if{ 1 (>L:emergency,bool) (P:local time,seconds) 30 + (>L:oxygen mask not pulled,number) }</Value>
      </Select>
   </Element>

   <Element>
      <Select>
         <Value>(L:Cabin_Alt_Ind, number) 40000 &gt; (L:Oxy_Charged,bool) 1 == and (L:oxygen mask not pulled,number) 0 == and
if{ 1 (>L:emergency,bool) (P:local time,seconds) 12 + (>L:oxygen mask not pulled,number) }</Value>
      </Select>
   </Element>


<!-- Oxygen Mask not Pulled in time -->
   <Element>
      <Select>
         <Value>(L:blackout,number) 0 == (L:oxygen mask not pulled,number) 0 &gt; and (L:Don_Mask,number) 0 == and (L:emergency,bool) 1 == and
if{ (L:oxygen mask not pulled,number) (P:local time, seconds) &gt;
if{ 280 (>K:PANEL_ID_OPEN) } els{ 1 (>L:blackout,number) 11025 (>K:PANEL_ID_OPEN) 1 (&gt;K:SOUND_OFF) } }</Value>
      </Select>
   </Element>


<!-- Hypoxia recovery-->
   <Element>
      <Select>
         <Value>(L:blackout,number) 1 == (L:emergency,bool) 1 == and (L:Cabin_Alt_Ind, number) 15000 &lt; and
if{ 0 (>L:blackout,number) 0 (>L:emergency,bool) 1 (>K:SOUND_ON) 11025 (>K:PANEL_ID_CLOSE) }</Value>
      </Select>
   </Element>

vololiberista
 
Last edited:
Messages
1,468
Country
italy
I like the heavy breathing!
Also the sound of silence.....
I thought the heavy breathing was a good way of simulating confirmation of oxygen flow to the mask itself.
I did think of going to the extreme and looping a nursery rhyme as hypoxia effects one in strange ways but I plumped for the 'simpler' solution!
 
Messages
97
Country
sweden
:( These timers are killing me.....sigh....what am I doing wrong? The needle is not moving.

Code:
<Update>
<Script>
(P:local time,seconds) flr 100 % (L:OxygenTimer, enum) > (L:Oxygen Select,number) 1 > and if{ 10 (>L:OxygenTimer, enum) ++ }
</Script>
</Update>
 
    <Element>
        <Position X="0.000" Y="0.000"/>
        <Image Name="Oxygenneedle.bmp" PointsTo="North">
            <Axis X="0.000" Y="0.000"/>
        </Image>
        <Shift>
            <Value>(L:Oxygen Select,number) 1 > if{ (P:local time,seconds) flr 100 % s0 99 == if{ 1 (>L:TimerReached99,bool) } (L:TimerReached99,bool) 0 ==
        if{ l0 (>L:OxygenTimer, enum) } els{ 99 (>L:OxygenTimer, enum) } }</Value>
                                <FailureTable id="FailureTable">
                        <Failure id="Failure">
                        <Fail_Key>SYSTEM_ELECTRICAL_PANEL</Fail_Key>
                        <Fail_Action>Zero</Fail_Action>
                        </Failure>
                    </FailureTable>
            <Nonlinearity>
                <Item Value="0" X="329" Y="662"/>
                <Item Value="50" X="214" Y="662"/>
                <Item Value="100" X="80" Y="662"/>
            </Nonlinearity>
        </Shift>
    </Element>
Code:
<Element id="Oxygen Knob">
            <FloatPosition>150.000,200.000</FloatPosition>
            <Select id="Select">
                <Expression id="Expression">
                    <Minimum>0.000</Minimum>
                    <Maximum>3.000</Maximum>
                    <Script>(L:Oxygen Select,number)</Script>
                </Expression>
                <Case id="Case">
                    <ExpressionResult>0.000</ExpressionResult>
                    <Image id="Image" Name="Oxygenoff.bmp">
                        <Transparent>True</Transparent>
                    </Image>
                </Case>
                <Case id="Case">
                    <ExpressionResult>1.000</ExpressionResult>
                    <Image id="Image" Name="Oxygenreset.bmp">
                        <Transparent>True</Transparent>
                    </Image>
                </Case>
                <Case id="Case">
                    <ExpressionResult>2.000</ExpressionResult>
                    <Image id="Image" Name="Oxygennormal.bmp">
                        <Transparent>True</Transparent>
                    </Image>
                </Case>
        <Case id="Case">
                    <ExpressionResult>3.000</ExpressionResult>
                    <Image id="Image" Name="Oxygenoverride.bmp">
                        <Transparent>True</Transparent>
                    </Image>
                </Case>
            </Select>        
        </Element>
 
 
<MouseArea id="Oxygen Knob">
                <FloatPosition>50.000,200.000</FloatPosition>
                <Size>302,135</Size>
                <MouseArea id="Oxygen INC">
                    <FloatPosition>152.000,0.000</FloatPosition>
                    <Size>150,135</Size>
                    <CursorType>DownArrow</CursorType>
                    <MouseClick id="MouseClick">
                        <Script>(L:Oxygen Select, number) ++ 3 min (>L:Oxygen Select, number) (L:Oxygen Select, number) 1 > if{ (P:local time,seconds) flr 100 % (>L:OxygenTimer, enum) }
                        </Script>
                        <ClickType>LeftSingle</ClickType>
                    </MouseClick>
                </MouseArea>
                <MouseArea id="Oxygen DEC">
                    <FloatPosition>0.000,0.000</FloatPosition>
                    <Size>150,135</Size>
                    <CursorType>UpArrow</CursorType>
                    <MouseClick id="MouseClick">
                        <Script>(L:Oxygen Select, number) -- 0 max (>L:Oxygen Select, number) (L:Oxygen Select, number) 0 ==
                                  if{ 0 (>L:OxygenTimer, number) }</Script>
                        <ClickType>LeftSingle</ClickType>
                    </MouseClick>
                </MouseArea>
</MouseArea>

Thanks for your additional comments.
- In answer to vololiberista's question, "PS Have you also modelled gas masks and hypoxia?"
- I am working on it.

I have a working pressurization system and a cabin annunciator alert if the cabin altitude is above 10,000' thusfar.

The only thing stopping me now is the timer :scratchch

Regards,
John
 
Messages
1,564
Country
thailand
John,

Its hard to follow what you want to do. I'm sure it will be easier to help if you can explain more fully, and carefully - in words. It is helpful that you included your Mouse section, thank you, but still difficult to understand your goal.

Are you trying to count down on oxygen use starting when your Oxygen Select knob is clicked to "1"? And, do you intend for the needle to move for 99 minutes then stop moving?

You seem to really like using "flr 100 %" when you don't need to, you typed "10" instead of "l0" at one point above, and a few other XML errors.

So, the best place to start, I recommend, is for you to describe what it is you want to accomplish. You will get it right soon ... hang in there.

Cheers,

Bob
 
Messages
97
Country
sweden
John,

Its hard to follow what you want to do. I'm sure it will be easier to help if you can explain more fully, and carefully - in words. It is helpful that you included your Mouse section, thank you, but still difficult to understand your goal.

Are you trying to count down on oxygen use starting when your Oxygen Select knob is clicked to "1"? And, do you intend for the needle to move for 99 minutes then stop moving?

You seem to really like using "flr 100 %" when you don't need to, you typed "10" instead of "l0" at one point above, and a few other XML errors.

So, the best place to start, I recommend, is for you to describe what it is you want to accomplish. You will get it right soon ... hang in there.

Cheers,

Bob

I am trying to countdown on the oxygen use starting when the Oxygen select knob is, ">" greater than position, "1" and I intend for the needle to move for 9 hours then stop moving (that is the approx. actiontime of the airplane with full fuel tanks) When the oxygen select knob is in the, "0" position needle movement will stop. When the oxygen select knob is in the, "1" position and the airplane is on the ground the oxygen will be re-set to full oxygen tanks. The oxygen override (oxygen select knob in position, "3") is only used in emergency situations and is not relevant at the moment, but it will be changed later.
:)

John
 
Messages
1,564
Country
thailand
John,

The timer you want to use is completely analogous to the solution suggested for you in your I don't want flashing text! thread a few weeks ago. Please take another look at that one.

Add the following to the Mouse click event when the Oxygen Select Knob is clicked to the "1" position:

(P:ABSOLUTE TIME, hours) 9 + (>L:OxygenTime_9, hours)

The value used to move the needle of your oxygen gauge Element is:

(L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - 9 / 0 max

This number counts down from 1.000 when the Oxygen knob is clicked to the "1" position (and the bottles are full) to 0.000 after 9 hours. The 0 max will keep the value at 0.000 after the 9 hours has expired. If you want, you can add some statements to keep the value at 1.000 before the Oxygen Select Knob is turned to the "1" position.

9 hours, huh? That's sloooow needle movement. Who flies FS long enough to even notice that needle movement?

Bob
 
Last edited:
Messages
97
Country
sweden
John,

The timer you want to use is completely analogous to the solution suggested for you in your I don't want flashing text! thread a few weeks ago. Please take another look at that one.

When the Oxygen Select Knob is clicked to the "1" position, add the following in that Mouse click event:

(P:ABSOLUTE TIME, hours) 9 + (>L:OxygenTime_9, hours)

The value used to move the needle of your oxygen gauge Element is:

(L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - 9 / 0 max

This number counts down from 1.000 when the Oxygen knob is clicked to the "1" position (and the bottles are full) to 0.000 after 9 hours. The 0 max will keep the value at 0.000 after the 9 hours has expired. If you want, you can add some statements to keep the value at 1.000 before the Oxygen Select Knob is turned to the "1" position.

9 hours, huh? That's sloooow needle movement. Who flies FS long enough to even notice that needle movement?

Bob

:D I love to fly over the atlantic and across the US and I fly FS long enough to notice such things. :rotfl:

Thank you, I will try the code above...
John
 
Messages
97
Country
sweden
John,

The timer you want to use is completely analogous to the solution suggested for you in your I don't want flashing text! thread a few weeks ago. Please take another look at that one.

Add the following to the Mouse click event when the Oxygen Select Knob is clicked to the "1" position:

(P:ABSOLUTE TIME, hours) 9 + (>L:OxygenTime_9, hours)

The value used to move the needle of your oxygen gauge Element is:

(L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - 9 / 0 max

This number counts down from 1.000 when the Oxygen knob is clicked to the "1" position (and the bottles are full) to 0.000 after 9 hours. The 0 max will keep the value at 0.000 after the 9 hours has expired. If you want, you can add some statements to keep the value at 1.000 before the Oxygen Select Knob is turned to the "1" position.

9 hours, huh? That's sloooow needle movement. Who flies FS long enough to even notice that needle movement?

Bob

Do I need a UPDATE section like I did for the I don't want flashing text! or will the timer automatically start subtracting from (L:OxygenTime_9, hours) when I have assigned a value of 1.000 to (L:OxygenTime_9, hours) and the switch is turned?

John
 
Messages
97
Country
sweden
John,

The timer you want to use is completely analogous to the solution suggested for you in your I don't want flashing text! thread a few weeks ago. Please take another look at that one.

Add the following to the Mouse click event when the Oxygen Select Knob is clicked to the "1" position:

(P:ABSOLUTE TIME, hours) 9 + (>L:OxygenTime_9, hours)

The value used to move the needle of your oxygen gauge Element is:

(L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - 9 / 0 max

This number counts down from 1.000 when the Oxygen knob is clicked to the "1" position (and the bottles are full) to 0.000 after 9 hours. The 0 max will keep the value at 0.000 after the 9 hours has expired. If you want, you can add some statements to keep the value at 1.000 before the Oxygen Select Knob is turned to the "1" position.

9 hours, huh? That's sloooow needle movement. Who flies FS long enough to even notice that needle movement?

Bob

Do I need a UPDATE section like I did for the I don't want flashing text! or will the timer automatically start subtracting from (L:OxygenTime_9, hours) when I have assigned a value of 1.000 to (L:OxygenTime_9, hours) and the switch is turned?

John
 
Messages
1,564
Country
thailand
You won't need anything in Update for this timer because P:ABSOLUTE TIME is constantly running. Therefore, the elapsed time, (L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - is constantly updating, even though it appears only in the <Value> part of your gauge Element.

As a suggestion, if you do not already use it or something similar, consider using a logic debugging tool like Blackbox. You will be able to see the real time values of any L:Var, A:Var, etc. That can be of great assistance when you're trying to figure out if your XML script is doing what you want it to do.

Bob
 
Last edited:
Messages
1,564
Country
thailand
Do I need a UPDATE section like I did for the I don't want flashing text! or will the timer automatically start subtracting from (L:OxygenTime_9, hours) when I have assigned a value of 1.000 to (L:OxygenTime_9, hours) and the switch is turned?

John


That's not quite how it works. A value of 1 isn't assigned to (L:OxygenTime_9, hours). In the Mouse click section, a value of 9 hours in advance of the current ABSOLUTE TIME is assigned to (L:OxygenTime_9, hours), and that number never changes.

The <Value> expression: (L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - 9 / is a two step process.

First, the elapsed time since the Oxygen Select Knob was clicked to "1" position is computed. That part is a subtraction: (L:OxygenTime_9, hours) (P:ABSOLUTE TIME, hours) - .

Second, the elapsed time is divided by 9. This ratio reflects the fraction, or percentage, of time left in the 9 hour countdown. That's the number that should drive your gauge needle.

Bob
 
Last edited:
Top