November 24, 2024, 09:10:45 PM

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.


Static, Random and Chasing Lights

Started by Patrick, February 16, 2015, 06:56:56 AM

Previous topic - Next topic

Patrick

I can't seem to figure this out.  Using a Prop1 with no trigger. All outputs used for LEDS.  I can find programs on the site that can do part of what I need, but not quite for everything.  What I need is:

Out 0 - 3 - Randomly flashing, at PAUSE 250 rate consistently
Out 4 - Static
Out 5 - 7 - Chase between 5-6-7 with a increasingly slower rate from PAUSE 25 to PAUSE 500 then back down to 25 again which repeats.

I can get everything to work at one single rate, but not with the different rates needed between the random and the chase.   Is this possible with t he Prop 1?  Can you provide an example if so?

Thanks,
Patrick

JonnyMac

That's actually going to be very tricky because you're asking a single-threaded controller to act like it can multi-task. What that means is you cannot use PAUSE in the way you think -- you must divide up your timing into small increments. I'll work on something for you.

It's going to look scary... :)
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

February 16, 2015, 01:59:57 PM #2 Last Edit: February 16, 2015, 02:32:42 PM by JonnyMac
Here you go. The world of Prop-1 multi-tasking is not one we like to play in. This was darned difficult. I had to hook up an oscilloscope to set the timing.

Is this for a retro sci-fi prop?

' =========================================================================
'
'   File...... patrick_leds.bs1
'   Purpose...
'   Author.... JonnyMac
'   E-mail....
'   Started...
'   Updated... 16 FEB 2015
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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

' Out 0..3 - Randomly flashing, at PAUSE 250 rate consistently
' Out 4      Static
' Out 5..7 - Chase between 5-6-7 with a increasingly slower rate from
'            PAUSE 25 TO PAUSE 500 then back down TO 25 again. Repeat


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


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


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

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  outBits         = B1

SYMBOL  fTimer          = B2                    ' 10 x 25ms = 250ms

SYMBOL  chState         = B3                    ' chaser state
SYMBOL  stTimer         = B4                    ' state timer
SYMBOL  chDelay         = B5                    ' chase delay for cycle
SYMBOL  chMode          = B6                    ' slow down / speed up

SYMBOL  lottery         = W5                    ' random #


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

Reset:
  PINS = %00010000                              ' P4 on
  DIRS = %11111111                              ' all outputs


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

Main:
  PAUSE 19                                     ' tuned for ~25ms loop


  ' random flasher process

Flasher:
  IF fTimer <> 0 THEN F_Exit                    ' time to update?
    RANDOM lottery                              ' stir random #
    outBits = lottery & %1111                   ' get four bits
    PINS = PINS & %11110000 | outBits           ' update OUT3..OUT0

F_Exit:
  fTimer = fTimer + 1 // 10                     ' keep 0 to 9


  ' 3-step chaser process

Chaser:
  LOOKUP chState, (%001, %010, %100), outBits   ' convert state to bit
  outBits = outBits * 32                        ' shift left 5 bits
  PINS = PINS & %00011111 | outBits             ' update OUT7..OUT5

  stTimer = stTimer + 1
  IF stTimer <= chDelay THEN Ch_Exit
    stTimer = 0                                 ' reset state timer
    chState = chState + 1 // 3                  ' update state

  IF chState <> 0 THEN Ch_Exit                  ' skip if no timing change

  BRANCH chMode, (SlowDown, SpeedUp)            ' jump to timing mode

SlowDown:
  chDelay = chDelay + 1
  IF chDelay < 20 THEN Ch_Exit
    chDelay = 18                                ' go other way
    chMode = 1                                  ' switch mode
    GOTO Ch_Exit

SpeedUp:
  chDelay = chDelay - 1
  IF chDelay <> $FF THEN Ch_Exit                ' $FF = -1
    chDelay = 1
    chMode = 0
    GOTO Ch_Exit

Ch_Exit:
  GOTO Main


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


' -------------------------------------------------------------------------


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

JackMan

I'll second the "Darned difficult". I took a stab at this before Jon posted and though I came close a couple times, I had some Hick-ups. Kudos to Jon for figuring this out!  ;)

JonnyMac

February 16, 2015, 04:36:18 PM #4 Last Edit: February 16, 2015, 04:39:47 PM by JonnyMac
Multitasking programs -- which the BS1 (brain of the Prop-1) is not really equipped to handle -- force us to think differently about time; we must stop thinking about fixed delays and work ins small slices. In this case the obvious slice was 25ms, though as you can see in the code, the one place PAUSE is used is adjusted to account for the amount of time spent doing other things. These programs are also like a Quentin Tarantino move: you often feel like you're entering the story part way through.

The random LEDs part was easy; I knocked that out as fast as I could type it.

The chaser with changing speed was another story; I banged my head around for a couple hours. Geez... at the EFX-TEK consulting rate of $150/hr, that's an expensive piece of code! :)
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

I really didn't think I was gonna get this but thought I'd give it a whirl. I did start out with 25ms as the time unit and I also had the random part pretty quickly but didn't quite get things right with the changing delay for the chaser.  ::)

Patrick

Jon,

I was not even in the ballpark, I really did not think this could be done.  Many thanks for making it work.  I am actually building a series of "mad scientist" lab props for Halloween this year which will require 14 Prop-1's, many of which will be using a version of this code.  I had easily done this type program on Prop-2's, but I was trying to save some money by going with the Prop-1 due to the quantity involved.  Hopefully you get a cut of Prop-1 sales to make up for the lost consulting fee!

Thanks again, I truly appreciate it.

Patrick

JonnyMac

February 16, 2015, 10:46:49 PM #7 Last Edit: February 17, 2015, 02:32:25 PM by JonnyMac
That is the up-side of buying our off-the-shelf products: you get our consulting (within reason -- and as long as you do it through the forums where others can benefit) at no charge! Crazy, I know, but that's how we roll.

Good luck with your project.
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

February 19, 2015, 08:46:56 PM #8 Last Edit: February 19, 2015, 08:51:04 PM by JackMan
Well, I took another stab at this with a totally different approach. The timing of the random LED's is a little off the mark but all in all the program functions pretty close to what Patrick was looking for. I'm no programming Guru like Jon, I just have middle of the road skills at best. I might add also that my program eats up about double the eeprom space compared to Jon's. Mine jumps the chase time straight back to 25ms after reaching about 1/2 second and also only has one of the 4 random LED's lit at any given time.


'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

'LED's on P0-P7


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


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

SYMBOL delay         = W1
SYMBOL lottery       = W2
SYMBOL idx           = W3
SYMBOL counter       = W4

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

Reset:
  PINS = %00010100                              ' LED 2&4 ON
  DIRS = %11111111                              ' make P0-P7 outputs
  idx = 0

' -----[ Program Code ]----------------------------------------------------
Main:
   counter = 0
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   delay = 0
Chase_1:                                        'chase LED's 5-7 from 25ms to 500ms and then back to 25ms
   idx = 1
   delay = delay + 25
   HIGH 5
   PAUSE delay
   LOW 5
   HIGH 6
   counter = counter + delay
   IF counter => 450 THEN Flash
Chase_2:
   idx = 2
   PAUSE delay
   LOW 6
   HIGH 7
   counter = counter + delay
   IF counter => 450 THEN Flash
Chase_3:
   idx = 3
   PAUSE delay
   LOW 7
   counter = counter + delay
   IF counter => 450 THEN Flash
   GOTO Chase_1

Flash:
    counter = 0
    RANDOM lottery
     IF lottery  > 49151 THEN Flash_3
     IF lottery  > 32768 THEN Flash_2
     IF lottery  > 16384 THEN Flash_1
     IF lottery  < 16384 THEN Flash_0
Flash_0:
   IF PIN0 = 1 THEN Flash_1
   LOW 1
   LOW 2
   LOW 3
   HIGH 0                                    ' LED 0 is on
   IF delay => 450 THEN Main
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   GOTO Chase_1
Flash_1:
   IF PIN1 = 1 THEN Flash_2
   LOW 0
   LOW 2
   LOW 3
   HIGH 1                                    ' LED 1 is on
   IF delay => 450 THEN Main
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   GOTO Chase_1
Flash_2:
   IF PIN2 = 1 THEN Flash_3
   LOW 0
   LOW 1
   LOW 3
   HIGH 2                                    ' LED 2 is on
   IF delay => 450 THEN Main
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   GOTO Chase_1
Flash_3:
   IF PIN3 = 1 THEN Flash_0
   LOW 0
   LOW 1
   LOW 2
   HIGH 3                                    ' LED 3 is on
   IF delay => 450 THEN Main
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   GOTO Chase_1

JackMan

February 20, 2015, 07:13:04 PM #9 Last Edit: February 21, 2015, 12:24:59 PM by JackMan
Had some redundant code in the previous version, this one is cleaned up a bit and uses less eeprom. (Still more than Jon's though!)


'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

'LED's on P0-P7


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


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

SYMBOL idx           = B1
SYMBOL delay         = W1
SYMBOL lottery       = W2
SYMBOL counter       = W3

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

Reset:
  PINS = %00010100                              ' LED 2&4 ON
  DIRS = %11111111                              ' make P0-P7 outputs
  idx = 0

' -----[ Program Code ]----------------------------------------------------
Main:
   counter = 0
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   delay = 0
Chase_1:                                        'chase LED's 5-7 from 25ms to approx. 500ms and then back to 25ms
   idx = 1
   delay = delay + 25
   HIGH 5
   PAUSE delay
   LOW 5
   HIGH 6
   GOSUB Flash_It
Chase_2:
   idx = 2
   PAUSE delay
   LOW 6
   HIGH 7
   GOSUB Flash_It
Chase_3:
   idx = 3
   PAUSE delay
   LOW 7
   GOSUB Flash_It
   GOTO Chase_1
Flash:
    counter = 0
    RANDOM lottery
     IF lottery  > 49151 THEN Flash_3
     IF lottery  > 32768 THEN Flash_2
     IF lottery  > 16384 THEN Flash_1
Flash_0:
   IF PIN0 = 1 THEN Flash_1
   LOW 1
   LOW 2
   LOW 3
   HIGH 0                                    ' LED 0 is on
   GOSUB Delay_Time
Flash_1:
   IF PIN1 = 1 THEN Flash_2
   LOW 0
   LOW 2
   LOW 3
   HIGH 1                                    ' LED 1 is on
   GOSUB Delay_Time
Flash_2:
   IF PIN2 = 1 THEN Flash_3
   LOW 0
   LOW 1
   LOW 3
   HIGH 2                                    ' LED 2 is on
   GOSUB Delay_Time
Flash_3:
   IF PIN3 = 1 THEN Flash_0
   LOW 0
   LOW 1
   LOW 2
   HIGH 3                                    ' LED 3 is on
   GOSUB Delay_Time
Delay_Time:
   IF delay => 450 THEN Main
   IF idx = 1 THEN Chase_2
   IF idx = 2 THEN Chase_3
   GOTO Chase_1
Flash_It:
   counter = counter + delay
   IF counter => 450 THEN Flash
   RETURN

JonnyMac

February 20, 2015, 08:20:21 PM #10 Last Edit: February 20, 2015, 08:22:50 PM by JonnyMac
You can change these lines to one

  LOW 0
  LOW 2
  LOW 3
  HIGH 1


like this

  PINS = PINS & %11110000 | %0010

PBASIC expressions are evaluated left-to-right, so the first part of the right side ANDs the current PINS setting with %11110000 which clears everything from P3..P0. The second side of that expression ORs the new P3..P0 pins to the output.

Masking is an important skill in microcontroller programming.
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

Great tip, thanks! This does indeed work but oddly enough, using this knocked 12 lines off the program but it only saved 1% on the eeprom. I'm also a little confused as to why the first part of that code (in red) doesn't turn on all of the chaser pins 5-7.
PINS = PINS & %11110000 | %0010

JonnyMac

The rule of AND is both bits have to be 1 for the result to be 1. What that line does is preserve the states of P7..P4 -- whatever they presently are. 1 and 1 = 1 (stays on). 1 and 0 = 0 (states off).

With OR is "If one or the other is 1, the result is 1" -- this is why we have to clear the P3..P0 bits with AND before updating to the new state with OR.

Code like this won't always shrink EE space, but it's worth trying in the Prop-1 with such a small memory.
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

Thanks for that explanation, I get it now and better yet, I think I'll remember!  ???

bsnut

Quote from: JackMan on February 21, 2015, 12:22:52 PM
Thanks for that explanation, I get it now and better yet, I think I'll remember!  ???
Thanks for showing. You learn something new everyday.
William Stefan
The Basic Stamp Nut