October 31, 2024, 08:28:18 PM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


Controlling more than set of light outputs at a time.

Started by jukingeo, September 16, 2007, 02:46:57 PM

Previous topic - Next topic

jukingeo

Hello all, 

OK, so itwas already established that the Prop-2 cannot multitask and that is mostly a job for the SX.  However, for triggering flashing lights or chase effects, I am sure there are ways to 'fake it'.  What I would like to do is see all 16 outputs to appear to flash at different rates semi-independently.  (Ok, lets keep it simple and just use 6 for now being that right now I am only using the output LEDS of the Prop-1 Trainer).  Using a good  example, what if I wanted to flash the first 3 LED's in a standard chase three pattern, have the next LED appear to flash slowly on and off.  Finally the last pair of LED would alternately flash (like a railroad crossing sign)?   I thinking that this would be possible because I know that in the discreet digital world you can divide flash rates down in the real world using a single 555 and few 4017 ic's.  This really isn't multitasking either and I would be hoping that the Prop-2 could handle something like this.  The decerning eye may pick up that the program is running on one and the same clock or in the case of the Prop-2 the same main loop.  However, if lights on a prop are mounted in serveral different places, the pattern may not be so easy to pick up on.

I was even thinking perhaps even the random function could be used here as well to randomly trigger some of the non-chaser outputs on & off.

I remember back in the day that I used to program in Basic on Commodore PET computers and you could do something called 'nesting' loops and I wonder if that is something that would be called for here.

Again, let me know what can (or can't) be done.


Thanx,

Geo

JonnyMac

September 16, 2007, 04:06:19 PM #1 Last Edit: September 16, 2007, 04:20:08 PM by JonnyMac
Don't get too wrapped around the axle about what you believe the Prop-2 (BS2) can't do -- in 13 years of programming BASIC Stamp microcontrollers I've shown a lot of naysayers things the were sure the BASIC Stamp couldn't do.

Here's a program to play with; it uses RANDOM to flash the LEDs -- note that the duty cycle is also random.

' =========================================================================
'
'   File...... Random_Flashing.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Speed           PIN     15                      ' SETUP = DN, no ULN
PatSelect       PIN     14                      ' SETUP = DN
Leds            VAR     OUTH


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


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

idx             VAR     Nib
lottery         VAR     Word                    ' random value
delay           VAR     Word


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

Reset:
  DIRH = %00111111                              ' make LEDs outputs


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

Main:
  FOR idx = 1 TO 3
    RANDOM lottery                              ' stir random value
  NEXT

  Leds = lottery & %00111111

Speed_Delay:
  HIGH Speed                                    ' charge RC circuit
  PAUSE 1
  RCTIME Speed, 1, delay                        ' read raw delay
  delay = delay / 3 + 50                        ' set new range
  PAUSE delay                                   ' hold a bit
  GOTO Main


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


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

JonnyMac

Here's another program to play with.  This contains the mechanisms that most "mutli-tasking" programs use: individual timers for each process (in this case, LED).  In this program each LED flashes at an individual rate (controlled by constants) and with a 50% duty cycle (on time and off time are equal).

' =========================================================================
'
'   File...... Multi_Leds.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Led6            PIN     13
Led5            PIN     12
Led4            PIN     11
Led3            PIN     10
Led2            PIN     9
Led1            PIN     8


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

Speed           CON     10

Rate1           CON     10
Rate2           CON     65
Rate3           CON     33
Rate4           CON     150
Rate5           CON     100
Rate6           CON     80


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

tmr1            VAR     Byte
tmr2            VAR     Byte
tmr3            VAR     Byte
tmr4            VAR     Byte
tmr5            VAR     Byte
tmr6            VAR     Byte


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

Reset:
  DIRH = %00111111                              ' make LEDs outputs


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

Main:
  tmr1 = tmr1 + 1                               ' update timer
  IF tmr1 = Rate1 THEN                          ' time to change state?
    Led1 = Led1 ^ 1                             ' yes, do it
    tmr1 = 0                                    ' and reset timer
  ENDIF

  tmr2 = tmr2 + 1
  IF tmr2 = Rate2 THEN
    Led2 = Led2 ^ 1
    tmr2 = 0
  ENDIF

  tmr3 = tmr3 + 1
  IF tmr3 = Rate3 THEN
    Led3 = Led3 ^ 1
    tmr3 = 0
  ENDIF

  tmr4 = tmr4 + 1
  IF tmr4 = Rate4 THEN
    Led4 = Led4 ^ 1
    tmr4 = 0
  ENDIF

  tmr5 = tmr5 + 1
  IF tmr5 = Rate5 THEN
    Led5 = Led5 ^ 1
    tmr5 = 0
  ENDIF

  tmr6 = tmr6 + 1
  IF tmr6 = Rate6 THEN
    Led6 = Led6 ^ 1
    tmr6 = 0
  ENDIF

  PAUSE Speed
  GOTO Main


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


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

jukingeo

Hello Jon,

You did it again!  Yes, this is very close to what I was looking for.

Now would I be shooting for the moon if I wanted to have 3 LEDs flash like this and have the other 3LEDs on a standard chase pattern?

If that is a 'Yes', then the Prop 2 would certainly handle my Delorean project.

But even so, this is great for any kind of computer panel project in which you want to create a display that has randomly blinking lights.

Now I am going to see what I can alter with this program :).

Thanx for your help it is much appreciated.

jukingeo

Hello Jon,

I played around with your program here some more and I came up with this (I copied the central part that contained the alterations I did).

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

Speed           CON     10

Rate1           CON     5
Rate2           CON     10
Rate3           CON     33
Rate4           CON     100
Rate5           CON     75
Rate6           CON     20


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

tmr1            VAR     Byte
tmr2            VAR     Byte
tmr3            VAR     Byte
tmr4            VAR     Byte
tmr5            VAR     Byte
tmr6            VAR     Byte


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

Reset:
  DIRH = %00111111                              ' make LEDs outputs


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

Main:
  tmr1 = tmr1 + 1                               ' update timer
  IF tmr1 = Rate1 THEN                          ' time to change state?
    Led1 = Led1 ^ 1
    Led2 = Led2 ^ 0
    PAUSE 200
    Led1 = Led1 ^ 0
    Led2 = Led2 ^ 1
    PAUSE 10                             ' yes, do it
    tmr1 = 0                                    ' and reset timer
  ENDIF

'  tmr2 = tmr2 + 1
'  IF tmr2 = Rate2 THEN
'    Led2 = Led2 ^ 1
'    tmr2 = 0
'  ENDIF

  tmr3 = tmr3 + 1
  IF tmr3 = Rate3 THEN
    Led3 = Led3 ^ 1
    tmr3 = 0
  ENDIF

What I did is disable the 2nd LED timer and asked the first timer to 'flip flop' the LEDs 1 & 2.  It isn't elegant and isn't fully as I wanted, but it does appear as if the first two LED's flip flop and the rest are doing their 'random' thing.

So that pretty much says that if I can get two LEDs to flip flop, than I could very well get a small chaser going with the 'random' LED's at the SAME time on the SAME Prop-2 board.   Thus 'faking' multi-tasking.  So this is a REAL good thing.

Geo


JonnyMac

Notes:

1. Using PAUSE in the middle of that loop defeats the purpose of the program design; the delay between bit flips is caused by counting to the "rate" specification, and a PAUSE in one counter section throws off the whole works, including the other LEDs.  You are actually breaking the faux multi-tasking process.

2. You cannot flip a bit with ^ 0 -- This does not change the bit; you must use ^ 1 to flip the bit.  If you want Led2 to follow Led1 then do this:

Main:
  tmr1 = tmr1 + 1       
  IF tmr1 = Rate1 THEN 
    Led1 = Led1 ^ 1
    Led2 = Led1
    tmr1 = 0
  ENDIF


If what you're after is asymmetric blinking (duty cycle is other than 50%), then you need to have two rate constants; one for the on-time, one for the off-time.  You would process them like this:

Main:
  tmr1 = tmr1 + 1
  IF Led1 = IsOn THEN
    IF tmr1 = Rate1On THEN
      Led1 = Led1 ^ 1
      tmr1 = 0
    ENDIF
  ELSE
    IF tmr1 = Rate1Off THEN
      Led1 = Led1 ^ 1
      tmr1 = 0
    ENDIF
  ENDIF


Here's how you would do a chaser on three LEDs (P0-P2) with random output on three others (P3-P5):

' =========================================================================
'
'   File...... Chase_Plus.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Speed           PIN     15                      ' SETUP = DN, no ULN
Leds            VAR     OUTH


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

IsOn            CON     1
IsOff           CON     0


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

pntr            VAR     Byte
idx             VAR     Byte
lottery         VAR     Word
delay           VAR     Word


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

Reset:
  DIRH  = %00111111                             ' make LEDs outputs


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

Main:
  READ (Chase + pntr), LEDs                     ' output fixed pattern
  pntr = pntr + 1 // 3                          ' update pointer

  FOR idx = 1 TO 3
    RANDOM lottery                              ' stir random value
  NEXT

  LEDs = LEDs | (lottery & %111000)             ' three random bits

Speed_Delay:
  HIGH Speed                                    ' charge RC circuit
  PAUSE 1
  RCTIME Speed, 1, delay                        ' read raw delay
  delay = delay / 3 + 50                        ' set new range
  PAUSE delay                                   ' hold a bit
  GOTO Main


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


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

Chase           DATA    %000001
                DATA    %000010
                DATA    %000100
                DATA    %001000
                DATA    %010000
                DATA    %100000


Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

Here's an even better version that looks more like multi-tasking.  This version changes the random LEDs (P3-P5) every cycle, but updates the chase pattern every Nth cycle (N is controlled by the variable "chaseTmr").  The result is quick random LEDs with a slow(er) chase pattern.

This is why I suggested (perhaps in another post) not to get wrapped around the axle on the idea of multi-tasking -- and don't assume that you need it.  Of the microcontrollers in use in the world today, over 95% of them DON'T have interrupts or do "multi-tasking"; most run tight loops with embedded schedulers (timers) to control various processes -- we can do that on the BASIC Stamp, too.

' =========================================================================
'
'   File...... Chase_Plus_v2.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Speed           PIN     15                      ' SETUP = DN, no ULN
Leds            VAR     OUTH


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

IsOn            CON     1
IsOff           CON     0


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

chaseTmr        VAR     Byte                    ' cycles divider
pntr            VAR     Byte                    ' pattern pointer
tLeds           VAR     Byte                    ' holder for LEDs pattern
idx             VAR     Byte                    ' loop controller
lottery         VAR     Word                    ' random value
delay           VAR     Word                    ' for timing


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

Reset:
  DIRH  = %00111111                             ' make LEDs outputs


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

Main:
  chaseTmr = chaseTmr + 1                       ' increment timer
  IF chaseTmr = 3 THEN                          ' time for new pattern
    READ (Chase + pntr), tLeds                  ' yes, read pattern
    LEDs = (LEDs & %111000) | tLeds             ' put on leds (protect others)
    pntr = pntr + 1 // 3                        ' update pattern pointer
    chaseTmr = 0                                ' reset timer
  ENDIF

  FOR idx = 1 TO 3
    RANDOM lottery                              ' stir random value
  NEXT

  LEDs = LEDs & %000111                         ' clear old random leds
  LEDS = LEDS | (lottery & %111000)             ' new random leds

Speed_Delay:
  HIGH Speed                                    ' charge RC circuit
  PAUSE 1
  RCTIME Speed, 1, delay                        ' read raw delay
  delay = delay / 4 + 25                        ' set new range
  PAUSE delay                                   ' hold a bit
  GOTO Main


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


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

Chase           DATA    %000001
                DATA    %000010
                DATA    %000100
                DATA    %001000
                DATA    %010000
                DATA    %100000


Jon McPhalen
EFX-TEK Hollywood Office

jukingeo

Quote from: JonnyMac on September 17, 2007, 08:01:04 AM
Notes:

1. Using PAUSE in the middle of that loop defeats the purpose of the program design; the delay between bit flips is caused by counting to the "rate" specification, and a PAUSE in one counter section throws off the whole works, including the other LEDs.  You are actually breaking the faux multi-tasking process.

2. You cannot flip a bit with ^ 0 -- This does not change the bit; you must use ^ 1 to flip the bit.  If you want Led2 to follow Led1 then do this:

Main:
  tmr1 = tmr1 + 1       
  IF tmr1 = Rate1 THEN 
    Led1 = Led1 ^ 1
    Led2 = Led1
    tmr1 = 0
  ENDIF


If what you're after is asymmetric blinking (duty cycle is other than 50%), then you need to have two rate constants; one for the on-time, one for the off-time.  You would process them like this:

Main:
  tmr1 = tmr1 + 1
  IF Led1 = IsOn THEN
    IF tmr1 = Rate1On THEN
      Led1 = Led1 ^ 1
      tmr1 = 0
    ENDIF
  ELSE
    IF tmr1 = Rate1Off THEN
      Led1 = Led1 ^ 1
      tmr1 = 0
    ENDIF
  ENDIF


Here's how you would do a chaser on three LEDs (P0-P2) with random output on three others (P3-P5):



Hello Jon,

Like I said...I am just putzing around...I am really just guessing, taking a stab at it so to speak.  Anyway, I replaced the first timer with the one you wrote above.  However, both LED's flash at the same time.  I was looking for an alternating flash.  The 50% duty cycle is fine.

Main:
  tmr1 = tmr1 + 1       
  IF tmr1 = Rate1 THEN
    Led1 = Led1 ^ 1
    Led2 = Led1
    tmr1 = 0
  ENDIF

I would guess that something would have to be done with the "LED 2" line, correct?  Basically if LED 1 is on, LED 2 is off and then it flip flops.

However, it does seem that going with the new chaser/random program you created does answer the question that you could chase AND still have the random flashing LED's.  I am sure that for the situation I mentioned above that a simple "Chase 2" program would give the alternating LED effect.  I am sure that I could also go the other direction and expand this to include more chase channels and more random channels.

Both of these last two programs do in fact prove the fact that you can 'fake' the multi-tasking and because of this realization. I know I can do much more with the Prop -2 than I initially anticipated.

The last program is pretty much what I was looking for except I would rather see a fast chase and a slower random flashing from the other LED's.  However, this program seems the most 'cryptic' to me.  So I have much to read up on here.

But all in all this is great.  I know I can do a couple (or a few) different lighting displays running from one Prop-2.

Thanx,

Geo



JonnyMac

If you want Led2 to be in opposition to Led1 you can do this:

  Led2 = Led1 ^ 1

Now Led1 and Led2 will always alternate at the same rate.

Here's an update to the program that runs the chaser (I changed to zig-zag) every cycle, and updates the random bits every Nth cycle, as controlled by the variable called "rndTimer."

' =========================================================================
'
'   File...... Chase_Plus_v3.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Speed           PIN     15                      ' SETUP = DN, no ULN
Leds            VAR     OUTH


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

IsOn            CON     1
IsOff           CON     0


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

pntr            VAR     Byte                    ' pattern pointer
tLeds           VAR     Byte                    ' holder for LEDs pattern
idx             VAR     Byte                    ' loop controller
rndTimer        VAR     Byte                    ' "clock" divider
lottery         VAR     Word                    ' random value
delay           VAR     Word                    ' for timing


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

Reset:
  DIRH  = %00111111                             ' make LEDs outputs


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

Main:
  READ (ZigZag + pntr), tLeds                   ' yes, read pattern
  LEDs = (LEDs & %111000) | tLeds               ' put on leds (protect others)
  pntr = pntr + 1 // 4                          ' update pattern pointer

  FOR idx = 1 TO 3
    RANDOM lottery                              ' stir random value
  NEXT

  rndTimer = rndTimer + 1                       ' update timer
  IF rndTimer = 5 THEN                          ' ready for new pattern?
    LEDs = LEDs & %000111                       ' clear old random leds
    LEDS = LEDS | (lottery & %111000)           ' new random leds
    rndTimer = 0                                ' reset timer
  ENDIF

Speed_Delay:
  HIGH Speed                                    ' charge RC circuit
  PAUSE 1
  RCTIME Speed, 1, delay                        ' read raw delay
  delay = delay / 3 + 50                        ' set new range
  PAUSE delay                                   ' hold a bit
  GOTO Main


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


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

ZigZag          DATA    %000001
                DATA    %000010
                DATA    %000100
                DATA    %000010
Jon McPhalen
EFX-TEK Hollywood Office

jukingeo

Hello Jon,

This is it!  This is what I was looking for.  Well, almost, but I was able to change the zig zag to represent the 3 channel chase of the "Flux Capacitor" the remaining LED's flash randomly and slowly for other panel button effects (for the Delorean project).

So that proves it and this is EXACTLY what I was first trying to say when when we first spoke in those emails.  Back then I was asking if the Prop 2 could do this function without having to go to the SX or a 'fancy' lighting controller.  So this (and the previous programs) is a resounding "Yes".

I already futzed around with this program and found out what I have to do to alter it in case I want more chase channels vs random channels.  So I was able to do my flip flop routine as well and add a 4th random channel.

This one program alone I will have MANY uses for.

You did get me off to a good start though and between your programs and my further research I should be good for now.  I probably will come back after Halloween when things have 'simmered down' here.

Thanx again for all your help.  I will do some heavy reading now.

Geo