PDA

View Full Version : Actuating Servos on a Schedule/Time Delay



wdmagic
- 14th March 2013, 21:56
I need to have servos (up to say 8) move from position 0 to (X) on a time delay, but I need to set a seperate time delay between each servo also,
so say every 10 minutes I need to cycle all servos and I need each servo to wait say 20 seconds before returning to the 0 position and letting the next servo run, so on and so forth. only 1 servo can be out of the position 0 at a one time. right now I'm just working with 2 servos, but I want to use up to 8. Ive been working with the code below, i would like the display to show which servo is not in position 0, and how long before the servos are to run (in a countdown perhaps). My code is incorrect as it would fire up all servos at the same time. also if anyone sees other problems with code let me know.


DEFINE LCD_DREG PORTD ' LCD Data bits on PORTD
DEFINE LCD_DBIT 0 ' PORTD starting address
DEFINE LCD_RSREG PORTD ' LCD RS bit on PORTD
DEFINE LCD_RSBIT 5 ' LCD RS bit address
DEFINE LCD_EREG PORTD ' LCD E bit on PORTD
DEFINE LCD_EBIT 4 ' LCD E bit address
DEFINE LCD_BITS 4 ' LCD in 4-bit mode
DEFINE LCD_LINES 4 ' LCD has 4 rows
DEFINE ADC_BITS 10 ' A/D number of bits
DEFINE ADC_CLOCK 1 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us

TRISA = 1 'PORTA is all input
TRISD = 0 ' PORTD is output 'LCD
TRISB = 0 ' PORTB is output

LCDOUT $FE, 1 ' Clear LCD
PAUSE 500 ' Wait 0.5sec for LCD to initialize

Time Var Word : time = 0' Time Between Engaging
Servo VAR word : Servo = 200 ' Servo Position Set when Engaged
NumServos VAR byte : numservos = 2 ' # of Servos, Max 8
Counter VAr word : Counter = 0' Time Counter
X var word : x = 0 ' OnTime
Y VAR WORD : y = 0 ' Servo Select

AGAIN:
ADCIN 0, time ' Read Channel 0 data
time = (time / 121) + 60 ' 60-600 Seconds
for Y = 1 to NumServos
PULSOUT PORTB.0 [Y], 100 ' Send the Home position Pulse
Next y
PAUSE 20 ' Wait 20 ms
goto Display
Counter = counter + 1
if counter > time then counter = 0
GOTO AGAIN ' Repeat

RunServos:
for X = 1 to 500 ' 20ms X 500 = 10 Seconds
For Y = 1 to NumServos ' Select Servo
PULSOUT PORTB.0[Y], 200 ' Send the Not HOME Pulse
Next Y
PAUSE 20 ' Wait 20 ms
goto display
next X
Return

Display:
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "Set Minutes = ", DEC3 time
LCDOUT $FE, $C0
LCDOUT "RunTime = " , DEC Counter , " "
return

wdmagic
- 15th March 2013, 19:51
OK i got it to work, timing is a bit off but it shouldnt work with servo positions used. I added a 3rd servo on a pot just to see what numbers i had to send to activate the servos... weird thing is it rotates from 15 - 50, a pic programming manual says to use 130 - 170, and Ive seen articles on here that use 100 - 200. on a older program i wrote just for testing servos with a 12f675 I used 100 - 200 and it worked fine. I am now using a 18f4550. not sure why its having issues. I would like to get it back to the 100-200 range for servo resolution. heres the code working right now. I did speed it up changing the adc math, 500 will go back to 121.


TRISA = 255 ' PORTA is all input
TRISD = 0 ' PORTD is output
TRISB = 0 ' PORTB is output

LCDOUT $FE, 1 ' Clear LCD
PAUSE 250 ' Wait 0.5sec for LCD to initialize

Time Var WORD : time = 0 ' Time Between Engaging
HomePos VAR byte : homepos = 20 ' Servo Starting Position 15
Servo VAR byte : Servo = 25 ' Servo Position Set when Engaged 50
NumServos VAR byte : numservos = 2 ' # of Servos, Max 8
Counter VAr WORD : Counter = 0 ' Time Counter
X var word : x = 0 ' OnTime
Y VAR WORD : y = 0 ' Servo Select

Initialize:
PORTB.2 = 1 ' Set All Servos to Home Position
For Y = 1 to NumServos ' Select Servo (Each in use for 5s)
for X = 1 to 25 ' 20ms X 250 = 5 Seconds
PULSOUT PORTB.0[y], homepos ' Send the Home Position Pulse
PAUSE 20 ' Wait 20 ms
next X
Next Y
PORTB.2 = 0

Mainloop:
ADCIN 0, time ' Read Channel 0 data
time = (time / 512) + 5 ' 60-600 Seconds
Counter = counter + 1
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "Set Minutes = ", DEC3 time
LCDOUT $FE, $C0
LCDOUT "Servo OFF = " , DEC3 counter

if counter > time then
counter = 0
For Y = 1 to NumServos ' Select Servo (Each in use for 15s)
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "Set Minutes = ", DEC3 time
LCDOUT $FE, $C0
LCDOUT "Servo On = " , DEC3 counter ' Update Display (Servo Selection)
PORTB.2 = 1 ' Set All Servos to Home Position
for X = 1 to 25 ' 20ms X 250 = 5 Seconds
PULSOUT PORTB.0[y], servo ' Send the Home Position Pulse
PAUSE 20 ' Wait 20 ms
next X
Next Y
PORTB.2 = 0
pause 100
PORTB.2 = 1 ' Set All Servos to Home Position

For Y = 1 to NumServos ' Select Servo (Each in use for 5s)
for X = 1 to 25 ' 20ms X 250 = 5 Seconds
PULSOUT PORTB.0[y], homepos ' Send the Home Position Pulse
PAUSE 20 ' Wait 20 ms
next X
Next Y
PORTB.2 = 0
ENDIF

'For X = 1 to 100
Pause Time
'next x
x = 0
GOTO mainloop ' Repeat
END