WOZZY-2010
- 7th February 2010, 05:36
This PBP project is a high precision timer and Speed Calculator.
Its designed to be used with a 2 sensor optical gate, though it can accurately measure the time of any single pulse.
It is mostly an experiment to carry as much precision as possible.
But also a useful gadget in it's own right.
It uses Darrel' Taylor's Instant Interrupts and N-Bit Math (64-Bits) throughout.
The core program is based on an implementation of CCP1, TIMER-1 Interrupts that was originally developed by Bruce from Rentron.
http://www.picbasic.co.uk/forum/showpost.php?p=23401&postcount=3
Here is the Start of the Code:
'************************************************* *****************
'*********************[ High-Resolution Timer ]********************
'************************************************* *****************
'** Author : Robert Wozniak, Robert.Wozniak -at- gmail.com **
'** Notice : This code may be freely used and distributed **
'** for use in non-commercial applications **
'** Version : 6.10 : Feb 06, 2010 **
'** Date : JAN 14, 2010 **
'************************************************* *****************
'** Versions: **
'** 6.0 : All 64 bit MATH, 99 min limit **
'** 5.0 : Working Timer and Speed Calculator with 64 bit math **
'************************************************* *****************
'** Hardware Tested: PIC18F4680 @20MHz **
'** 4x16 Parallel LCD Module **
'** PBP 2.60 / MPLAB IDE 8.40.000 **
'** Compiled with: [-n -ampasmwin] Build Options **
'** 32 BIT LONG SIGNED INTEGER **
'** **
'** Thanks to Darrel & Bruce at MEL PB Forums for Code examples **
'** Alexander for N-Bit Math...Excellent ASM code **
'************************************************* *****************
'** MAX OVRFLO=457763, COUNTS=44041 for 99min:59.9999998sec **
'** MIN OVRFLO=0, COUNTS=261 for 9999.999MPH **
'************************************************* *****************
PRECISION CON 8 SYSTEM ; Set 8 bytes = 64-bit Precision for N-Bit_Math.pbp
INCLUDE "N-BIT_Math.pbp" ; Include Alexander Avtanski's Multibyte Arithmetic
; Assembly Library Wrapped for PBP by Darrel Taylor [Version:1.3 Beta (JAN 07,2010)]
; Version:1.3 Beta (1/7/2010)
INCLUDE "DT_INTS-18.bas" ; Include Darrel Taylor's Base Interrupt System for PIC18F [Version:3.3 (MAR 24, 2008)]
INCLUDE "ReEnterPBP-18.bas" ; Include Darrel Taylor's PBP interrupts for PIC18F [Version:1.4 (MAR 24, 2008)]
DEFINE OSC 20
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 57600 ' 38400 BAUD N-8-1, PORT C6
DEFINE DEBUG_MODE 1 ' 1 = inverted, 0 = true
DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTA ' Set LCD Register Select port
DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 3 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us (2000)
DEFINE LCD_DATAUS 50 ' Set data delay time in us (50)
TRISA=%00000000 ' SET to Output
TRISC.2=1 ' SET to Input
ADCON0=%11000000
ADCON1=%00000111
T1CON.7=1 ' Set Timer1 to 16 bit mode
LED VAR PORTD.1 ' Alias PORTD.0 to LED
I VAR BYTE
J VAR BYTE
OVRFLO VAR LONG ' Timer1 Overflow total
COUNTS VAR WORD ' Timer1 Counts after falling edge capture
PRESET VAR BYTE
OVFLS32 VAR LONG
COUNTS32 VAR LONG
TSEC32 VAR LONG
OVFLS64 VAR BYTE[PRECISION]
OVFLS64M VAR BYTE[PRECISION]
COUNTS64 VAR BYTE[PRECISION]
TSEC64 VAR BYTE[PRECISION]
BITS16 VAR LONG
BITS1664 VAR BYTE[PRECISION]
TMIN64 VAR BYTE[PRECISION]
TSECINT64 VAR BYTE[PRECISION]
TSECDEC64 VAR BYTE[PRECISION]
CONVSEC VAR LONG
CONVSEC64 VAR BYTE[PRECISION]
AA32 VAR LONG
AA64 VAR BYTE[PRECISION]
BB32 VAR LONG
BB64 VAR BYTE[PRECISION]
CC32 VAR LONG
CC64 VAR BYTE[PRECISION]
TMIN VAR LONG
TSEC VAR LONG
TSECINT VAR LONG
TSECDEC VAR LONG
DISTINCH VAR LONG
DISTFT VAR LONG
DISTFT64 VAR BYTE[PRECISION]
DISTFT64M VAR BYTE[PRECISION]
FPS32 VAR LONG
FPS64 VAR BYTE[PRECISION]
FPSINT VAR LONG
FPSINT64 VAR BYTE[PRECISION]
FPSDEC VAR LONG
FPSDEC64 VAR BYTE[PRECISION]
MPH64 VAR BYTE[PRECISION]
MPHINT64 VAR BYTE[PRECISION]
MPHDEC64 VAR BYTE[PRECISION]
MPH32 VAR LONG
MPHINT VAR LONG
MPHDEC VAR LONG
' ****** Setup Variables with Initial Parameters and 64-BIT Constants
I = 0
J = 1
PRESET = 3 ' ********** PER OVERFLOW LOOP TICS CORRECTION **********
BITS16 = 65536 * 2 ' ********** COUNTS MAX * 200 NS PER TIC**********
@ MOVE?LP _BITS16, _BITS1664
DISTINCH = 6000 ' ********** 6.000 inches (MAX = 65.535 in) **********
DISTFT = ((DISTINCH*10000)/12)
@ MOVE?LP _DISTFT, _DISTFT64 ' ********** CONVERT TO FEET **********
AA32 = 1000000 ' ********** BUMP UP RESOLUTION
@ MOVE?LP _AA32, _AA64
@ MATH_MUL _DISTFT64, _AA64, _DISTFT64M ' ********** BUMP UP DISTANCE DIGITS
CONVSEC = 600000000
@ MOVE?LP _CONVSEC, _CONVSEC64 ' ********** BUMP UP TIME DIGITS
Pause 500
LCDOUT $FE,1
LCDOUT $FE,$80,"HIGH-RESOLUTION "
LCDOUT $FE,$C0," TIMER "
LCDOUT $FE,$90," Version 6.10 "
LCDOUT $FE,$D0," Robert Wozniak "
DEBUG 10,13,10,13,10,13
DEBUG "HIGH-RESOLUTION ",10,13
DEBUG " TIMER ",10,13
DEBUG " Version 6.10 ",10,13
DEBUG " Robert Wozniak ",10,13,10,13,10,13
For I = 1 to 5
HIGH LED ' Turn ON LED connected to PORTD.1
Pause 50
LOW LED
PAUSE 50 ' Turn OFF LED connected to PORTD.1
NEXT I
I = 0
;----[High Priority Interrupts (DT_INTS_18)]----------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler CCP1_INT, _Capture, PBP, yes
INT_Handler TMR1_INT, _Timer1, PBP, yes
endm
INT_CREATE ; Creates the High Priority interrupt processor
ENDASM
CCP1CON = %00000101 ' Capture mode, capture on rising edge
T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
@ INT_ENABLE CCP1_INT ; enable Capture interrupts
to be concluded in next post due to length limitations.
The timer has a 200 nS resolution and can go for 99Minutes: 99.9999999Seconds.
Here is the Schematic of the setup
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3972&stc=1&d=1265519692
The Full Resolution PDF file is here:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3971&stc=1&d=1265519692
Here is an photo of the actual Circuit:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3973&stc=1&d=1265519978
This timer was developed to use an input pulse from the 2-Beam Pulse Generator Circuit which I presented here:http://www.picbasic.co.uk/forum/showthread.php?t=12614
While this code looks like an abomination, it's actually pretty cool that all the math is done with 64 bit precision.
I'm pretty new at all this, so I'd really like to hear your comments or criticism.
This is a work in progress. I have several features I'm still planning to include.
I'll follow up with a post with some comments and limitations.
Many thanks to Darrel, Bruce and Alexander for their excellent Code examples.
Its designed to be used with a 2 sensor optical gate, though it can accurately measure the time of any single pulse.
It is mostly an experiment to carry as much precision as possible.
But also a useful gadget in it's own right.
It uses Darrel' Taylor's Instant Interrupts and N-Bit Math (64-Bits) throughout.
The core program is based on an implementation of CCP1, TIMER-1 Interrupts that was originally developed by Bruce from Rentron.
http://www.picbasic.co.uk/forum/showpost.php?p=23401&postcount=3
Here is the Start of the Code:
'************************************************* *****************
'*********************[ High-Resolution Timer ]********************
'************************************************* *****************
'** Author : Robert Wozniak, Robert.Wozniak -at- gmail.com **
'** Notice : This code may be freely used and distributed **
'** for use in non-commercial applications **
'** Version : 6.10 : Feb 06, 2010 **
'** Date : JAN 14, 2010 **
'************************************************* *****************
'** Versions: **
'** 6.0 : All 64 bit MATH, 99 min limit **
'** 5.0 : Working Timer and Speed Calculator with 64 bit math **
'************************************************* *****************
'** Hardware Tested: PIC18F4680 @20MHz **
'** 4x16 Parallel LCD Module **
'** PBP 2.60 / MPLAB IDE 8.40.000 **
'** Compiled with: [-n -ampasmwin] Build Options **
'** 32 BIT LONG SIGNED INTEGER **
'** **
'** Thanks to Darrel & Bruce at MEL PB Forums for Code examples **
'** Alexander for N-Bit Math...Excellent ASM code **
'************************************************* *****************
'** MAX OVRFLO=457763, COUNTS=44041 for 99min:59.9999998sec **
'** MIN OVRFLO=0, COUNTS=261 for 9999.999MPH **
'************************************************* *****************
PRECISION CON 8 SYSTEM ; Set 8 bytes = 64-bit Precision for N-Bit_Math.pbp
INCLUDE "N-BIT_Math.pbp" ; Include Alexander Avtanski's Multibyte Arithmetic
; Assembly Library Wrapped for PBP by Darrel Taylor [Version:1.3 Beta (JAN 07,2010)]
; Version:1.3 Beta (1/7/2010)
INCLUDE "DT_INTS-18.bas" ; Include Darrel Taylor's Base Interrupt System for PIC18F [Version:3.3 (MAR 24, 2008)]
INCLUDE "ReEnterPBP-18.bas" ; Include Darrel Taylor's PBP interrupts for PIC18F [Version:1.4 (MAR 24, 2008)]
DEFINE OSC 20
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 57600 ' 38400 BAUD N-8-1, PORT C6
DEFINE DEBUG_MODE 1 ' 1 = inverted, 0 = true
DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTA ' Set LCD Register Select port
DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 3 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us (2000)
DEFINE LCD_DATAUS 50 ' Set data delay time in us (50)
TRISA=%00000000 ' SET to Output
TRISC.2=1 ' SET to Input
ADCON0=%11000000
ADCON1=%00000111
T1CON.7=1 ' Set Timer1 to 16 bit mode
LED VAR PORTD.1 ' Alias PORTD.0 to LED
I VAR BYTE
J VAR BYTE
OVRFLO VAR LONG ' Timer1 Overflow total
COUNTS VAR WORD ' Timer1 Counts after falling edge capture
PRESET VAR BYTE
OVFLS32 VAR LONG
COUNTS32 VAR LONG
TSEC32 VAR LONG
OVFLS64 VAR BYTE[PRECISION]
OVFLS64M VAR BYTE[PRECISION]
COUNTS64 VAR BYTE[PRECISION]
TSEC64 VAR BYTE[PRECISION]
BITS16 VAR LONG
BITS1664 VAR BYTE[PRECISION]
TMIN64 VAR BYTE[PRECISION]
TSECINT64 VAR BYTE[PRECISION]
TSECDEC64 VAR BYTE[PRECISION]
CONVSEC VAR LONG
CONVSEC64 VAR BYTE[PRECISION]
AA32 VAR LONG
AA64 VAR BYTE[PRECISION]
BB32 VAR LONG
BB64 VAR BYTE[PRECISION]
CC32 VAR LONG
CC64 VAR BYTE[PRECISION]
TMIN VAR LONG
TSEC VAR LONG
TSECINT VAR LONG
TSECDEC VAR LONG
DISTINCH VAR LONG
DISTFT VAR LONG
DISTFT64 VAR BYTE[PRECISION]
DISTFT64M VAR BYTE[PRECISION]
FPS32 VAR LONG
FPS64 VAR BYTE[PRECISION]
FPSINT VAR LONG
FPSINT64 VAR BYTE[PRECISION]
FPSDEC VAR LONG
FPSDEC64 VAR BYTE[PRECISION]
MPH64 VAR BYTE[PRECISION]
MPHINT64 VAR BYTE[PRECISION]
MPHDEC64 VAR BYTE[PRECISION]
MPH32 VAR LONG
MPHINT VAR LONG
MPHDEC VAR LONG
' ****** Setup Variables with Initial Parameters and 64-BIT Constants
I = 0
J = 1
PRESET = 3 ' ********** PER OVERFLOW LOOP TICS CORRECTION **********
BITS16 = 65536 * 2 ' ********** COUNTS MAX * 200 NS PER TIC**********
@ MOVE?LP _BITS16, _BITS1664
DISTINCH = 6000 ' ********** 6.000 inches (MAX = 65.535 in) **********
DISTFT = ((DISTINCH*10000)/12)
@ MOVE?LP _DISTFT, _DISTFT64 ' ********** CONVERT TO FEET **********
AA32 = 1000000 ' ********** BUMP UP RESOLUTION
@ MOVE?LP _AA32, _AA64
@ MATH_MUL _DISTFT64, _AA64, _DISTFT64M ' ********** BUMP UP DISTANCE DIGITS
CONVSEC = 600000000
@ MOVE?LP _CONVSEC, _CONVSEC64 ' ********** BUMP UP TIME DIGITS
Pause 500
LCDOUT $FE,1
LCDOUT $FE,$80,"HIGH-RESOLUTION "
LCDOUT $FE,$C0," TIMER "
LCDOUT $FE,$90," Version 6.10 "
LCDOUT $FE,$D0," Robert Wozniak "
DEBUG 10,13,10,13,10,13
DEBUG "HIGH-RESOLUTION ",10,13
DEBUG " TIMER ",10,13
DEBUG " Version 6.10 ",10,13
DEBUG " Robert Wozniak ",10,13,10,13,10,13
For I = 1 to 5
HIGH LED ' Turn ON LED connected to PORTD.1
Pause 50
LOW LED
PAUSE 50 ' Turn OFF LED connected to PORTD.1
NEXT I
I = 0
;----[High Priority Interrupts (DT_INTS_18)]----------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler CCP1_INT, _Capture, PBP, yes
INT_Handler TMR1_INT, _Timer1, PBP, yes
endm
INT_CREATE ; Creates the High Priority interrupt processor
ENDASM
CCP1CON = %00000101 ' Capture mode, capture on rising edge
T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
@ INT_ENABLE CCP1_INT ; enable Capture interrupts
to be concluded in next post due to length limitations.
The timer has a 200 nS resolution and can go for 99Minutes: 99.9999999Seconds.
Here is the Schematic of the setup
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3972&stc=1&d=1265519692
The Full Resolution PDF file is here:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3971&stc=1&d=1265519692
Here is an photo of the actual Circuit:
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3973&stc=1&d=1265519978
This timer was developed to use an input pulse from the 2-Beam Pulse Generator Circuit which I presented here:http://www.picbasic.co.uk/forum/showthread.php?t=12614
While this code looks like an abomination, it's actually pretty cool that all the math is done with 64 bit precision.
I'm pretty new at all this, so I'd really like to hear your comments or criticism.
This is a work in progress. I have several features I'm still planning to include.
I'll follow up with a post with some comments and limitations.
Many thanks to Darrel, Bruce and Alexander for their excellent Code examples.