The following code provides a full-featured single servo controller with up to 1 microsecond resolution and controlled using only 2 buttons.
Using the buttons the servo increments or decrements by a user declared step value until the minimum or maximum timing values, also declared by the user, are reached.
It has another button feature that allows auto-repeat-incrementing and auto-repeat-decrementing the position until it reaches the max or min value by simply holding a button down for an extended period.
The final button feature is auto-center of the servo by holding both buttons at the same time. The center timing is declared by the user.
Also, this is a nice project to make using an 8-Pin 12F683... only 3 GPIO pins needed!
Enjoy the program and have a great new year.
Code: Select all
program PB_SERVO
'**************************************************************************'
'***** *****'
'***** 50Hz SINGLE SERVO TESTER USING 2 BUTTONS *****'
'***** 16F628A @ 4MHz INTOSC_NoClkout *****'
'***** Written By Warren Schroeder on 12.31.08 *****'
'***** Using MikroBASIC v.7.2 *****'
'***** Tested and Programmed Using EasyPIC5 *****'
'***** Code Is Easily Adapted For Any PIC With CCP Module *****'
'***** *****'
'***** 1 microsecond position accuracy *****'
'***** Range of 1us to 19,999us *****'
'***** User can setup Min, Max, & Center Sweep Range as needed *****'
'***** *****'
'***** Features 2 Button Control For 3 Main Functions: *****'
'***** *****'
'***** Button1 = move to min position by user declared Step Value *****'
'***** Button2 = move to max position by user declared Step Value *****'
'***** Button1+Button2 = move to center position *****'
'***** *****'
'***** HOLDING a BUTTON WILL AUTO INCREMENT/DECREMENT Till MAX/MIN *****'
'***** *****'
'**************************************************************************'
Symbol SPIN = PORTB.0 ' Servo Output Pin
Const StepVal = 5 ' in microseconds
MinPos = 500 ' in microseconds
MaxPos = 2500 ' in microseconds
Center = 1500 ' in microseconds
Dim CCPR as Word Absolute $15 ' CCPR1L:CCPR1H pair
ServoPos as Word
Temp as Byte
sub procedure Interrupt()
If (PORTB And 1) = 1 Then
SPIN = 0 ' turn servo off
CCPR = 20000 - CCPR ' off time to finish 20ms
Else
SPIN = 1 ' turn servo on
CCPR = ServoPos ' on time in microseconds
End If
PIR1.CCP1IF = 0 ' clear int flag
End sub
sub procedure delay30()
Delay_ms(30)
end sub
sub procedure INIT()
CMCON = 7 ' turn off comparators
PORTA = 0
PORTB = 0
TRISA = 3
TRISB = 0
ServoPos = 0
end sub
Sub procedure CCP_SETUP()
INTCON = 192 ' GIE, PEIE enabled
T1CON = 0 ' no prescale; off; 1us ticks
TMR1H = 0 ' clear timer1
TMR1L = 0
CCP1CON = 11 ' reset timer1 on compare-match
CCPR = MinPos ' match int value; 0 deg position
PIR1.CCP1IF = 0 ' clear int flag
PIE1.CCP1IE = 1 ' enable int
T1CON.TMR1ON = 1 ' timer1 run
end sub
'***** Buttons Inputs are Pulled Low on RA0 and RA1 *****'
'*********************************************************'
sub procedure BUTTONS()
If (PORTA And 3) <> 0 Then ' check for active buttons
delay30 ' debounce delay
Temp = PORTA And 3 ' save button value
While Temp <> 0 ' while a button is active do
If Temp = 3 Then ' both buttons active
ServoPos = Center ' goto center position
Else
If Temp = 1 Then ' dec position by stepval
ServoPos = ServoPos - StepVal
If ServoPos < MinPos Then ServoPos = MinPos End If
Else ' inc position by stepval
ServoPos = ServoPos + StepVal
If ServoPos > MaxPos Then ServoPos = MaxPos End If
End If
End If
delay30 ' button release delay
Temp = PORTA And 3 ' check again for release
Wend ' if not released will inc or dec more
End If
end sub
main:
INIT()
CCP_SETUP()
While 1=1
BUTTONS()
Wend
end.