Strange problem with 'pauseus' command
I am having a weird problem here, and I'm wondering if someone has any idea
what's going on. I'm building a new version of my charcoal smoker temperature
controller, and decided to incorporate a damper on the airbox. That way, when it wants
to cool off the smoker, the damper closes and it cools off quicker.
I decided to use an R/C servo to control the damper, that way it is easy to adjust the
open / close points. Rather than have my main processor (18F2550) control the servo, I
decided to use a 12F683 and just have a line from the main processor that goes high or low.
This way, the main processor doesn't have to worry about creating the pulse that controls
the servo.
I only need the servo all the way one way (1mS pulse) or the other (2mS pulse), no proportional
control is needed.
Below is the original way I wrote the code. The numbers for pulse count and pulse
are what worked out to the two pulse lengths and the 20mS period. It worked fine.
I wanted to have a little more resolution for adjustments, so I decided to change the 100uS
pause to 50uS and double the other three numbers. When I looked at the signal on the scope,
it was nowhere near what I wanted. In fact, I had to lower the three numbers almost to
where they were in the original!
Is 50uS just too fast for 8Mhz? If not, what else could have caused this effect?
Code:
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF
#ENDCONFIG
DEFINE OSC 8 'LETS PBP KNOW WE WILL BE RUNNING AT 8MHZ
DISABLE 'NO DEBUG, NO INTERRUPTS
'PIN DEFENITIONS
'GP0 USED FOR ICSP DATA
'GP1 USED FOR ICSP CLOCK
'GP2 USED TO DRIVE SERVO (SIGNAL LINE)
'GP3 USED FOR MCLR AND ICSP PROGRAMMING
'GP4 USED FOR TRIGGER INPUT
'GP5 USED FOR LED
'SET UP THE SPECIAL REGISTERS
OSCCON = %01110001 '8MHZ INTERNAL CLOCK USED
CMCON0 = %00000111 'CIN PINS ARE I/O, COUT PIN IS I/O
OPTION_REG = 0 'WEAK PULL UPS ARE ENABLED
TRISIO = %00011011 'GP5 AND GP2 ARE OUTPUTS, THE REST ARE INPUTS
ANSEL = 0 'NO ANALOG PORTS - ALL DIGITAL
WPU = %00010000 'GP4 WEAK PULL UP ENABLED. GP3 WEAK PULL UP AUTOMATICALLY ENABLED
'AS THE PIN IS DEFINED AS MCLR
IOC = 0 'NO INTERRUPT ON CHANGE
'PIN ALIASES
SERVO VAR GPIO.2
TRIGGER VAR GPIO.4
LED VAR GPIO.5
'VARIABLES
PERIOD_COUNT VAR BYTE 'TO TIME THE 20mS PERIOD
PULSE VAR BYTE 'PULSE LENGTH IN 100uS INCREMENTS
SERVO = 0 'MAKE SURE NO SIGNAL
LED = 0 'MAKE SURE LED IS OFF
MAIN:
DO 'ENDLESS LOOP
IF TRIGGER = 1 THEN 'CLOSE THE DAMPER
PULSE = 19 '2.0mS PULSE TO SERVO
LED = 1 'TURN ON LED
ELSE 'OPEN THE DAMPER
PULSE = 8 '1.0mS PULSE TO SERVO
LED = 0 'TURN OFF LED
ENDIF
FOR PERIOD_COUNT = 1 TO 187 '20mS PERIOD
IF PERIOD_COUNT > PULSE THEN 'MAKE LINE LOW FOR REST OF 20mS PERIOD
SERVO = 0 'MAKE SURE SERVO SIGNAL IS NOW LOW
ELSE
SERVO = 1 'SERVO SIGNAL LINE HIGH FOR 1.0 OR 2.0mS
ENDIF
PAUSEUS 100 '100uS PAUSE
NEXT PERIOD_COUNT
LOOP
END
Re: Strange problem with 'pauseus' command
Quote:
PERIOD_COUNT VAR BYTE 'TO TIME THE 20mS PERIOD
Quote:
I wanted to have a little more resolution for adjustments, so I decided to change the 100uS
pause to 50uS and double the other three numbers
Quote:
PERIOD_COUNT = 1 TO 187 '20mS PERIOD
what is 187*2 ?
will it fit in a byte ?
Re: Strange problem with 'pauseus' command
Quote:
Originally Posted by
richard
what is 187*2 ?
will it fit in a byte ?
Sorry, forgot to mention that I did define PERIOD_COUNT as a word when I doubled everything.
Thanks,
Andy
Re: Strange problem with 'pauseus' command
Code:
FOR PERIOD_COUNT = 1 TO 187 '20mS PERIOD
IF PERIOD_COUNT > PULSE THEN 'MAKE LINE LOW FOR REST OF 20mS PERIOD
SERVO = 0 'MAKE SURE SERVO SIGNAL IS NOW LOW
ELSE
SERVO = 1 'SERVO SIGNAL LINE HIGH FOR 1.0 OR 2.0mS
ENDIF
NEXT PERIOD_COUNT
this for next loop takes 45us to execute when PERIOD_COUNT is a word var even without the pause, it severly limits resolution
if you do it this way the resolution is 1 uS or thereabouts
Code:
'****************************************************************
'* Name : hobby_servo.BAS *
'* Author : richard *
'* Notice : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 11/19/2016 *
'* Version : 1.0 *
'* Notes : 12f683 *
'* : *
'****************************************************************
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF
#ENDCONFIG
DEFINE OSC 8 'LETS PBP KNOW WE WILL BE RUNNING AT 8MHZ
include "dt_ints-14.bas"
include "REENTERPBP.bas"
'PIN DEFENITIONS
'GP2 USED TO DRIVE SERVO (SIGNAL LINE)
'GP3 USED FOR MCLR AND ICSP PROGRAMMING
'GP4 USED FOR TRIGGER INPUT
'GP5 USED FOR LED
'SET UP THE REGISTERS
OSCCON = %01110001 '8MHZ INTERNAL CLOCK USED
CMCON0 = %00000111 'CIN PINS ARE I/O, COUT PIN IS I/O
OPTION_REG=%01010111 ;set prescaler and assign it to tmr0
define NO_WDT 1
TRISIO = %00011011 'GP5 AND GP2 ARE OUTPUTS, THE REST ARE INPUTS
ANSEL = 0 'NO ANALOG PORTS - ALL DIGITAL
WPU = %00010000 'GP4 WEAK PULL UP ENABLED. GP3 WEAK PULL UP AUTOMATICALLY ENABLED
'AS THE PIN IS DEFINED AS MCLR
@Timer1 = TMR1L ; map timer1 registers to a word variable
Timer1 VAR WORD EXT
t1con=0
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'Wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
asm
INT_LIST macro
INT_Handler TMR0_INT, _serv, PBP, yes
INT_Handler TMR1_INT, _st, PBP, yes
endm
INT_CREATE
ENDASM
'PIN ALIASES
SERVO VAR GPIO.2
TRIGGER VAR GPIO.4
LED VAR GPIO.5
'VARIABLES
servo_t VAR word 'pulse TIME in us
SERVO = 0 'MAKE SURE NO SIGNAL
LED = 0 'MAKE SURE LED IS OFF
@ int_enable TMR0_INT
@ int_enable TMR1_INT
MAIN:
IF TRIGGER = 1 THEN 'CLOSE THE DAMPER
servo_t = 2000 '2.0mS PULSE TO SERVO
LED = 1 'TURN ON LED
ELSE 'OPEN THE DAMPER
servo_t = 1000'1.0mS PULSE TO SERVO
LED = 0 'TURN OFF LED
ENDIF
goto main
END
serv:
tmr0=tmr0+100
Timer1 = -servo_t
pir1.0=0
t1con=$11
SERVO =1
@ int_return
st:
t1con=0
servo=0
@ int_return
Re: Strange problem with 'pauseus' command
Quote:
Originally Posted by
richard
'************************************************* ***************
'* Name : hobby_servo.BAS *
'* Author : richard *
'* Notice : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 11/19/2016 *
'* Version : 1.0 *
'* Notes : 12f683 *
'* : *
'************************************************* ***************
I thank you Sir. MUCH better resolution, like you said. While I have used DT's Instant Interrupts a little,
I have not used them a lot. I'm starting to get a handle on how you did that. In fact, I may port this over
to an 18F2550 so I can use debug to watch everything to help my understanding.
Thanks again,
Andy
Re: Strange problem with 'pauseus' command
Quote:
I may port this over
to an 18F2550 so I can use debug to watch everything to help my understanding.
it should be pretty straight forward to get it to work on a pic18.
trying to debug/watch isr's in action is an art form in itself especially when they need to run at full speed to function realistically or even at all.
try this version if you want to regulate the speed the servo
ps the osctune setting is for my particular chip others may/will need a different value ,see data sheet
I chose a value that gives me an accurate 2mS pulse for a servo_t value of 2000 / trial and error
Code:
'****************************************************************
'* Name : hobby_servo.BAS *
'* Author : richard *
'* Notice : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 11/19/2016 *
'* Version : 1.0 *
'* Notes : 12f683 *
'* : now with speed control and osc tuned for accuracy *
'****************************************************************
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
#ENDCONFIG
DEFINE OSC 8 'LETS PBP KNOW WE WILL BE RUNNING AT 8MHZ
include "dt_ints-14.bas"
include "REENTERPBP.bas"
'PIN DEFENITIONS
'GP2 USED TO DRIVE SERVO (SIGNAL LINE)
'GP3/mclr USED FOR TRIGGER INPUT
'GP4 vacant
'GP5 USED FOR LED
'SET UP THE REGISTERS
OSCCON = %01110001 '8MHZ INTERNAL CLOCK USED
CMCON0 = %00000111 'CIN PINS ARE I/O, COUT PIN IS I/O
OPTION_REG=%01010111 ;set prescaler and assign it to tmr0
define NO_WDT 1
TRISIO = %00011011 'GP5 AND GP2 ARE OUTPUTS, THE REST ARE INPUTS
ANSEL = 0 'NO ANALOG PORTS - ALL DIGITAL
WPU = %00010000 'GP4 WEAK PULL UP ENABLED. GP3 WEAK PULL UP AUTOMATICALLY ENABLED
'AS THE PIN IS DEFINED AS MCLR
@Timer1 = TMR1L ; map timer1 registers to a word variable
Timer1 VAR WORD EXT
t1con=0
OSCTUNE=3 ;trim best way
closed con 2000
open con 500
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'Wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
asm
INT_LIST macro
INT_Handler TMR0_INT, _serv, PBP, yes
INT_Handler TMR1_INT, _st, PBP, yes
endm
INT_CREATE
ENDASM
'PIN ALIASES
SERVO VAR GPIO.2
TRIGGER VAR GPIO.3
LED VAR GPIO.5
'VARIABLES
servo_t VAR word 'pulse TIME in us
tick var byte
mvflg var bit
servo_t=open
LED = !TRIGGER
@ int_enable TMR0_INT
@ int_enable TMR1_INT
MAIN:
IF TRIGGER = 1 THEN 'CLOSE THE DAMPER
LED = 1 'TURN ON LED
while servo_t < closed
servo_t = servo_t + 20
mvflg=0
while !mvflg :wend
wend
servo_t = closed
ELSE 'OPEN THE DAMPER
LED = 0 'TURN ON LED
while servo_t > open
servo_t = servo_t - 20
mvflg=0
while !mvflg :wend
wend
servo_t = open
ENDIF
goto main
END
serv:
tmr0=tmr0+97
Timer1 = ~servo_t;+50 alternative trim method
pir1.0=0
t1con=$11
SERVO =1
tick=tick+1
if tick.0 then mvflg=1
@ int_return
st:
t1con=0
servo=0
@ int_return