November 14, 2024, 10:58:55 AM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


Running two props off a Prop1 - TCT and MIB

Started by Spooky Dad, August 28, 2010, 11:54:14 AM

Previous topic - Next topic

Spooky Dad

I'm helping a friend of mine with programming his Prop 1 for two props, each with their own triggers, to be able to go off when either sensor is triggered.  We want either one to be able to be triggered even if somehow the other is not triggered by a guest.

The TCT is on a pressure mat and the MIB will be on a breakbeam.   The TCT is a simple cylinder that I want to go up, hold for 3 seconds,  and then reset.  The MIB is also a simple cylinder used to simulate randomly thrashing like the cellar door code.  No extras on the MIB, just the cylinder.

After either is triggered I wait both to set up a time out period for each prop (the TCT and MIB separately) to prevent them from being retriggered for 60 seconds.

Below is the code we came up with, but when we we simulated the normally closed on the inputs it didn't trigger for either.  Looking for help from the forum.

=========================================================================
'
'   File......Basic_TCT-MIB.BS1
'   Purpose..."Simple" Thrash MIB
'   Author....Spooky Dad
'   E-mail....karlen_alexander@dell.com
'   Started...08/28/2010
'   Updated...08/28/2010
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Connections:
'
'
' P6 -   TCT - Mat Switch
'
' P5 -   MIB - Breakbeam
'
' OUT1 - 12v TCT valve
'
' OUT0 - 24v MIB valve


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  MatSw           = PIN6                  ' MatSwitch Trigger to TCT
SYMBOL  BreakBeam       = PIN5                  ' BreakBeam Trigger to MIB
SYMBOL  TCT             = PIN0                  ' to 12v valve
SYMBOL  Box             = PIN1                  ' to 24v valve

' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  BoxRun        = 10000                 ' box is 10s

SYMBOL  MinJump         =   100                 ' timing for lid/box jumps
SYMBOL  MaxJump         =   250


' -----[ Variables ]-------------------------------------------------------

SYMBOL  sensor      = B0         ' active sensor
SYMBOL  mask      = B1         ' input mask
SYMBOL  debounce        = B2                    ' event timer
SYMBOL  timer           = W3                    ' event timer
SYMBOL  delay           = W4                    ' run delay
SYMBOL  lottery         = W5                    ' random #


' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000011                              ' make P0-P1 outputs


' -----[ Program Code ]----------------------------------------------------

Main:
  sensor = %01100000            ' assume inputs are active
  timer = 0                                     ' reset timer
  FOR debounce = 1 to 20
     RANDOM lottery                             ' stir random #
     PAUSE 10                                   ' debounce inputs
     sensor = sensor & PINS         ' scan inputs
  NEXT
  IF sensor = %01000000 THEN Pop_Up
  IF sensor = %00100000 THEN Thrash
  IF sensor = %00000000 THEN Main               'Loop back to main if no inputs are active

' -----[ Subroutines ]-----------------------------------------------------

Pop_Up:
  HIGH TCT                ' lift prop
  PAUSE 3000                ' hold for 3 seconds
  LOW TCT                ' retract prop

  PAUSE 2000                ' 2 second post-delay
  GOTO Main                ' back to Main

Thrash:
  RANDOM lottery                                ' re-stir
  delay = MaxJump - MinJump + 1                 ' get span
  delay = lottery // delay + MinJump            ' calc jump timing
  Box = IsOn - Box                              ' toggle cylinder
  PAUSE delay                                   ' hold
  timer = timer + delay                         ' update run timer
  IF timer < BoxRun THEN Thrash               ' if not done, go again

  Box = IsOff
  GOTO Main

' -----[ User Data ]-------------------------------------------------------

jukingeo

Hello,

There was quite a bit of talk that Jon and I had in regards to multi-tasking the Prop-2, as it turns out, some of those programs did translate over to the Prop-1.

Here is a program that Jon wrote a while back that should do what you ask:

(The program is referred to as a sequencer or drum sequencer in lieu of the program table, thus in order to change events you just simple alter what you want to turn on/off using the first part of the EEPROM data and then change the timing required by altering the step value in the second part of the EEPROM data.   Alterations to a program like this is VERY easy to do and you can easily visulize what your program will do just by looking at the EEPROM data.   Jon turned me on to these style programs a long time ago and I must say they are excellent and can be suited to a wide variety of tasks.

The the program works because it runs the timing very fast so it "samples" both inputs.  It also sets two timers which count independently).

Hope it works out for you.

Geo

' =========================================================================

'

'   File....... Dual-Sequencer.BS1

'   Purpose....

'   Author..... Jon Williams

'               -- based on code by Allen Huffman

'   E-mail..... jwilliams@efx-tek.com

'   Started....

'   Updated.... 17 MAY 2006

'

'   {$STAMP BS1}

'   {$PBASIC 1.0}

'

' =========================================================================





' -----[ Program Description ]---------------------------------------------

'

' This program converts the Prop-1 into a dual timer capable of simultane-

' ously and independently controlling two individual props.  The outputs

' for each prop are defined by an EEPROM table.  Each record in the table

' holds the new outputs for a given state as well as the timing for that

' state.  Bit7 of the outputs value indicates the end of the sequence. It

' is the programmer's responsibility to set Seq1Start and Seq2Start to

' the proper values before downloading the program.

'

' P6 and P7 are setup for active-high inputs -- move the SETUP jumpers to

' the DN position.





' -----[ Revision History ]------------------------------------------------





' -----[ I/O Definitions ]-------------------------------------------------



SYMBOL  Trigger2        = PIN7                  ' move setup to DN

SYMBOL  Trigger1        = PIN6                  ' move setup to DN





' -----[ Constants ]-------------------------------------------------------



SYMBOL  IsOn            = 1                     ' for active-high input

SYMBOL  IsOff           = 0



SYMBOL  Running         = 1                     ' for status flags

SYMBOL  Stopped         = 0



SYMBOL  Yes             = 1

SYMBOL  No              = 0





SYMBOL  Seq1Start       = 0                     ' start point in EE

SYMBOL  Seq1Mask        = %00111000             ' protect P3-P5



SYMBOL  Seq2Start       = 12                    ' start point in EE

SYMBOL  Seq2Mask        = %00000111             ' protect P0-P2





' -----[ Variables ]-------------------------------------------------------



SYMBOL  status          = B0                    ' sequence status flags

SYMBOL  seq1            = BIT0

SYMBOL  seq2            = BIT1

SYMBOL  pinsTemp        = B1                    ' temporary output

SYMBOL  endOfSeq        = BIT15                 ' 1 = end of sequence

SYMBOL  loopTmr         = B2

SYMBOL  pntr1           = B3                    ' pointer for seq 1

SYMBOL  timer1          = B4                    ' timer for seq 1

SYMBOL  pntr2           = B5

SYMBOL  timer2          = B6





' -----[ Initialization ]--------------------------------------------------



Reset:

  PINS = %00000000                              ' clear outputs

  DIRS = %00111111                              ' set to output mode



  pntr1 = Seq1Start                             ' initialize pointers

  pntr2 = Seq2Start





' -----[ Program Code ]----------------------------------------------------



Main:                                           ' test triggers, pad loop

  FOR loopTmr = 1 TO 5                          ' test 5x

    seq1 = seq1 | Trigger1                      ' update running flag

    seq2 = seq2 | Trigger2                      ' update running flag

    PAUSE 20                                    ' 5 x 20 ms = ~100 ms

  NEXT





Run_1:

  IF seq1 = Stopped THEN Run_2                  ' running?

    IF timer1 = 0 THEN Reload_1                 '  yes, timer expired?

      timer1 = timer1 - 1                       '   no, decrement timer

      GOTO Run_2



Reload_1:

  READ pntr1, pinsTemp                          ' read output state

  pinsTemp = pinsTemp & Seq2Mask                ' protect Seq1 pins

  PINS = PINS & Seq1Mask | pinsTemp             ' apply new outputs

  pntr1 = pntr1 + 1                             ' point to timing

  READ pntr1, timer1                            ' read it

  pntr1 = pntr1 + 1                             ' point to next record

  IF endOfSeq = No THEN Run_2                   ' at end?

    seq1 = Stopped                              ' - stop sequence

    pntr1 = Seq1Start                           ' - reset pointer





Run_2:

  IF seq2 = Stopped THEN Main                   ' running?

    IF timer2 = 0 THEN Reload_2                 '  yes, timer expired?

      timer2 = timer2 - 1                       '   no, decrement timer

      GOTO Main



Reload_2:

  READ pntr2, pinsTemp                          ' read output state

  pinsTemp = pinsTemp & Seq1Mask                ' protect Seq2 pins

  PINS = PINS & Seq2Mask | pinsTemp             ' apply new outputs

  pntr2 = pntr2 + 1                             ' point to timing

  READ pntr2, timer2                            ' read it

  pntr2 = pntr2 + 1                             ' point to next record

  IF endOfSeq = No THEN Main                    ' at end?

    seq2 = Stopped                              ' - stop sequence

    pntr2 = Seq2Start                           ' - reset pointer



  GOTO Main





' -----[ Subroutines ]-----------------------------------------------------





' -----[ EEPROM Data ]-----------------------------------------------------



' Timing value is in ~100 millisecond units

' -- trigger check loop is 5 iterations x 20 ms



Sequence1:

  EEPROM (%00000001, 5)

  EEPROM (%00000010, 5)

  EEPROM (%00000100, 5)

  EEPROM (%00000010, 5)

  EEPROM (%00000001, 5)

  EEPROM (%10000000, 0)                         ' end of sequence





Sequence2:

  EEPROM (%00100000, 2)

  EEPROM (%00010000, 2)

  EEPROM (%00001000, 2)

  EEPROM (%00100000, 2)

  EEPROM (%00010000, 2)

  EEPROM (%00001000, 2)

  EEPROM (%00100000, 2)

  EEPROM (%00010000, 2)

  EEPROM (%00001000, 2)

  EEPROM (%00100000, 2)

  EEPROM (%00010000, 2)

  EEPROM (%00001000, 2)

  EEPROM (%00100000, 2)

  EEPROM (%00010000, 2)

  EEPROM (%00001000, 2)

Spooky Dad

August 29, 2010, 04:18:26 PM #2 Last Edit: August 29, 2010, 04:20:04 PM by Spooky Dad
Thanks Geo!  This is very elegant and I can see that it continually cycles through both Seq1 and Seq2, so that both devices could be tripped (nearly) at the same time.  Nice!  I have a few questions though.  


  • in the second sequence, shouldn't the last entry have a "1" in B7?
  • I don't understand how the following lines of code would ever turn any output high.  I also think the in Reload 1, shouldn't we be protecting Seq2 pins and vice versa in Reload 2? I have edited the code below to what makes sense to me, but would appreciate getting a lesson if I am confused.  

 pinsTemp = pinsTemp| PINS & Seq2Mask                ' read new Seq1 outputs and protect Seq21 pins
 PINS = PINS & Seq1Mask | pinsTemp             ' apply new outputs


  • at the top in declaration of the variable end of sequence, how does the "1" in the eeprom data get in this variable?
  • BTW, how many EEPROM locations are there where data can be stored?

bsnut

Spooky Dad,

I like to point you an article that Jon wrote for Nut&Volts on this whole process http://www.parallax.com/dl/docs/cols/nv/vol7/col/NV135.pdf

This should answer all of your questions on the Multi Tasking with the Prop1 and this saves Jon some typing.

William "bsnut" 
William Stefan
The Basic Stamp Nut

JonnyMac

Do you need to run both props at the same time (really hard, inflexible) or just check two triggers and run whichever is active (easy)?
Jon McPhalen
EFX-TEK Hollywood Office

Spooky Dad

August 30, 2010, 01:12:41 PM #5 Last Edit: August 30, 2010, 01:30:44 PM by Spooky Dad
The latter (easy).  Just check the two triggers and run whichever is active AFTER a time-out has prevented either from be retriggered for 60 seconds.

William "bsnut" - Thank you for pointing me to the article.  It did in fact answer my questions and confirmed / corrected my understanding.  It seems that the original code provided by Geo got truncated and the first pinstemp assignment is actually unnecessary.  It is all much clearer now. 

bsnut

So, you want to do it the easy way and not the multi tasking program that Jon has done for the Nut&Volts article that I pointed out to you. If you do the easy way, you will only be able to do one type of prop at a time, is this what you are looking for? Jon or I can program this with no problem.
William Stefan
The Basic Stamp Nut

JonnyMac

Here's how I would do it -- this version runs just one prop at a time and even handles ties (when both triggers are active at the same time).

' =========================================================================
'
'   File...... Basic_TCT-MIB.BS1
'   Purpose... "Simple" Thrash MIB
'   Author.... Spooky Dad
'   E-mail.... karlen_alexander@dell.com
'   Started... 08/28/2010
'   Updated... 08/30/2010 (by Jon Williams)
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Connections:
'
'
' P6 -   TCT - Mat Switch
'
' P5 -   MIB - Breakbeam
'
' OUT1 - 12v TCT valve
'
' OUT0 - 24v MIB valve


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  MatSw           = PIN6                  ' MatSwitch Trigger to TCT
SYMBOL  BreakBeam       = PIN5                  ' BreakBeam Trigger to MIB

SYMBOL  Box             = PIN1                  ' to 24v valve
SYMBOL  TrashCan        = PIN0                  ' to 12v valve


' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  BoxRun          = 10000                 ' box is 10s

SYMBOL  MinJump         =   100                 ' timing for lid/box jumps
SYMBOL  MaxJump         =   250


' -----[ Variables ]-------------------------------------------------------

SYMBOL  sensor          = B2                    ' active sensor
SYMBOL  mask            = B3                    ' input mask
SYMBOL  debounce        = B4                    ' event timer
SYMBOL  last            = B5                    ' for handling ties

SYMBOL  timer           = W3                    ' event timer
SYMBOL  delay           = W4                    ' run delay
SYMBOL  lottery         = W5                    ' random #


' -----[ Initialization ]--------------------------------------------------

Reset:
 PINS = %00000000                              ' clear all
 DIRS = %00000011                              ' make P0-P1 outputs


' -----[ Program Code ]----------------------------------------------------

Main:
 sensor = %01100000                            ' assume inputs are active
 FOR debounce = 1 TO 20
   RANDOM lottery                              ' stir random #
   PAUSE 10                                    ' debounce inputs
   sensor = sensor & PINS                      ' re-scan inputs
 NEXT

 sensor = sensor / 32                          ' shift to right
 BRANCH sensor, (Main, Thrash, Pop, Tie)

Tie:
 BRANCH last, (Thrash, Pop)


Pop:
 HIGH TrashCan                                 ' lift prop
 PAUSE 3000                                    ' hold for 3 seconds
 LOW TrashCan                                  ' retract prop
 last = 0
 GOTO Post_Delay


Thrash:
 timer = 0

Thrash_Again:
 RANDOM lottery                                ' re-stir
 delay = MaxJump - MinJump + 1                 ' get span
 delay = lottery // delay + MinJump            ' calc jump timing
 Box = IsOn - Box                              ' toggle cylinder
 PAUSE delay                                   ' hold
 timer = timer + delay                         ' update run timer
 IF timer < BoxRun THEN Thrash_Again           ' if not done, go again
   Box = IsOff
 last = 1


Post_Delay:
 PAUSE 60000                                   ' no triggers for 1 min
 GOTO Main

' -----[ User Data ]-------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

Spooky Dad

August 30, 2010, 04:07:14 PM #8 Last Edit: August 30, 2010, 04:27:57 PM by Spooky Dad
Thanks JonnyMac!  A couple of questions to the forum, if I may.

1.  How does dividing by 32 shift things to the right?  What value does %01000000 become after dividing by 32?  What value does %00100000 become after diving by 32?  What value does %01100000 become?  If I am reading the guide right, the last four bits become the first, 0 through 3?
2.  Why is there Thrash and Thrash Again sub routines?  Couldn't they just be combined into a single subroutine, or am I missing something simple?  UPDATED - I found my answer.  You needed another place to send the MIB code back to without resetting the timer.  
3.  The only other thing that we want the program to do is to have a unique time-out period per prop, allowing the other prop to still be tripped if it has been longer than 60 seconds.  Can anyone help with that?

William "bsnut" - The props will never be run / have a chance to run at the same time due to their placement in the haunt.  Just in case, the tie logic is a nice back up.  As mentioned above, the only remaining issue is preventing retriggering so that the victims in the haunt move on after the TCT or MIB has triggered and quit.

JonnyMac

PBASIC1 does not have shift operators, so we get there -- albeit the hard way -- by dividing.  Each bit position is a power of two.  To shift right one bit position we divide by two; to shift right by two bit positions we divide by four, three positions is eight, and so on.

In that program we are using bits 5 and 6 of the sensor byte as inputs.  In order to convert this:

IF sensor = %00000000 THEN Main
IF sensor = %00100000 THEN Thrash
IF sensor = %01000000 THEN Pop
IF sensor = %01100000 THEN Tie


... to a BRANCH statement we have to move the bit5 (P5) to the bit0 position.  As I just pointed out we don't have the shift operator so we use divide instead.  The key is that you must use powers of two

2 (1 bit), 4 (2 bits), 8 (3 bits), 16 (4 bits), 32 (5 bits), 64 (6 bits), 128 (7 bits)

Having a time-out timer per prop is hard.  I'll try, with no guarantees that there is enough variable space available. 

You know... every time someone wants to control two independent props from one Prop-1 controller, I get this urge to raise the price....  :)

Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

Okay, give this a try.  I've done the heavy lifting -- your job is to 1) try it, and 2) study it to discover the logic I used to implement two timers.

' =========================================================================
'
'   File...... Basic_TCT-MIB.BS1
'   Purpose... "Simple" Thrash MIB
'   Author.... Spooky Dad
'   E-mail.... karlen_alexander@dell.com
'   Started... 08/28/2010
'   Updated... 08/30/2010 (by Jon Williams)
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Connections:
'
'   P6   - TCT - Mat Switch
'   P5   - MIB - Breakbeam
'
'   OUT1 - 12v TCT valve
'   OUT0 - 24v MIB valve


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  MatSw           = PIN6                  ' MatSwitch Trigger to TCT
SYMBOL  BreakBeam       = PIN5                  ' BreakBeam Trigger to MIB

SYMBOL  Box             = PIN1                  ' to 24v valve
SYMBOL  TrashCan        = PIN0                  ' to 12v valve


' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  BoxRun          = 10000                 ' box is 10s

SYMBOL  MinJump         =   100                 ' timing for lid/box jumps
SYMBOL  MaxJump         =   250


' -----[ Variables ]-------------------------------------------------------

SYMBOL  sensor          = B0                    ' active sensor
SYMBOL  idx             = B1                    ' loop control
SYMBOL  last            = B2                    ' for handling ties

SYMBOL  timeout0        = W2                    ' timeout for thrash
SYMBOL  timeout1        = W3                    ' timeout for pop-up
SYMBOL  timer           = W4                    ' event timer
SYMBOL  delay           = W5                    ' run delay
SYMBOL  lottery         = W6                    ' random #


' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000011                              ' make P0-P1 outputs


' -----[ Program Code ]----------------------------------------------------

Main:
  sensor = %01100000                            ' assume inputs are active
  FOR idx = 1 TO 20
    RANDOM lottery                              ' stir random #
    PAUSE 10                                    ' debounce inputs
    sensor = sensor & PINS                      ' re-scan inputs
  NEXT

Check_T0:
  IF timeout0 = 0 THEN Check_T1                 ' timeout timer running?
    timeout0 = timeout0 - 200                   ' (must match debounce loop timing)

Check_T1:
  IF timeout1 = 0 THEN Check_Sensor
    timeout1 = timeout1 - 200

Check_Sensor:
  sensor = sensor / 32                          ' shift to right
  BRANCH sensor, (Main, Thrash, Pop, Tie)

Tie:
  BRANCH last, (Pop, Thrash)


Thrash:
  IF timeout0 > 0 THEN Main                     ' still in time-out?
  timer = 0

Thrash_Again:
  RANDOM lottery                                ' re-stir
  delay = MaxJump - MinJump + 1                 ' get span
  delay = lottery // delay + MinJump            ' calc jump timing
  Box = IsOn - Box                              ' toggle cylinder
  PAUSE delay                                   ' hold
  timer = timer + delay                         ' update run timer
  IF timer < BoxRun THEN Thrash_Again           ' if not done, go again
    Box = IsOff
  last = 0
  timeout0 = 60000                              ' no retrigger for 60s
  GOTO Main


Pop:
  IF timeout1 > 0 THEN Main                     ' still in time-out?
  HIGH TrashCan                                 ' lift prop
  PAUSE 3000                                    ' hold for 3 seconds
  LOW TrashCan                                  ' retract prop
  last = 1
  timeout1 = 60000                              ' no retrigger for 60s
  GOTO Main


' -----[ User Data ]-------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

QuoteYou know... every time someone wants to control two independent props from one Prop-1 controller, I get this urge to raise the price.... 

Or just charge $39.95 for your programming services........ ;D

Spooky Dad

Got it!  Lesson received and I think understood.  By adding the two time out values, if they are not all the way counted down to 0 from 60000 (200 ms at a time because of the random stir time), then the Pop and Thrash, respectively will escape back to main.  Since the program will not always go to Pop or Thrash, you added the two conditions up front, check t0 and check t1, to take care of the decrement from t0 and t1 through every loop.  Jaxombie and I will try by the end of the holiday weekend and let you know.  The test of learning a lesson is applying it in the future.   :)  Thanks JonnyMac!

JonnyMac

Well, you see why it's so tough to cleanly run two independent props from one Prop-1 controller.  Your post pointed out that I didn't account for one prop's timeout period while the other ran -- this variation does.

After you understand this I expect you to help me help others as we get into the season!  ;D

' =========================================================================
'
'   File...... Basic_TCT-MIB.BS1
'   Purpose... "Simple" Thrash MIB
'   Author.... Spooky Dad
'   E-mail.... karlen_alexander@dell.com
'   Started... 08/28/2010
'   Updated... 08/31/2010 (by Jon Williams)
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Connections:
'
'   P6   - TCT - Mat Switch
'   P5   - MIB - Breakbeam
'
'   OUT1 - 12v TCT valve
'   OUT0 - 24v MIB valve


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  MatSw           = PIN6                  ' MatSwitch Trigger to TCT
SYMBOL  BreakBeam       = PIN5                  ' BreakBeam Trigger to MIB

SYMBOL  Box             = PIN1                  ' to 24v valve
SYMBOL  TrashCan        = PIN0                  ' to 12v valve


' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  BoxRun          = 10000                 ' box is 10s

SYMBOL  MinJump         =   100                 ' timing for lid/box jumps
SYMBOL  MaxJump         =   250

SYMBOL  PopTiming       =  3000


' -----[ Variables ]-------------------------------------------------------

SYMBOL  sensor          = B0                    ' active sensor
SYMBOL  idx             = B1                    ' loop control
SYMBOL  last            = B2                    ' for handling ties

SYMBOL  timeout0        = W2                    ' timeout for thrash
SYMBOL  timeout1        = W3                    ' timeout for pop-up
SYMBOL  timer           = W4                    ' event timer
SYMBOL  delay           = W5                    ' run delay
SYMBOL  lottery         = W6                    ' random #


' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000011                              ' make P0-P1 outputs


' -----[ Program Code ]----------------------------------------------------

Main:
  sensor = %01100000                            ' assume inputs are active
  FOR idx = 1 TO 20
    RANDOM lottery                              ' stir random #
    PAUSE 10                                    ' debounce inputs
    sensor = sensor & PINS                      ' re-scan inputs
  NEXT

Check_T0:
  IF timeout0 = 0 THEN Check_T1                 ' timeout timer running?
    timeout0 = timeout0 - 200                   ' (must match debounce loop timing)

Check_T1:
  IF timeout1 = 0 THEN Check_Sensor
    timeout1 = timeout1 - 200

Check_Sensor:
  sensor = sensor / 32                          ' shift to right
  BRANCH sensor, (Main, Thrash, Pop, Tie)

Tie:
  BRANCH last, (Pop, Thrash)


Thrash:
  IF timeout0 > 0 THEN Main                     ' still in time-out?
  timer = 0

Thrash_Again:
  RANDOM lottery                                ' re-stir
  delay = MaxJump - MinJump + 1                 ' get span
  delay = lottery // delay + MinJump            ' calc jump timing
  Box = IsOn - Box                              ' toggle cylinder
  PAUSE delay                                   ' hold
  timer = timer + delay                         ' update run timer
  IF timer < BoxRun THEN Thrash_Again           ' if not done, go again
    Box = IsOff
  last = 0
  timeout0 = 60000                              ' no retrigger for 60s

Update_T1:                                      ' update other timer
  IF timeout1 > BoxRun THEN Update_T1b          ' if running
    timeout1 = 0
    GOTO Main

Update_T1b:
  timeout1 = timeout1 - BoxRun
  GOTO Main


Pop:
  IF timeout1 > 0 THEN Main                     ' still in time-out?
  HIGH TrashCan                                 ' lift prop
  PAUSE PopTiming                               ' hold
  LOW TrashCan                                  ' retract prop
  last = 1
  timeout1 = 60000                              ' no retrigger for 60s

Update_T0:                                      ' update other timer
  IF timeout0 > PopTiming THEN Update_T0b       ' if running
    timeout0 = 0
    GOTO Main

Update_T0b:
  timeout0 = timeout0 - PopTiming
  GOTO Main


' -----[ User Data ]-------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

Spooky Dad

I honestly didn't catch it, but I'm glad I sparked your synapses.  Thanks again and consider me vominated (a blend of volunteering and nomination) to help out this season.  Looking to get upgraded to a jr member.  :)