November 22, 2024, 10:52:20 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.


FOR - NEXT newbie problems

Started by MontroseHaunt, October 11, 2008, 10:43:52 AM

Previous topic - Next topic

MontroseHaunt

I am trying to shorten my code by using a variable FOR - NEXT loop instead of repeating the code multiple times. I'm also trying to randomize the number of loops inside the FOR - NEXT as well... I'm sure it's some stupid newbie thing, and I know I can make this work with lots of code... but I'd love to have it working in a cleaner fashion. Any help would be greatly appreciated!!

Here is the program code:

' =========================================================================
'
' File....... Trash Can Scare.BS1
' Purpose.... Trash Can jumps up
' Started.... 11 Oct 2008
' Updated....
'
' {$STAMP BS1}
' {$PBASIC 1.0}
'
' =========================================================================
' -----[ I/O Definitions ]-------------------------------------------------

' -----[ Constants ]-------------------------------------------------------
SYMBOL TrashCan = 0            ' Trash Can pneumatic on OUT1

' -----[ Variables ]-------------------------------------------------------
SYMBOL timer = W1              ' Timer value
SYMBOL delay = W2              ' Delay value
SYMBOL randomNum = B1          ' Used for random number generation
SYMBOL pinNum = B2             ' Pin number being used
SYMBOL jumpCnt = B3            ' Control number of times the Trash Can jumps
SYMBOL cycles = B4             ' Used for looping control

' -----[ Initialization ]--------------------------------------------------
Reset:

' -----[ Program Code ]----------------------------------------------------
Main:
   RANDOM timer                 ' Stir random generator

' Randomly pick a Trash Can to activate
'   RANDOM randomNum                 ' Stir random generator
'   pinNum = randomNum // 4 + 1      ' Pick a Trash Can pin (One of 4 Trash Cans)

' Randomly pick number of times the lucky Trash Can will jump
    RANDOM randomNum                  ' Stir random generator
    jumpCnt = randomNum // 3 + 5      ' Trash Can should jump 5 to 8 times
  DEBUG "Jump Count = "
  DEBUG jumpCnt

' Loop Control
    FOR cycles = 1 TO 8

  DEBUG "Inside For/Next = ", cycles

    ' Make Trash Can Jump
       HIGH TrashCan                  ' Push piston under Trash Can
       PAUSE 5                        ' Allow time for solenoid to power up
       LOW TrashCan                   ' Retract piston under Trash Can

    ' Random Delay
       RANDOM timer                   ' Stir random generator
       delay = timer // 10 + 5        ' Create delay from .5 to 1.5 seconds
       delay = delay * 100            ' Convert to Milliseconds
  DEBUG "Delay = ", delay
       PAUSE delay                    ' hold for a random delay

  DEBUG "End of For/Next"

    NEXT

    ' Randomized Delay between Trash Can activations
    '  RANDOM timer                 ' Stir random generator
    '  delay = timer // 60 + 30     ' Create delay from 30 TO 60 seconds
    '  delay = delay * 1000         ' Convert to Milliseconds
    '  PAUSE delay                  ' hold for a random delay

DEBUG "GOTO Main"

    GOTO Main

=======================

Here is he debug results after letting it go through a few times:

Jump Count = JUMPCNT = 7
Inside For/Next = CYCLES = 1
Delay = DELAY = 1400
End of For/Next
GOTO Main

Jump Count = JUMPCNT = 7
Inside For/Next = CYCLES = 1
Delay = DELAY = 1200
End of For/Next
GOTO Main

Jump Count = JUMPCNT = 7
Inside For/Next = CYCLES = 1
Delay = DELAY = 1300
End of For/Next
GOTO Main

JonnyMac

While you could use FOR-NEXT I think it's best to handle random-length loops manually -- this saves a varaiable (which can at times be critical).  Handling the loop manual is really simple and only adds one line of code over FOR-NEXT.

This is my randomized version of the program above:

' =========================================================================
'
'   File...... Jumping_Trashcan.BS1
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2008 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

SYMBOL  TrashCan        = PIN0                  ' use V+/OUT0


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

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

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  jumps           = B2

SYMBOL  timer           = W4
SYMBOL  lottery         = W5


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

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000001                              ' set outputs


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

Main:
  RANDOM lottery                                ' stir random #
  jumps = lottery // 8 + 1                      ' 1 to 8 jumps

Jump_Baby:
  IF jumps = 0 THEN Rest
  TrashCan = IsOn                               ' pulse cylinder
  PAUSE 5
  TrashCan = IsOff
  RANDOM lottery                                ' restir
  timer = lottery // 1001 + 500                 ' 500 to 1500 ms
  PAUSE timer
  jumps = jumps - 1                             ' update jump count
  GOTO Jump_Baby

Rest:
  RANDOM lottery                                ' restir
  timer = lottery // 30001 + 30000              ' 30 to 60 seconds
  PAUSE timer

  GOTO Main


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


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


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

MontroseHaunt

Jon,

Thanks for the quick reply!!!  :)

I will replace the code with your example. Thanks!! But it really bothers my why the FOR - NEXT loop didn't seem to work. It just dropped right out of the loop instead of looping. Do you know why it would have done that? It's really bugging me...

Part II of my question is that we would now "like" to use the same PROP-1 controller to bounce 4 or 5 cans around the front of haunt. We'd like to have the cans all jumping randomly, and don't want one can waiting on another. This isn't my idea, but what the owner wants. I think this will end up being very complicated code, and we should either use multiple PROP-1 controllers or be OK with the idea that we're only going to be able to control one can at a time.

What do you think? If you think we can randomly make multiple cans jump around randomly, can you publish an example program?

Thanks!!!
Chris

JonnyMac

The reason FOR-NEXT isn't working as you expect in your original program is that variable assignments are clobbering each other -- this is one of the traps using the BS1 processor.  One has to remember that B0 and B1 occupy the same space as W0, B2 and B3 occupy the same space as W1, etc.  In this program pinNum (B2) and jumpCnt (B3) occupy the same physical memory location as delay (W1) so these variables can clobber each other.   

When assigning variables my habit is to assign bytes (Bx vars) from B2 (B0 if I need) more and go up, and words (Wx) from W5 and go down -- this minimizes location conflicts.  Of course, there are times when the overlay is beneficial and in those cases you would program for it.

You don't have enough memory in the Prop-1 for "four or five" independent cans.  And when you want multiple items to behave independently within the same controller the programming gets very tricky (state machine).  Let me see what I can come up with -- please don't expect too much from a $39 controller.
Jon McPhalen
EFX-TEK Hollywood Office

MontroseHaunt

Again, thanks for the quick reply!! We've been cranking out different applications for these PROP-1's all day now...

I'm sure the memory pointer information for the variables are documented somewhere, but I have yet to trip across it obviously!!

Anything you can come up with on controlling multiple cans would be great, but don't kill your self. I may just control them in serial now that I understand the FOR-NEXT a bit better.

Thanks!!

JonnyMac

Too late, already killed myself.  ;D  No kidding, this program was a bear.

I managed to fit three cans into the code, but just barely.  Programming purists love to call this "spaghetti code" because of the way things are intertwined.  It can be tough to follow.  That said, the codes for cans 2 and 3 are duplicates of what's running for can 1. 

' =========================================================================
'
'   File...... Jumping_Trashcans_X3.BS1
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2008 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated... 11 OCT 2008
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

SYMBOL  TrashCan3       = PIN2                  ' use V+/OUT2
SYMBOL  TrashCan2       = PIN1                  ' use V+/OUT1
SYMBOL  TrashCan1       = PIN0                  ' use V+/OUT0


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

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

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  Jumping         = 1
SYMBOL  Resting         = 0


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

SYMBOL  status          = B0
SYMBOL   can1           = BIT0                  ' 1 = jumping, 0 = rest
SYMBOL   can2           = BIT1
SYMBOL   can3           = BIT2

SYMBOL  jumps1          = B1
SYMBOL  jumps2          = B2
SYMBOL  jumps3          = B3

SYMBOL  timer1          = W2
SYMBOL  timer2          = W3
SYMBOL  timer3          = W4

SYMBOL  lottery         = W5                    ' random #


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

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000111                              ' set outputs

  ' timers must be preloaded > 0!

  timer1 = 1
  timer2 = 10                                   ' 1 sec initial offset
  timer3 = 50                                   ' 5 sec initial offset


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

Main:
  RANDOM lottery                                ' stir random #
  PAUSE 100                                     ' timing in 0.1s units


' ----------------
' Can 1 Processing
' ----------------
'
Check_Timer1:
  RANDOM lottery                                ' re-stir
  timer1 = timer1 - 1                           ' update timer
  IF timer1 > 0 THEN Check_Timer2               ' abort if still running

Check_Can1_State:
  IF can1 = Resting THEN Can1_Jump_Setup

Can1_Is_Jumping:
  IF TrashCan1 = IsOn THEN Update_Jumps1

Can1_Jump_Now:
  TrashCan1 = IsOn
  timer1 = 1                                    ' jump time = 0.1s
  GOTO Check_Timer2

Update_Jumps1:
  jumps1 = jumps1 - 1
  IF jumps1 = 0 THEN Can1_Rest_Setup

Can1_Jump_Delay:
  TrashCan1 = IsOff
  timer1 = lottery // 11 + 5                    ' jump delay - 0.5s to 1.5s
  GOTO Check_Timer2

Can1_Rest_Setup:
  TrashCan1 = IsOff
  timer1 = lottery // 301 + 300                 ' can rest = 30s to 60s
  can1 = Resting
  GOTO Check_Timer2

Can1_Jump_Setup:
  jumps1 = lottery // 8 + 1                     ' 1 to 8 jumps
  TrashCan1 = IsOn
  timer1 = 1
  can1 = Jumping


' ----------------
' Can 2 Processing
' ----------------
'
Check_Timer2:
  RANDOM lottery
  timer2 = timer2 - 1
  IF timer2 > 0 THEN Check_Timer3

Check_Can2_State:
  IF can2 = Resting THEN Can2_Jump_Setup

Can2_Is_Jumping:
  IF TrashCan2 = IsOn THEN Update_Jumps2

Can2_Jump_Now:
  TrashCan2 = IsOn
  timer2 = 1
  GOTO Check_Timer3

Update_Jumps2:
  jumps2 = jumps2 - 1
  IF jumps2 = 0 THEN Can2_Rest_Setup

Can2_Jump_Delay:
  TrashCan2 = IsOff
  timer2 = lottery // 11 + 5
  GOTO Check_Timer3

Can2_Rest_Setup:
  TrashCan2 = IsOff
  timer2 = lottery // 301 + 300
  can2 = Resting
  GOTO Check_Timer3

Can2_Jump_Setup:
  jumps2 = lottery // 8 + 1
  TrashCan2 = IsOn
  timer2 = 1
  can2 = Jumping


' ----------------
' Can 3 Processing
' ----------------
'
Check_Timer3:
  RANDOM lottery
  timer3 = timer3 - 1
  IF timer3 > 0 THEN Main

Check_Can3_State:
  IF can3 = Resting THEN Can3_Jump_Setup

Can3_Is_Jumping:
  IF TrashCan3 = IsOn THEN Update_Jumps3

Can3_Jump_Now:
  TrashCan3 = IsOn
  timer3 = 1
  GOTO Main

Update_Jumps3:
  jumps3 = jumps3 - 1
  IF jumps3 = 0 THEN Can3_Rest_Setup

Can3_Jump_Delay:
  TrashCan3 = IsOff
  timer3 = lottery // 11 + 5
  GOTO Main

Can3_Rest_Setup:
  TrashCan3 = IsOff
  timer3 = lottery // 301 + 300
  can3 = Resting
  GOTO Main

Can3_Jump_Setup:
  jumps3 = lottery // 8 + 1
  TrashCan3 = IsOn
  timer3 = 1
  can3 = Jumping
  GOTO Main


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


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

MontroseHaunt