One of the most compelling reasons to use a programmable controller like the Prop-1, Prop-2, or Prop-SX in your designs is a function of the respective languages called RANDOM. To be fair, RANDOM isn't truly random, it is in fact pseudo-random. What this means is that the algorithm used generates a seemingly random list of values each time it's called. The result of the RANDOM function is wholly dependent on the seed value feed to it; same seed, same result.
That said, our props are often waiting for something to happen, perhaps a PIR or mat switch to detect a guest. While waiting, we can continuously call RANDOM and thus end up with a truly random value; we're using random timing of the external event to drive the value. Here's what it looks like in code:
Main:
RANDOM lottery
IF PIR = No THEN Main
As you can see, the RANDOM function will be called until the PIR goes active, and that is a random event, hence we end up with a random value in lottery.
Just a note: When using RANDOM to drive LEDs to create a candle-flicker effect, you should stir the random value a few times before sending it to the LEDs. The reason is that the algorithm used for RANDOM is called a Linear Feedback Shift Register, and while the decimal values look random, one can see the apparent linear motion of the bits when the output is connected to parallel LEDs. The fix is easy:
Light_Candles:
FOR idx = 1 TO 3
RANDOM lottery
NEXT
Wicks = lottery
PAUSE 25
GOTO Light_Candles
Just to show effective RANDOM can be here's a little test program for or "Chuckie Fries" electric chair prop:
SYMBOL Thrasher = 0
SYMBOL msDelay = B2
SYMBOL lottery = W5
Reset:
LOW Thrasher
Main:
RANDOM lottery
msDelay = lottery // 201 + 50
TOGGLE Thrasher
PAUSE msDelay
GOTO Main
Here's video from the test bench:
--- http://www.efx-tek.com/files/chuckie_fries.wmv (http://www.efx-tek.com/files/chuckie_fries.wmv)
Special thanks to "Scary" Terry Simmons and his family for helping me assembly this over the weekend.
I've been asked about triggering the program above and running the random thrashing for a specific period; here's how:
' {$STAMP BS1}
' {$PBASIC 1.0}
SYMBOL Trigger = PIN6 ' SETUP = DN
SYMBOL Thrasher = 0
SYMBOL IsOff = 0
SYMBOL IsOn = 1
SYMBOL ThrashTime = 15000 ' 15 seconds
SYMBOL msDelay = B2 ' thrash cycle timing
SYMBOL timer = W4 ' event timing
SYMBOL lottery = W5 ' random value
Reset:
LOW Thrasher
Main:
IF Trigger = IsOff THEN Main ' wait for trigger
timer = 0 ' reset timer
Thrash_Baby_Thrash:
IF timer > ThrashTime THEN Settle_Down ' quit if timer expired
RANDOM lottery ' create new timing
msDelay = lottery // 201 + 50 ' between 50 and 250 ms
TOGGLE Thrasher ' flip cylinder status
PAUSE msDelay ' hold
timer = timer + msDelay ' update timer
GOTO Thrash_Baby_Thrash
Settle_Down:
LOW Thrasher ' stop it!
PAUSE 15000 ' hold 15 secs
GOTO Main ' start over
Jon,
In your Thrasher program, how do you change the thrash cycle timing from between 50 and 250 ms to something longer, like 500 to 1000 ms. I thought it would be as simple as changing the values, but it didn't work.
Thanks for the help and all your good example programs.
Jim
Two things need to happen. 1) You need to define msDelay as a Word so that it can old values greater than 255, like this:
SYMBOL msDelay = W3 ' thrash cycle timing
... and 2), you need to update the code that sets msDelay. For 500 to 1000 it would be this:
msDelay = lottery // 501 + 500
Thanks, it works perfectly.
Do I need to use the "w" variable vs the "b" variable because I need to use the word name and not the byte name? I assume this is due to size?
Thanks for the lesson.
Jim
Yes, that's correct. This article -- one of my first for Nuts & Volts -- goes into detail on BS1 (the brain of the Prop-1) memory.
-- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol1/col/nv30.pdf