We have a latched Hall Sensor on CCP1 pin with 2 magnets on a wheel diameter.
CCP1 pin is 5Volts for half a turn and 0Volt for the next half turn.
We want to measure the pulse time on 5Volts between 2 captures (rising and falling)
Then we want to have the LEDon for half a turn at any speed.
GCBASIC compile with no error, but the code does not work.
DO
'Set up timer
InitTimer1 Osc,PS1_1/8
ClearTimer 1
StartTimer 1
If PilotFlag = 0 Then
' Set up CCP1 capture mode every 1 Cycle Rising Edge
CCP1CON = b'00000101'
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 1
TimeCount1 = TimeCount
' Reset CCP1 module
CCP1CON = b'00000000'
End If
If PilotFlag = 1 Then
' Set up CCP1 capture mode every 1 Cycle Falling Edge
CCP1CON = b'00000100'
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 2
SnapTiming = TimeCount - TimeCount1 ' speed measure for 180°
'Reset CCP1 module
CCP1CON = b'00000000'
End IF
If PilotFlag = 2 Then
LEDon
' Set up CCP1 compare mode
CCP1CON = b'00001010'
ClearTimer 1
StartTimer 1
CapturedTime = SnapTiming
On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 3
' Reset CCP1 module
CCP1CON = b'00000000'
End If
If PilotFlag = 3 Then
LEDoff
PilotFlag = 0
End If
Loop
'===== HANDLER
'=========================================================
Sub PulseReceived (TimeCount As word, CapturedTime As word)
TimeCount = CapturedTime ' Alias CCPR1H,CCPR1L
PilotFlag + = 1
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This does not fulfill your requirement of triggering on both rising and falling edge. But i may give you a better understanding of the flow of the program.
This code has not been tried on a board/hdwe
' Pulse timer
' Port RC2 is CCP1 input
' CapturedTime is period of pulse
' Led is on for 1/2 rotation
' 2/17/2011
#chip 16F886, 8 'chip must have ccp I don't know what osc you are using
#define LED PORTB.0
dir PORTB.0 OUT
InitTimer1 Osc,PS1_1/8
ClearTimer 1
initCCP1
'===============================Main
Main:
pilotflag =0
do
If (pilotflag = 1) AND (LED = ON) Then
set LED OFF
pilotflag = 0
end if
If (pilotflag = 1) AND (LED = OFF) Then
set LED ON
pilotflag = 0
end if
loop
'==================Initialization of interrupt and ccp
'four capture modes:
'0100 falling edge
'0101 rising edge
'0110 every 4th rising edge
'0111 every 16th rising edge
'
sub initCCP1
dir PortC.2 in 'pulse input Pin RC2/CCP1/P1A on the PIC16F886
T1CON = b'00110001'
CCP1CON = b'00000000' 'Switching from one capture prescaler to another does not
'clear the prescaler and may generate a false interrupt.
'must switched off and then set
CCP1CON = b'00000101' 'start pulse capture on rising edge
On Interrupt CCP1 call PulseReceived ' set up the interrupt to read the duration and reset the timer
StartTimer 1
end sub
'===== Interrupt HANDLER
'=========================================================
Sub PulseReceived
ClearTimer 1 ' reset timer 1
CapturedTime_H = CCPR1H 'read pulse width and store
CapturedTime_L = CCPR1L
CCP1IF = 0 'clear capture flag
PilotFlag = 1 'indicate to main you have capture period
End Sub
GL
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
mmotte your Main Do Loop code do not use the CCP1 pin signal and do not fulfill the requirement of measuring a pulse period with the CCP1 Capture Mode and wait half a revolution with athe CCP1 Compare Mode.
I modified the code with your idea of re-initializing in the handler outside the loop. But the new code below does not fulfill the requirement of changing the CCP1 Mode on the Fly.
PilotFlag = 0
'Set up timer
InitTimer1 Osc,PS1_1/8
ClearTimer 1
StartTimer 1
DO
If PilotFlag = 0 Then
'Set up CCP1 capture mode every 1 Cycle Rising Edge
CCP1CON = b'00000101'
Set CCP1IF = 0
On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 1
End If
If PilotFlag = 1 Then
LEDoff
Set COIL1 ON
TimeCount1 = TimeCount
'Set up CCP1 capture mode every 1 Cycle Falling Edge
CCP1CON = b'00000100'
Set CCP1IF = 0
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 2
End If
If PilotFlag = 2 Then
SnapTiming2 = TimeCount - TimeCount1 ' speed measure for 180°
SnapTiming1 = Snaptiming2 / 2 ' speed measure for 90°
Timeoffset = SnapTiming1 / 7 ' maximum advance 26°
'Set up CCP1 compare mode
CCP1CON = b'00001010'
Set CCP1IF = 0
CapturedTime = SnapTiming1 - Timeoffset
On Interrupt CCP1 Call PulseReceived ' set PilotFlag = 3
End If
If PilotFlag = 3 Then
Set COIL1 Off
End If
LOOP
'==============================================================
'===== HANDLER
'==============================================================
Sub PulseReceived (TimeCount As word, CapturedTime As word)
TimeCount = CapturedTime 'Alias CCPR1H,CCPR1L
PilotFlag + = 1
IF PilotFlag = 4 Then PilotFlag = 0
LEDon
Set CCP1IE = 0
'Reset CCP1 module
CCP1CON = b'00000000'
ClearTimer 1
StartTimer 1
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
mmotte I am using a MicroChip PIC 16F628 with a 20Mhz Cristal config is OSC = HS
I have several good test codes on the PC board for the CCP1 pin working in Capture Mode, and for the timer1. .
The GCBASIC oninterrupt help says GCBASIC doesn't fully support all of the hardware which can generate interrupts ……
This is why I am working with the Microchip PIC MCU CCP and ECCP Tips and Tricks document
capaction,
GCBASIC may not have keyword for somethings but that does not prevent the programmer from using any features of the chip. GCBASIC allows integration of assembly directly intermixed with the basic, I find this an advantage.
Here is my latest attempt to code your challenge.
It sounds like a four stroke engine. How do you know if you are on the power stroke?
'Select chip
#chip 16F628, 20
'Define ports
#define LED PORTA.1
#define COIL1 PORTA.2
#define LEDoff Set LED off
#define LEDon Set LED on
'Set port directions
dir LED out
dir COIL1 out
dir PortB.3 in 'pulse input Pin RB3/CCP1 on the PIC16F628
DIM TimeCount As word
DIM TimeCount1 As word
DIM CapturedTime As word
DIM SnapTiming1 As word
DIM SnapTiming2 As word
DIM Timeoffset As word
PilotFlag = 0
'Initialize Interrupt and Set up timer
InitTimer1 Osc,PS1_1/8
CCP1CON = b'00000000'
CCP1CON = b'00000101' 'start pulse capture on rising edge
On Interrupt CCP1 call PulseReceived ' set up the interrupt to read the duration
ClearTimer 1
StartTimer 1
CCP1IF = 0
DO
wait 100 ms 'do nothing, interrupt is doing it all
LOOP
'==============================================================
'===== HANDLER
'==============================================================
Sub PulseReceived
ClearTimer 1 ' reset timer 1
CapturedTime_H = CCPR1H 'read pulse width and store
CapturedTime_L = CCPR1L
If PilotFlag = 0 Then
LEDon
'Set up CCP1 capture mode every 1 Cycle Rising Edge
CCP1CON = b'00000000'
CCP1CON = b'00000101'
End If
If PilotFlag = 1 Then
LEDoff
Set COIL1 ON
TimeCount1 = CapturedTime
'Set up CCP1 capture mode every 1 Cycle Falling Edge
CCP1CON = b'00000000'
CCP1CON = b'00000100'
End If
If PilotFlag = 2 Then
SnapTiming2 = CapturedTime - TimeCount1 ' speed measure for 180°
SnapTiming1 = Snaptiming2 / 2 ' speed measure for 90°
Timeoffset = SnapTiming1 / 7 ' maximum advance 26°
'Set up CCP1 compare mode
'Compare mode, generate software interrupt on match
'CCP1IF bit is set, CCP1 pin is unaffected
CCP1CON = b'00000000'
CCP1CON = b'00001010'
CapturedTime = SnapTiming1 - Timeoffset
CCPR1H = CapturedTime_H 'write pulse width and store
CCPR1L = CapturedTime_L
End If
If PilotFlag = 3 Then
Set COIL1 Off
End If
PilotFlag += 1
IF PilotFlag = 4 Then PilotFlag = 0
CCP1IE = 0
CCP1IF = 0 'clear capture flag
ClearTimer 1
StartTimer 1
End Sub
'The user should keep bit
'CCP1IE (PIE1<2>) clear to avoid false interrupts and
'should clear the flag bit CCP1IF following any such
'change in Operating mode.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
mmotte thank you for your suggestion.
My code does not work. I add an ignition test before the Do-wait-Loop this code is OK with the PCB.
then the Led is on, when I start the motor the led stays off; meaning that the interrupts don't work.
My code is there: http://capaction.free.fr/16F628_V12.txt
I am puzzled
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We have a latched Hall Sensor on CCP1 pin with 2 magnets on a wheel diameter.
CCP1 pin is 5Volts for half a turn and 0Volt for the next half turn.
We want to measure the pulse time on 5Volts between 2 captures (rising and falling)
Then we want to have the LEDon for half a turn at any speed.
GCBASIC compile with no error, but the code does not work.
DO
'Set up timer
InitTimer1 Osc,PS1_1/8
ClearTimer 1
StartTimer 1
If PilotFlag = 0 Then
' Set up CCP1 capture mode every 1 Cycle Rising Edge
CCP1CON = b'00000101'
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 1
TimeCount1 = TimeCount
' Reset CCP1 module
CCP1CON = b'00000000'
End If
If PilotFlag = 1 Then
' Set up CCP1 capture mode every 1 Cycle Falling Edge
CCP1CON = b'00000100'
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 2
SnapTiming = TimeCount - TimeCount1 ' speed measure for 180°
'Reset CCP1 module
CCP1CON = b'00000000'
End IF
If PilotFlag = 2 Then
LEDon
' Set up CCP1 compare mode
CCP1CON = b'00001010'
ClearTimer 1
StartTimer 1
CapturedTime = SnapTiming
On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 3
' Reset CCP1 module
CCP1CON = b'00000000'
End If
If PilotFlag = 3 Then
LEDoff
PilotFlag = 0
End If
Loop
'===== HANDLER
'=========================================================
Sub PulseReceived (TimeCount As word, CapturedTime As word)
TimeCount = CapturedTime ' Alias CCPR1H,CCPR1L
PilotFlag + = 1
End Sub
Your Do- loop is resetting the timer and re-initializing the ccp every loop.
Move you intializations outside of the main loop. Could put them into subs.
This does not fulfill your requirement of triggering on both rising and falling edge. But i may give you a better understanding of the flow of the program.
This code has not been tried on a board/hdwe
' Pulse timer
' Port RC2 is CCP1 input
' CapturedTime is period of pulse
' Led is on for 1/2 rotation
' 2/17/2011
#chip 16F886, 8 'chip must have ccp I don't know what osc you are using
#define LED PORTB.0
dir PORTB.0 OUT
InitTimer1 Osc,PS1_1/8
ClearTimer 1
initCCP1
'===============================Main
Main:
pilotflag =0
do
If (pilotflag = 1) AND (LED = ON) Then
set LED OFF
pilotflag = 0
end if
If (pilotflag = 1) AND (LED = OFF) Then
set LED ON
pilotflag = 0
end if
loop
'==================Initialization of interrupt and ccp
'four capture modes:
'0100 falling edge
'0101 rising edge
'0110 every 4th rising edge
'0111 every 16th rising edge
'
sub initCCP1
dir PortC.2 in 'pulse input Pin RC2/CCP1/P1A on the PIC16F886
T1CON = b'00110001'
CCP1CON = b'00000000' 'Switching from one capture prescaler to another does not
'clear the prescaler and may generate a false interrupt.
'must switched off and then set
CCP1CON = b'00000101' 'start pulse capture on rising edge
On Interrupt CCP1 call PulseReceived ' set up the interrupt to read the duration and reset the timer
StartTimer 1
end sub
'===== Interrupt HANDLER
'=========================================================
Sub PulseReceived
ClearTimer 1 ' reset timer 1
CapturedTime_H = CCPR1H 'read pulse width and store
CapturedTime_L = CCPR1L
CCP1IF = 0 'clear capture flag
PilotFlag = 1 'indicate to main you have capture period
End Sub
GL
mmotte your Main Do Loop code do not use the CCP1 pin signal and do not fulfill the requirement of measuring a pulse period with the CCP1 Capture Mode and wait half a revolution with athe CCP1 Compare Mode.
I modified the code with your idea of re-initializing in the handler outside the loop. But the new code below does not fulfill the requirement of changing the CCP1 Mode on the Fly.
PilotFlag = 0
'Set up timer
InitTimer1 Osc,PS1_1/8
ClearTimer 1
StartTimer 1
DO
If PilotFlag = 0 Then
'Set up CCP1 capture mode every 1 Cycle Rising Edge
CCP1CON = b'00000101'
Set CCP1IF = 0
On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 1
End If
If PilotFlag = 1 Then
LEDoff
Set COIL1 ON
TimeCount1 = TimeCount
'Set up CCP1 capture mode every 1 Cycle Falling Edge
CCP1CON = b'00000100'
Set CCP1IF = 0
On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 2
End If
If PilotFlag = 2 Then
SnapTiming2 = TimeCount - TimeCount1 ' speed measure for 180°
SnapTiming1 = Snaptiming2 / 2 ' speed measure for 90°
Timeoffset = SnapTiming1 / 7 ' maximum advance 26°
'Set up CCP1 compare mode
CCP1CON = b'00001010'
Set CCP1IF = 0
CapturedTime = SnapTiming1 - Timeoffset
On Interrupt CCP1 Call PulseReceived ' set PilotFlag = 3
End If
If PilotFlag = 3 Then
Set COIL1 Off
End If
LOOP
'==============================================================
'===== HANDLER
'==============================================================
Sub PulseReceived (TimeCount As word, CapturedTime As word)
TimeCount = CapturedTime 'Alias CCPR1H,CCPR1L
PilotFlag + = 1
IF PilotFlag = 4 Then PilotFlag = 0
LEDon
Set CCP1IE = 0
'Reset CCP1 module
CCP1CON = b'00000000'
ClearTimer 1
StartTimer 1
End Sub
capaction,
You only need to set up the interrupt once. It must be called outside the main loop once. It sets up the vector for the interrupt.
Check out this explanation and see the example.
http://gcbasic.sourceforge.net/newfiles/help/oninterrupt.htm
capaction,
looks like you are using ccp1 for too many purposes
which chip are you using?
you should have other resources like ccp2, interrupt on port B change, interrupt
mmotte I am using a MicroChip PIC 16F628 with a 20Mhz Cristal config is OSC = HS
I have several good test codes on the PC board for the CCP1 pin working in Capture Mode, and for the timer1. .
The GCBASIC oninterrupt help says GCBASIC doesn't fully support all of the hardware which can generate interrupts ……
This is why I am working with the Microchip PIC MCU CCP and ECCP Tips and Tricks document
http://ww1.microchip.com/downloads/en/DeviceDoc/41214B.pdf
Tip#3 Measuring Pulse Width page 8 ( half a revolution with my Hall Sensor hardware )
COMPARE TIPS ' N TRICKS page 16
COMBINATION CAPTURE AND COMPARE TIPS page 49
Thank you for looking on the Reset on the Fly challenge.
capaction,
GCBASIC may not have keyword for somethings but that does not prevent the programmer from using any features of the chip. GCBASIC allows integration of assembly directly intermixed with the basic, I find this an advantage.
Here is my latest attempt to code your challenge.
It sounds like a four stroke engine. How do you know if you are on the power stroke?
mmotte thank you for your suggestion.
My code does not work. I add an ignition test before the Do-wait-Loop this code is OK with the PCB.
then the Led is on, when I start the motor the led stays off; meaning that the interrupts don't work.
My code is there:
http://capaction.free.fr/16F628_V12.txt
I am puzzled