November 21, 2024, 03:23:03 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.


HALO themed cake - FINISHED

Started by Nannuu, June 09, 2007, 09:51:30 PM

Previous topic - Next topic

Nannuu

June 09, 2007, 09:51:30 PM Last Edit: July 17, 2007, 09:10:59 AM by Nannuu
Although I've had my prop-1 in the closet for 6 months this is my first project (and I'm starting last minute as usual).  I have 3 standard servos and 3 continuous servos (had no idea what the diff was when I bought them).  What I want my program to do is to randomly move the first 3 servos.  The second 3 I want to move/stop/move/stop etc for random times and speeds (direction is not important).  I think my program will randomly move the standard servos and start/stop the continuous ones?  I've used Vern Graner's random program as a start.  The last programming I've did was uh....too long ago so excuse whatever rule breaking I've done.
While writing this I just noticed I totally screwed my variables by using W1-W6 (over B2-B13).  DOH!!!!  I'm not allowed to do that am I?  If not is there any way I can re-write this to work on the Prop-1.

The end result I want is that 3 randomly always move, the other 3 move for a time, stop for a time etc.  I was going for random times of everything but it doesn't look like that can happen.
It seems like I might have to settle for random movement shared between 3 or the times stop/start can be shared or something.  Any suggestions would be great.

Thanks,
Will


EDIT:
REMOVED USELESS CODE

Nannuu

Ok, now that I'm thinking of ways to fix this.  Instead of using a word for my stop/start time.  Can I increment this somehow with a byte?  Since the program is pausing 20 ms for each loop I can run the random RESULT and divide to get a value between 0-255.  In my timing loop just increment + or - 1 which really increments 20 ms plus the program runtime (if that is even gaged in ms).  So the most pause I could have would be 255*20=5100 ms which is 5 seconds?  That would cut my words down 1 (RESULT).  And my bytes to B2 to B16.  Not enough.  So I can re-write so that the start/stop times are the same for each servo using B2-B13.  The sheet I have says that B12 and B13 are used as a stack for GOSUB-RETURN.  What is that?  Does that mean I can't use B12 and B13 this way?

Or maybe better is to have 3 times (as bytes), TIME1, TIME2 and TIME3.  Could that be written to mix match between the 3 servos for start/stops?
Servo 1:
Go for TIME1
Stop for TIME2

Servo 2:
Go for TIME2
Stop for TIME3

Servo 3:
Go for TIME3
Stop for TIME1
That way they seem more random.

Nannuu

I just realized I don't have a serial cable to program my board for testing.  Doh, will have to wait until tomorrow.  I have a question though.  If I add a PAUSE command in a loop or IF/THEN, does the entire program sit idle for that time or does it continue and just jump over that loop for the specified PAUSE time?

JonnyMac

PAUSE stops the entire program in its tracks -- the Prop-1 is single threaded and simple at that.  To be honest, your project may be a bit too ambitious for the small memory and code footprint of the Prop-1.  Vern's random servo program took a bit of work.  I'll get out Vern's code in the morning (okay, later in the morning, it's now coming on 2 AM and I'm tired...) and see if I can make it work per your description.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

Quote from: JonnyMac on June 10, 2007, 02:41:32 AM
PAUSE stops the entire program in its tracks -- the Prop-1 is single threaded and simple at that.  To be honest, your project may be a bit too ambitious for the small memory and code footprint of the Prop-1.  Vern's random servo program took a bit of work.  I'll get out Vern's code in the morning (okay, later in the morning, it's now coming on 2 AM and I'm tired...) and see if I can make it work per your description.
Thanks, ok so PAUSE won't work.  I'm been thinking about it some more.  I don't think I NEED the continuous servos to be random all over.  If I just slap a different number (1-255) into the direction for each and decide on a time to wait I can remove all of those variables.  Let me give it a try before you mess with it.  I don't need to waste your time if I can get it working.  I'll post my new code for review if I think I have it or at least close.
I don't understand the DIRS function either, is there a way to use that for this application?  I work until midnight so maybe I'll get some time at dinner to read up on some other functions.

JonnyMac

There is a programming strategy that *may* let you get to what you want without using PAUSE -- but this is tricky because what you really end up doing is writing a simple multii-tasking program and this can be tough for new programmers to follow.  You're right, though, in that when you're using servos you should never have a PAUSE greater than 20 minus 1.5 times the number of servos.  If you have 6 servos, then, your PAUSE should never be greater than 10 or so, otherwise the refresh delay between servos is too long.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

If I have a loop that skips a servo, would that stop the servo?  I don't have to send a signal to stop a servo right?  In another post about continuous servos you write that a signal of 150 stops the servo, is that necessary?

JonnyMac

You should update the servo every 20 ms, even if it is not moving.  C/R servos will stop moving when the "centering" signal (for a normal servo) is received.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

How is the speed of a servo controlled?  Is a signal of 10 going to be any different than 140 to a continuous rotation servo?  Or do those value just send a signal of move clockwise?  (ie: over 150 is CCW)
I'm guessing that speed is controlled by the time between pulses?

I'm stuck on how to get the continuous servos to stop for any amount of time and then start again.  I can get them to stop no problem but starting again.....ugh.  I was kind of hoping I could just increment the pulse signal up and down somehow so that they slow down at either end of the loop but I don't think that's happening either.  It's fun trying though.  I'm poop at programming, I keep drawing circles around and around my loops I just wrote trying to figure out what I was just thinking  ???

Would my original program work on a Prop-2 (assuming I revised my variables so they didn't lap)?  How many bits/bytes/words can a Prop-2 support?

JonnyMac

June 10, 2007, 10:01:39 PM #9 Last Edit: June 10, 2007, 10:13:53 PM by JonnyMac
You can get *some* degree of speed control, but it's not predictable and not at all linear.  A Parallax engineer did tests a few years ago and concluded that you should just run C/R servos full speed or stop them; when you attempt to run them slowly (near the 150 point) they draw a lot of current.  A company called Pololu makes a small DC motor controller than might be better for your application -- it is compatible with the Prop-1.

I played a bit with your ideas today and the biggest hurdle with the Prop-1 is variable space; you really need three bytes per servo and there's not enough in the Prop-1 for that.  You have nearly twice the space with a Prop-2 and a few programming niceties with PBASIC 2.5 that might make the task a little easier.  That doesn't change the issue of speed control with C/R servos, though; it will always be limited.  The C/R servo is a hack of a standard servo which wants to go from point A to point B as quickly as possible.

And remember... programming is just a skill.  It's not magic, it's not impossible, it can be mastered by you and anyone else who chooses to master it.  If you can design and build that entertainment center that I saw on your web site you can learn to program our prop controller.  I promise -- just like the entertainment center, a program starts with a plan and gets built one piece at a time.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

I thought I'd post a picture of what the C/R servo is planned for.  If I can't stop the servo in a loop then I think I'll come up with a different application for it.  I have plenty of motors that can just move the guy back and forth and never stop so I feel like I'm wasting my Prop controller using it for just that.

Now that I think of it, I do have two EL wires I want to control as well.  One wire I want to flash on every 15 seconds or so.  And the other I want to do multiple flashes every 25 seconds or so.  I was planning to do these mechanically through a nice hokey motor closing a circuit on each round but I'll bet the Prop can do it better.  The EL wire runs off of 12VDC so that matches my power supply I got from EFX for the Prop-1.  Am I going to run into the same problem flashing the EL wire at some set intervals while running the 3 random servos?

Also, I got the Parallax standard servos which say they take 6VDC max, do I need to only hook up a 6VDC power supply to my Prop-1 then?  Meaning I can't run 12VDC stuff?

If you look in the cake section of my website you'll see that my wife and I make animated cakes for our children.  I volunteered to make a Halo inspired cake for a friend's son and I really want to do a nice job, thus the Prop-1.  I'd originally bought it for the Halloween cake but just ran out of time during planning and making yard Halloween decorations  :-[.

JonnyMac

For the mechanism you picture you should NOT use a C/R servo; if you have a programming mistake and the servo rotates too far you'll damage the rig, the servo, or both.  If you must use the C/R servo in that application, extend the servo shaft straight up to the character so that there is no possibility of binding.

Servos are designed for 5v but can run from 6; if you connect them to the Prop-1 TTL output headers they will get 5v and you'll be fine.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

Ok, I'm back on it.  Had to take a few days off to finish a Halo sword for my nephew.
I now have my final design and I will be using only the 3 standard servos and 4 LEDs.  The 3 standard servos will still run the random motion.  The 4 LEDs I want to light all at the same time and keep lit for about 1 second, I want this to happen every 10 seconds or so (not too picky of exact times).
Will this code do what I want?


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

'------------------------------------------------------
' Halo Cake
' By Will Turnbow 6-21-07
' Revised version of Vern Graner's HEX Servo Random Movement Generator
'------------------------------------------------------
' Hardware setup:
' Servos connected to pins 0-2
' LEDs connected to pins 3-6


'Declare Variables
'------------------------------------------------------
SYMBOL    RESULT = W0  ' value can be 0 to 65535 (used for servo destinations)
SYMBOL   BaseOFF = W4  ' value can be 0 to 65535, used for timing between base lighting
SYMBOL    BaseON = W5  ' value can be 0 to 65535, used to hold base lights on
'STANDARD SERVOS:
SYMBOL CLEARDEST = B2  ' value can be 0 to 255 destination
SYMBOL  CLEARCUR = B3  ' value can be 0 to 255 current location
SYMBOL   REDDEST = B4  ' value can be 0 to 255 destination
SYMBOL    REDCUR = B5  ' value can be 0 to 255 current location
SYMBOL GREENDEST = B6  ' value can be 0 to 255 destination
SYMBOL  GREENCUR = B7  ' value can be 0 to 255 current location

'Pre set values in variables
'------------------------------------------------------
RESULT      = 11010   ' set initial "seed" value
'CLEARDEST  = 50      ' Set all current and destination values to match
'CLEARCUR   = 50      ' to force the cur=dest routines to generate a random
'REDDEST    = 50      ' destination for all servos on first pass
'REDCUR     = 50
'GREENDEST  = 50
'GREENCUR   = 50
BaseOFF    = 10000
BaseON     = 800
'------------------------------------------------------

'Main loop begin
LOOP:

IF CLEARDEST=CLEARCUR THEN FetchCLEARDest   'If the servo has reached it's destination fetch a new one
  GOTO NextTest1                   ' if not, skip to next test
FetchCLEARDest:
  RANDOM RESULT                    'Use RANDOM to find a new destination
  RESULT=RESULT // 256             'modulus to return remainder of division (0-255)
  CLEARDEST=RESULT                 'Stuff the new destination into DEST variable
  CLEARDEST=CLEARDEST MIN 50       'Set limits so servos do not exceed positional
  CLEARDEST=CLEARDEST MAX 200       requiremenmts
'  DEBUG "CLEARCUR=",#CLEARDEST,"CLEARDEST=",#CLEARDEST,CR
NextTest1:

IF REDDEST=REDDEST THEN FetchREDDest
  GOTO NextTest2:
FetchREDDest:
  RANDOM RESULT
  RESULT=RESULT // 256
  REDDEST=RESULT
  REDDEST=REDDEST MIN 50
  REDDEST=REDDEST MAX 200
'  DEBUG "REDCUR=",#REDCUR,"REDDEST=",#REDDEST,CR
NextTest2:

IF GREENDEST=GREENDEST THEN FetchGREENDest
  GOTO NextTest3
FetchGREENDest:
  RANDOM RESULT
  RESULT=RESULT // 256
  GREENDEST=RESULT
  GREENDEST=GREENDEST MIN 50
  GREENDEST=GREENDEST MAX 200
'  DEBUG "GREENCUR=",#GREENCUR,"GREENDEST=",#GREENDEST,CR
NextTest3:


IF CLEARCUR<CLEARDEST THEN PlusCLEARCUR        'Check to see if CUR is less than DEST
CLEARCUR=CLEARCUR-1                            'If NOT then decrement CUR
GOTO TestDone1                                 'Jump out of the test
PlusCLEARCUR:
CLEARCUR=CLEARCUR+1                            'If SO then increment CUR
TestDone1:

IF REDCUR<REDDEST THEN PlusREDCUR
REDCUR=REDCUR-1
GOTO TestDone2
PlusREDCUR:
REDCUR=REDCUR+1
TestDone2:

IF GREENCUR<GREENDEST THEN PlusGREENCUR
GREENCUR=GREENCUR-1
GOTO TestDone3
PlusGREENCUR:
GREENCUR=GREENCUR+1
TestDone3:


PULSOUT 0,CLEARCUR  'send a pulse to the servo on P0 (CLEAR MASTER CHIEF)
PULSOUT 1,REDCUR    'send a pulse to the servo on P1 (RED MASTER CHIEF)
PULSOUT 2,GREENCUR  'send a pulse to the servo on P2 (GREEN MASTER CHIEF)


If BaseOFF = 0 then LightBase     'test to see if countdown of light off is dimished
BaseOFF = BaseOFF - 1             'lowers timer of base off time
GOTO BaseDONE
LightBase:                        'sends a signal to 4 LEDs to light base
HIGH 3                            'turns on LED
HIGH 4
HIGH 5
HIGH 6
BaseON = BaseON - 1               'lowers timer of base on time
If BaseON <> 0 then BaseDONE      'checks to see if countdown of light on is dimished
BaseOFF = 10000                   'resets timer of base off
BaseON = 800                      'resets timer of base on
LOW 3                             'turns off LED
LOW 4
LOW 5
LOW 6
BaseDONE:

PAUSE 20        'Use a value of 20 for slow servo motion, comment out for fastest motion
GOTO LOOP       'lets do it again! :)

JonnyMac

June 21, 2007, 04:43:33 PM #13 Last Edit: June 21, 2007, 04:46:18 PM by JonnyMac
I've worked with Vern's random servo code as well, so here's my version of your program; it seems to work the way you want.  You're doesn't seem to light the LEDs.

' =========================================================================
'
'   File...... Halo_Cake.BS1
'   Purpose...
'   Author.... Jon Williams (based on work by Will Turnbow and Vern Graner)
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

SYMBOL  Led4            = 6
SYMBOL  Led3            = 5
SYMBOL  Led2            = 4
SYMBOL  Led1            = 3
SYMBOL  Servo3          = 2
SYMBOL  Servo2          = 1
SYMBOL  Servo1          = 0


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

SYMBOL  IsOn            = 1
SYMBOL  IsOff           = 0


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

SYMBOL  flags           = B0
SYMBOL  updn            = BIT1                  ' 0 = 1 sec, 1 = 10 secs

SYMBOL  posClear        = B2                    ' clear servo position
SYMBOL  posRed          = B3                    ' red servo position
SYMBOL  posGreen        = B4                    ' green servo position
SYMBOL  destClear       = B5                    ' clear servo destination
SYMBOL  destRed         = B6                    ' red servo destination
SYMBOL  destGreen       = B7                    ' green servo destination

SYMBOL  ledTimer        = W5                    ' for leds on/off timing
SYMBOL  lottery         = W6                    ' random value


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

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


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

Main:
  PULSOUT Servo1, posClear                      ' update servos
  PULSOUT Servo2, posRed
  PULSOUT Servo3, posGreen
  PAUSE 10                                      ' <-- fine tune for LEDs


Check_Clear:
  RANDOM lottery                                ' stir random value
  IF posClear <> destClear THEN Move_Clear      ' at destination?
    destClear = lottery // 151 + 50             ' randomize, 50 - 200
    GOTO Check_Red

Move_Clear:
  IF posClear > destClear THEN Move_Clear_CCW
    posClear = posClear + 1                     ' move position CW
    GOTO Check_Red

Move_Clear_CCW:
  posClear = posClear - 1                       ' move position CCW


Check_Red:
  RANDOM lottery
  IF posRed <> destRed THEN Move_Red
    destRed = lottery // 151 + 50
    GOTO Check_Green

Move_Red:
  IF posRed > destRed THEN Move_Red_CCW
    posRed = posRed + 1
    GOTO Check_Green

Move_Red_CCW:
  posRed = posRed - 1


Check_Green:
  RANDOM lottery
  IF posGreen <> destGreen THEN Move_Green
    destGreen = lottery // 151 + 50
    GOTO Update_Timer

Move_Green:
  IF posGreen > destGreen THEN Move_Green_CCW
    posGreen = posGreen + 1
    GOTO Update_Timer

Move_Green_CCW:
  posGreen = posGreen - 1


Update_Timer:
  ledTimer = ledTimer + 1
  IF updn = 1 THEN Leds_Off

Leds_On:
  PINS = %01111000                              ' refesh leds
  IF ledTimer < 50 THEN Main                    ' still timing on-cycle
    ledTimer = 0                                ' reset timer
    updn = 1                                    ' set to off
    GOTO Main

Leds_Off:
  PINS = %00000000                              ' clear leds
  IF ledTimer < 500 THEN Main                   ' still timing off-cycle
    ledTimer = 0                                ' reset timer
    updn = 0                                    ' set to off
    GOTO Main


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


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


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


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


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


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


' -----[ EEPROM Data ]-----------------------------------------------------


LED timing is based on a loop time of approximately 20 ms (standard servo refresh timing). 50 x 20 = 1000 (one second one), 500 x 20 = 10000 (10 seconds off).  There are three bytes left which could be used to add speed control to the individual servos without upsetting the rest of the loop.
Jon McPhalen
EFX-TEK Hollywood Office

Nannuu

Wow, thanks!  Was mine that bad?  So my HIGH and LOW signals don't work?

Noticing I have extra outputs available I picked up the 20 second recording module from Radio Shack.  Can a switch be added when the LEDs come on to activate the sound module?