November 23, 2024, 08:32:40 AM

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.


RC-4 / Prop-1 / Cowlacious Audio board / Topic: Servo movement

Started by EricTheMannn, May 24, 2009, 12:31:13 PM

Previous topic - Next topic

EricTheMannn

Hi everyone here at EFX-TEK forums, I have a question about servos. I have a 2 axis head that i need to do random movements, here's an example of my current setup & movements using the parallax servo controller board, http://www.youtube.com/watch?v=dhD4ggobxe4&feature=channel_page

Can i add Similar servo movements to the below program using pin1 and pin0? I'm not well rounded with the servo code as of now but i am willing to learn.

[EDIT] 5/25/09  Here's what Ive come up with so far The problem i am having now is the limited eeprom space of the prop-1.


' =========================================================================
'
'   File......  Frankie2009servo.bs1
'   Purpose...
'   Author.... Eric garthwait
'   E-mail.... ericthemannn@live.com
'   Started... 4/26/2009
'   Updated... 5/25/2009
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' frankie prop with servo movements

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


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

SYMBOL  Sio             = 7                          ' SETUP = out; no ULN
SYMBOL  Trigger         = PIN6                       ' SETUP = DN


SYMBOL  Servo2          = 1
SYMBOL  Servo1          = 0

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

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

SYMBOL  Baud            = OT2400
SYMBOL  RecLen          = 4                     ' record length (servos + 1)
' -----[ Variables ]-------------------------------------------------------
SYMBOL   relays      = B0
SYMBOL   Left_Side   = BIT0     'K1 On RC-4
SYMBOL   Right_Side  = BIT1     'K2 On RC-4
SYMBOL   Side_fx     = BIT2     'K3 on RC-4
SYMBOL   Lighting    = BIT3     'K4 on RC-4
SYMBOL   timer       = B2
SYMBOL   idx         = B3
'---------------[Servo Varibles]-------------------------------------------
SYMBOL  record          = B0                    ' movement record
SYMBOL  pntr            = B1                    ' table byte pointer
SYMBOL  s1Pos           = B2                    ' servo 1 position
SYMBOL  s2Pos           = B3                    ' servo 2 position
SYMBOL  s3Pos           = B4                    ' servo 3 position
SYMBOL  repeats         = B5                    ' repeats for record data

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

Reset:
  PINS = %00000000                               ' clear all outputs, Lighting and everything else turned
                                                 ' off when show is over.
  DIRS = %10000111                              ' make servo pins outputs no direct outputs

  relays = IsOff
  SEROUT Sio, Baud, ("!!!!!RC4", %00, "X")     ' clear RC-4 outputs

  record = 0
  GOSUB Get_Servo_Pos                           ' get "home" positions

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

Main:
  timer = 0                                     ' reset timer
  Check_Trigger:
  PAUSE 5                                       ' loop pad
  timer = timer + 5 * Trigger                   ' update timer
  IF timer < 100 THEN Check_Trigger             ' wait for 0.1 sec input
  HIGH 0
  PAUSE 500                                     'Audio Trigger
  LOW 0
  Lighting = IsOn
  GOSUB Update_RC4:
  GOSUB FX_Routine
  GOSUB Servo_Routine
  GOSUB Struggle_Routine
  GOSUB FX_Routine
  PAUSE 3000
  GOSUB Struggle_routine
  GOSUB Servo_Routine
  GOSUB FX_Routine
  PAUSE 300
  GOSUB FX_Routine
  GOTO  Reset                                   ' End of program, reset wait till next show

' -----[ Subroutines ]-----------------------------------------------------
   ' Update servos -- time consumed is 18 to 21 ms

Refresh_Servos:
  PULSOUT Servo1, s1Pos
  PULSOUT Servo2, s2Pos
  PAUSE 15                                      ' pad for loop timing
  RETURN
' Call with "record" set to table line to read

Get_Servo_Pos:
  pntr = record * RecLen                        ' point into table
  READ pntr, s1Pos                              ' read servo 1 value
  pntr = pntr + 1                               ' point to servo 2
  READ pntr, s2Pos
  pntr = pntr + 1
  READ pntr, s3Pos
  pntr = pntr + 1                               ' point to repeats
  READ pntr, repeats                            ' read repeats
  RETURN
' -------------------------------------------------------------------------
Struggle_Routine:
    FOR idx = 1 TO 6           'left and right side (arms and legs) movements. cylinders are in the down
    Left_Side = IsOn           'position when unactivated.
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 150
    Left_Side = IsOff
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 150
    Right_Side = IsOn
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 150
    Right_Side = IsOff
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 150
    NEXT
    RETURN
' -------------------------------------------------------------------------
  FX_Routine:
    FOR idx = 1 TO 3         'Cylinder is extended when valve is not activated
    Side_fx  = IsOn
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 500
    Side_fx = IsOff
    SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
    PAUSE 500
    NEXT
    RETURN
' -------------------------------------------------------------------------
' Note on servo movement timing:
'
' Time spent on each record is 20 ms x (repeats + 1) so a repeats value
' of 0 is ~20 ms and a repeats value of 255 (max) is ~5.1 sseconds at that
' position.
'         s1   s2   s3   rpts
Move_Table:
  EEPROM (150, 150, 150, 255)                   ' home position
  EEPROM (200, 225, 150,  50)                   ' start of movements
  EEPROM (150, 200, 150,  50)
  EEPROM (150, 150, 150, 255)                   ' end here
' -------------------------------------------------------------------------
' -------------------------------------------------------------------------
Servo_Routine:
GOSUB Refresh_Servos
Reset_Moves:
  record = 1                                    ' point to start of moves
Move_Engine:
  GOSUB Get_Servo_Pos                           ' get servo positions
  IF s1Pos = 225 THEN Reset                     ' abort if at end
Servo_Hold:
  GOSUB Refresh_Servos
  IF repeats = 0 THEN New_Record                ' time left at this pos?
    repeats = repeats - 1                       ' yes, decrement timing
    GOTO Servo_Hold
New_Record:
  record = record + 1
  GOTO Move_Engine

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


Thank You,
-Eric Garthwait

WooHoo

JonnyMac

The *problem* with adding servos to a Prop-1 or Prop-2 program is that you must design the program such that the servos get updated every 20 milliseconds or so -- this can be difficult (it's easier on the SX because you can write a background servo driver).  If you do a search on "servo" you'll see lots of demos where I have shown how to integrate servos so that they are constantly refreshed.  If you don't refresh the servo it will lose its position and if under load something will move when you don't want it to.

Servos are hard and force us to write tricky programs for the Prop-1 and Prop-2.  You have two choices: Write a tricky program or buy an off-board servo controller to handle the servos so you don't have to.
Jon McPhalen
EFX-TEK Hollywood Office

EricTheMannn

Well I'm glad i have the parallax usb servo controller on hand! i better get vsa or something simulator, have you used vixen with one of these servo controllers?

Thank you for the fantastic support,

-Eric Garthwait
WooHoo

JonnyMac

Unfortunately, Vixen and VSA will not help you with integrating servos into a stand-alone prop; if you want to do that you'll have to gut it out and figure out what position values you need at any given point in the program. 

Sorry if I sounded like I was trying to dissuade you, I'm not, I just want everyone to understand that when you want to add servo movement to a prop it is a bit of a process and is not something that one can bang out in a few minutes (like we can with most other prop programs).
Jon McPhalen
EFX-TEK Hollywood Office

EricTheMannn

Its okay, I understand how frustrating it can be using servos in a stand alone prop,  I can probably use a host computer and just have the parallax servo controller program as the main program and play the show on a loop of some sort. I plan to have this prop indoors so its not a big deal if its not completely stand alone. But it was worth a try, now that the servo mech is all situated i can work on the pneumatics & lighting FX, then program the show. 

Thank You, Jon

Have a great day

-Eric Garthwait  ;D
WooHoo

JonnyMac

They important thing with servos is to take the time to play -- they are just not as easy as using HIGH and LOW to turn things on and off.  Once you get a good handle you *may* be able to incorporate them into your code, but... your code will have to be designed to deal with servos. 

For example, here's a framework that uses a state-machine approach and updates the servos at the top of Main:

' =========================================================================
'
'   File......
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2009 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 ]---------------------------------------------
'
' Sio     :: Serial IO to EFX-TEK accessories (RC-4, FC-4, etc.)
'            -- clip pin 1 of ULN2803 or replace with ULN2003
'
' Trigger :: Parallax-compatible PIR or N.O. button (mat switch, etc.)
'            -- connect N.O. button between P6.W and P6.R


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


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

SYMBOL  Sio             = 7                     ' SETUP = UP; no ULN
SYMBOL  Trigger         = PIN6                  ' SETUP = DN

SYMBOL  Servo2          = 1
SYMBOL  Servo1          = 0


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

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

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  Baud            = OT2400                ' B/R jumper removed


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

SYMBOL  task            = B2

SYMBOL  pos1            = B3
SYMBOL  pos2            = B4


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

Reset:
  PINS = %00000000                              ' preset output pins
  DIRS = %00111111                              ' define ins/outs

  pos1 = 150
  pos2 = 150


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

Main:
  PULSOUT Servo1, pos1                          ' refesh servos
  PULSOUT Servo2, pos2
  PAUSE 22                                      ' adjust for 25ms loop

  BRANCH task, (Task_0, Task_1, Task_2, Task_3)
  task = 0                                      ' fix task error


Task_0:
  ' handle task 0 stuff here
  ' -- update task # as required
  GOTO Main


Task_1:
  ' handle task 1 stuff here
  ' -- update task # as required
  GOTO Main


Task_2:
  ' handle task 2 stuff here
  ' -- update task # as required
  GOTO Main


Task_3:
  ' handle task 3 stuff here
  ' -- update task # as required
  GOTO Main


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


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


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


If each task section is small you can simply adjust the PAUSE 22 to get a 25ms loop time -- this means that all of your timing events are in units of 25ms.  If they are wildly varied you can in fact pad each task section with a PAUSE to balance the loop timing (so that the loop runs 25ms, no matter which task is active).  The latter is time-consuming; I actually had to do this with a commercial product developed using the BS2.
Jon McPhalen
EFX-TEK Hollywood Office