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