May 20, 2024, 01:09:23 PM

News:

Got VSA?  Want to use your Prop-SX?  Now you can!  See the VSA section of the Library forum for Prop-SX code that works with VSA.


Randon LED flicker with Bias towards certain output

Started by gadget-evilusions, April 18, 2016, 07:06:36 PM

Previous topic - Next topic

gadget-evilusions

I want to use a prop-1 to get the following effect if possible:

Led1 on OUT0
Led2 on OUT1
Led3 on OUT2

Program continuously loops with no trigger inputs

I want the 3 outputs to randomly turn on and off, with 100 to 500ms off time, and 250 to 1000ms on times. Only one output should be on at a time. Out0 should be chosen 15% of the time, OUT1 60% of the time, and OUT2 25% of the time.

Is this asking too much of a prop-1? Making leds randomly flicker is 2nd hand to me now, but having to only pick one at a time, and not in equal amounts is what is causing me trouble with where to start.
Brian
Evilusions LLC
www.evilusions.com for all your pneumatic components

JonnyMac

This isn't perfect but may get close to what you're looking for. Since the 5% is the common denominator in the distribution there is a table of 20 values which provides the desired distribution. Assuming -- and this is not a good assumption -- that the RANDOM function has pretty event distribution of its numbers, the output should pretty closely match what you want.

If I was doing this on the Propeller I would have a mask value that would ensure all elements of the distribution table had been output in a cycle before starting another. That's really tough to do in the BS1 (not shifting and limited to a couple of 16-bit variables [we need 20 bits]).

' =========================================================================
'
'   File...... random_leds.bs1
'   Purpose...
'   Author.... JonnyMac (for Brian Warner)
'   E-mail....
'   Started...
'   Updated... 18 APR 2016
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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


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

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  idx             = B2
SYMBOL  theLed          = B3

SYMBOL  delay           = W4
SYMBOL  lottery         = W5


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

Power_Up:
  ' put code here that only happens at power-up/hard reset

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00000111                              ' P2..P0 are outputs

  lottery = 725                                 ' initial seed


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

Main:
  RANDOM lottery
  idx = lottery // 20                           ' random, 0..19
  READ idx, theLed                              ' read output from index

  HIGH theLed
  RANDOM lottery
  delay = lottery // 751 + 250                  ' random, 250..1000 on
  PAUSE delay

  LOW theLed
  RANDOM lottery
  delay = lottery // 401 + 100                  ' random, 100..500 off
  PAUSE delay

  GOTO Main


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

Distribution:
  EEPROM (1, 1, 2, 1, 1, 0, 2)
  EEPROM (1, 1, 2, 1, 1, 0, 2)
  EEPROM (1, 1, 2, 1, 1, 0)

Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

April 19, 2016, 02:16:31 PM #2 Last Edit: April 19, 2016, 06:40:57 PM by JonnyMac
Having slept on it, I came up with this version -- it tries to ensure your distribution rules by using three bytes to hold the 20 flag bits.

' =========================================================================
'
'   File...... bw_random_leds.bs1
'   Purpose... Randomized LED output wit bias
'              -- OUT0 = 15%, OUT1 = 60%, OUT2 = 25%
'   Author.... JonnyMac (for Brian Warner)
'   E-mail....
'   Started...
'   Updated... 19 APR 2016
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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


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

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  idx             = B0
SYMBOL  theLed          = B1

SYMBOL  flags0          = B2                    ' flags0 & 1 are in W1
SYMBOL  flags1          = B3
SYMBOL  flags2          = B4

SYMBOL  mask            = B5
SYMBOL  check           = B6

SYMBOL  delay           = W4
SYMBOL  lottery         = W5


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

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00000111                              ' P2..P0 are outputs

  lottery = 725                                 ' initial seed


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

Main:
  RANDOM lottery
  idx = lottery // 20                           ' random, 0..19

  IF idx <  8 THEN Check0
  IF idx < 16 THEN Check1

Check2:
  mask = idx - 16                               ' get 0..7 position
  READ mask, mask                               ' convert to bit mask
  check = flags2 & mask                         ' slot already used?
  IF check > 0 THEN Main                        ' if yes, try again
    flags2 = flags2 | mask                      ' no, mark now
    GOTO LED_On

Check1:
  mask = idx - 8
  READ mask, mask
  check = flags1 & mask
  IF check > 0 THEN Main
    flags1 = flags1 | mask
    GOTO LED_On

Check0:
  READ idx, mask
  check = flags0 & mask
  IF check > 0 THEN Main
    flags0 = flags0 | mask

LED_On:
  idx = idx + 8                                 ' disti table at addr 8
  READ idx, theLed                              ' read output from index

  HIGH theLed
  RANDOM lottery
  delay = lottery // 751 + 250                  ' random, 250..1000 on
  PAUSE delay

  LOW theLed
  RANDOM lottery
  delay = lottery // 401 + 100                  ' random, 100..500 off
  PAUSE delay

Check_All_Used:
  IF flags0 <> %11111111 THEN Main
  IF flags1 <> %11111111 THEN Main
  IF flags2 <> %00001111 THEN Main

Reset_Distribution:
  flags0 = $00
  flags1 = $00
  flags2 = $00
  GOTO Main


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

Masks:
  EEPROM ($01, $02, $04, $08, $10, $20, $40, $80)


' Distribution rules
' -- 0 = 15%
' -- 1 = 60%
' -- 2 = 25%

Distribution:
  EEPROM (1, 1, 2, 1, 1, 0, 2)                  ' starts at address 8
  EEPROM (1, 1, 2, 1, 1, 0, 2)
  EEPROM (1, 1, 2, 1, 1, 0)
Jon McPhalen
EFX-TEK Hollywood Office

fearfair

What would need to be changed to make the LED's stay on longer?  I had asked Brian for help with this and he then posted here.  Here is the completed prop running the code...

https://vimeo.com/184844726



The code is for these 'air quality monitors' for our queue line, which is themed as a cavern.  The idea being that the oxygen is being depleted.  The actual desired behavior would be for the red LED to stay lit the majority of the time and then switch to amber or green only for a moment, then back to red..

Is that possible?

JonnyMac

When programming a prop, context always matters. Seeing the video caused me to write this program:

' =========================================================================
'
'   File...... air_quality.bs1
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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


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

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  Red             = %100                  ' OUT2
SYMBOL  Yellow          = %010                  ' OUT1
SYMBOL  Green           = %001                  ' OUT0

SYMBOL  AllOff          = %000
SYMBOL  AllOn           = %111


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

SYMBOL  delay           = W4

SYMBOL  lottery         = W5
SYMBOL   lottoLo        =  B10                  ' low byte of lotto
SYMBOL   lottoHi        =  B11                  ' high byte of lotto


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

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00000111                              ' P2..P0 are outputs

  READ 0, lottoLo                               ' read random seed
  READ 1, lottoHi

  PINS = AllOn                                  ' do a lamp test
  PAUSE 1000
  PINS = AllOff
  PAUSE 250


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

Main:
  RANDOM lottery

Critical:
  PINS = Red
  RANDOM lottery
  delay = lottery // 751 + 250                  ' random, 250..1000 on
  PAUSE delay
  RANDOM lottery
  IF lottoLo > 64 THEN Main                     ' drop to moderate 25% of the time

Moderate:
  PINS = Yellow
  RANDOM lottery
  delay = lottery // 251 + 250                  ' random, 250..500 on
  PAUSE delay
  RANDOM lottery
  IF lottoLo > 64 THEN Main                     ' drop to safe 25% of the time

Safe:
  PINS = Green
  RANDOM lottery
  delay = lottery // 251 + 250                  ' random, 250..500 on
  PAUSE delay

Save_Seed:
  WRITE 0, lottoLo                              ' save random # for next
  WRITE 1, lottoHi

  GOTO Moderate

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

Seed:
  EEPROM (10, 31)                               ' random seed


The Red (OUT2) light is on most of the time. After a random period the random number generator is stirred and we do a check so that the Yellow (OUT1) will run about 25% of the time (remember though, the timing is randomized so it will wobble). After a short delay we do that test again so about 25% of the time that the Yellow runs, the Green will be called. Since this is a monitor type device, when the Green light runs it will go back to Yellow before going back to Red. This seems to me to be a more authentic behavior for a device that is measuring changes in air quality.

I also added a feature which reads the random # see from the EEPROM. When the Green LED is on the value in the random # (lottery) is saved back to the EEPROM. The truth of the matter is that RANDOM is actually pseudo-random; that is, it creates what looks like and random sequence but in fact it's not. Given the same seed value, you will get a predictable result. This is what allows us to write Simon-style games without having to memorize the output sequence.
Jon McPhalen
EFX-TEK Hollywood Office

fearfair

Thank you so much.... This looks so much more realistic.

JonnyMac

Excellent. As I pointed out, context matters. It's not just blinking lights, is an air quality level simulation -- hence requires a different approach from random blinking lights. Anyway, we're always happy to help.
Jon McPhalen
EFX-TEK Hollywood Office


JonnyMac

Jon McPhalen
EFX-TEK Hollywood Office