I am testing a DT Instant interrupt routine which is supposed to set the length of time that two servos are on or off. Everything works OK except the servos runs very rough. The average position of the servos is correct, but the twitching movement is excessive, making it unuseable. The timing is based on the Elapsed Timer1 Program, from routines found on this Forum. For comparison purposes I have another routine that does not use interrupts, but relies on cycle counting. With this program the servos are smooth and quiet. The cycle counting demo follows here:
Code:
'device is PIC 16F684
'set registers
OPTION_REG.7 = 0 'enable porta pullups
CMCON0 = 7 'comparators off
ANSEL = 0 'porta pins all digital
TRISA = %111111 'set porta pins as input
TRISC = %001101 'set portc pins 0,2,3 as input, all others output
OSCCON = %1110000 'set internal osc. at 8 mhz, wait for stable freq.
OSCTUNE = 0 'internal osc. running at factory calibration
DEFINE OSC 8 '8 Mhz oscillator
while OSCCON.2 = 0 'wait for osc.to be stable
wend
'declare variables
i var word 'couting variable
led var portc.3 'led output on portc.3
dummy var byte 'variable needed to end porta mismatch
throttlepos var word 'servo1 pulse width in .01 seconds
servopos var word 'servo2 pulse width
pulsecnt var byte
start:
low led 'flash red LED for 0.5 sec to show circuit is functioning
pause 500
high led
pause 2000 'delay timer start 2 seconds
portc.1 = 0 'turn off servo
portc.4 = 0 'initialize servo pulse low
portc.5 = 0 'initialize throttle pulse low
throttlepos = 400 '2*(200) pulse width adjusted for 8 mhz osc
servopos = 400 '2*(200) pulse width adjusted for 8 mhz osc
low Led 'turn on led
portc.1 = 1 'turn on servos
for i = 1 to 500 'run servo for 10 seconds (500 cycles)
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pause 16
next
high Led 'turn off led
throttlepos = 200 '2*(100) pulse width adjusted for 8 mhz osc
servopos = 400 '2*(200) pulse width adjusted for 8 mhz osc
for i = 1 to 75 'run servos for 1.5 seconds (75 cycles}
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pause 16
next
low Led ' turn on led
for i = 1 to 750 'run servos for 15 seconds 750 cycles)
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pauseus 16100
next
high led 'turn off led
DT: high portc.3 'turn off led
servopos = 200 'DT release position 2*(100)
pulsecnt = 75 'hold for 1.5 second
gosub pulse 'this section uses a subroutine to run the servo
servopos = 400 'home position
pulsecnt = 50 'hold for 1 second
gosub pulse 'return to home position
goto halt
'subroutine pulse runs the servo
pulse: portc.4 = 0 'initialize servo pulse low
for i = 1 to pulsecnt
pulsout portc.4,servopos
pause 18
next
return
halt:
portc.1 = 0 'turn off servo
end
The demo interrupt program is follows here. Two interrupts are used in this case, but it makes no difference; the servos runs rough even when the interrupt on change is taken out. The twitching is still there even if only one servo is used. Any ideas on why the rough running?
Code:
'device is PIC 16F684
'set registers
OPTION_REG.7 = 0 'enable porta pullups
CMCON0 = 7 'comparators off
ANSEL = 0 'porta pins all digital
TRISA = %111111 'set porta pins as input
TRISC = %001101 'set portc pins 0,2,3 as input, all others output
OSCCON = %1110000 'set internal osc. at 8 mhz, wait for stable freq.
OSCTUNE = 0 'internal osc. running at factory calibration
DEFINE OSC 8 '8 Mhz oscillator
while OSCCON.2 = 0 'wait for osc.to be stable
wend
'declare variables
i var byte
led var portc.3 'led output on portc.3
MTtime var word 'target motor runtime in tenths of seconds
BKtime var word 'target brake time in tenths of seconds
DTtime var word 'target DT time in tenths of seconds
dummy var byte 'variable needed to end porta mismatch
throttlepos var word
servopos var word
pulsecnt var byte
start:
low led 'flash red LED for 0.5 sec to show circuit is functioning
pause 500
high led
pause 2000 'delay timer start 2 seconds
INCLUDE "DT_INTS-14 for F684.bas" 'Base interrupt with wsave selected for 16F684
INCLUDE "ReEnterPBP.bas" 'Using PBP interrupts
INCLUDE "Elapsed_INT_RI2.bas" 'Elasped timer counting seconds and tenths seconds
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RAC_INT, _RDT, PBP, yes
INT_Handler TMR1_INT, _ClockCount, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
goto overint
'-------Interrupt Handler for RDT------------
RDT:
high led 'turn led off
dummy = porta 'needed to end mismatch for porta
IOCA.4 = 0 'disable porta.4 interrupt
@ INT_RETURN
'--------------------------------------------
overint:
portc.1 = 0 'turn off servo
portc.4 = 0 'initialize servo pulse low
portc.5 = 0 'initialize throttle pulse low
throttlepos = 400 '2*(200)
servopos = 400 '2*(200)
dummy = porta ' initialize dummy variable
IOCA.4 = 1 ' enable porta pin 4 for interrupt on change
MTtime = 100 ' 10.0 second motor run time
BKtime = 15 ' 1.5 second brake time
DTtime = 150 ' 15 second glide time
gosub ResetTime ' Reset Time to 0d-00:00:00.00
gosub StartTimer ' Start the Elapsed Timer
@ INT_ENABLE RAC_INT ; Enable PortA Change Interrupt
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
low Led 'turn on led
portc.1 = 1 'turn on servo
main:
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pause 17
if IOCA.4 = 0 then
goto newtime1 'jump to end-time on interrupt
endif
if sum => MTtime then 'stop when target end time is reached
high led 'turn off led
goto newtime1
endif
goto main 'loop until endtime is reached
newtime1:
gosub StopTimer ' Stop Timer1
gosub ResetTime ' Reset Time to 0d-00:00:00.00
gosub StartTimer ' Start the Elapsed Timer
throttlepos = 200 ' 2*(100)
high Led 'turn off led
portc.5 = 0 'initialize throttle pulse low
brake:
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pause 17
if IOCA.4 = 0 then
goto newtime2 'jump to end-time on interrupt
endif
if sum => BKtime then 'stop if elapsed time = target end-time
low led 'turn on led
goto newtime2
endif
goto brake
newtime2:
gosub StopTimer
gosub ResetTime ' Reset Time to 0d-00:00:00.00
gosub StartTimer ' Start the Elapsed Timer
IOCA.4 = 1 ' re-enable porta pin 4 for interrupt on change
low Led ' turn on led
portc.5 = 0 ' initialize throttle pulse low
portc.4 = 0 ' initialize servo pulse low
glide:
pulsout portc.5,throttlepos
pulsout portc.4,servopos
pause 17
if IOCA.4 = 0 then
goto DT 'jump to end-time on interrupt
endif
if sum => DTtime then 'stop if elapsed time = target end-time
high led 'turn off led
goto DT
endif
goto glide
@ INT_DISABLE RAC_INT ; Disable PortA Change Interrupt
@ INT_DISABLE TMR1_INT ; Disable Timer 1 Interrupts
DT: high portc.3 'turn off led
servopos = 200 'DT release position
pulsecnt = 75 'hold for 1.5 second
gosub pulse
servopos = 400 'home position
pulsecnt = 50 'hold for 1 second
gosub pulse 'return to home position
goto halt
'subroutine pulse runs the servo
pulse: portc.4 = 0 'initialize servo pulse low
for i = 1 to pulsecnt
pulsout portc.4,servopos
pause 18
next
return
halt:
portc.1 = 0 'turn off servo
end
Bookmarks