PDA

View Full Version : Tachometer with DT Interrupts?



DanPBP
- 17th November 2009, 04:39
Hello Guys,

Well, for a few weeks, maybe a few months, I've been trying not to open this thread, as a website admin from another forum I know what is like to have the same question asked over and over again, but I couldn't find a simple piece of code for a tachometer using DT Interrupts (if it's possible to do that).

I don't need the config fuses for the PIC (16F88) or the entire code for the project I'm doing (a wireless tach for R/C brushless cars), I only need to know how to read how many pulses there are on a pin in a second and read that from a word variable (because I think a byte is not enough) using DT Interrupts.

So, could someone give me a hand with this request? :) (don't like the words help/problem)

Thanks!

Daniel.

Acetronics2
- 17th November 2009, 08:04
Hi, Daniel

I generally use TMR1 and it's interrupt, reading Timer1 ( as free running timer ) ...

just read it @ each interrupt ... difference from previous read ... gives the period.

@ 20 Mhz max resolution is 200ns which is quite enough ...

Alain

aratti
- 17th November 2009, 08:41
Hi Daniel, you can also use the timer1 as an asynchronous counter, and connect your encoder directly to portB.6 (pin 12) and with two words variable one for the count one for the delay you will govern the counting process. You can also set (using DT interrupt) an overflow routine which will tell you when the setted delay time is too much.

All the time you will call the subroutine Get_Count the word Counter will contain the count from time0 and time0+delay. Setting delay appropriatly the counter could give you the speed without any additional maths.

Al.





Counter var word
Delay var word


Get_Count:
TCON1 = 6
TMR1L = 0
TMR1H = 0
TCON1 = 7
Pauseus Dalay
TCON1 = 6
Counter.Byte0 = TMR1L
Counter.byte1 = TMR1H
Return

Charles Linquis
- 17th November 2009, 13:43
I posted this at least once before, but here it is again;





INCLUDE "DT_INTS-18.bas" ; Base Interrupt System


ASM
INT_LIST macro
INT_Handler TMR0_INT, ReadTachs, ASM, yes

endm
INT_CREATE
ENDASM

Goto OverInt

;-----------------------------------------------------------------

Asm
ReadTachs
movff PreloadH,TMR0H ; Preload depends on clk speed
movff PreloadL,TMR0L



infsnz MasterClock ; 16 bit timer used for housekeeping
incf MasterClock + 1

btfsc TPE,0 ; Tells tach routine to stop
bra DoneForNow

;CheckTach
infsnz TachClock ; Tells tach counters how long to count
incf TachClock + 1

movlw 0x03 - 1 ; Real value is 1000 = 0x3E8, but must have one less
cpfsgt TachClock + 1 ; to compare with greater than
bra TachRoutine
movlw 0xE8 - 1 ; Likewise, subtract one here, too.
cpfsgt TachClock
bra TachRoutine
bsf TPE,0

clrf TachClock
clrf TachClock + 1
bra DoneForNow

TachRoutine

movf PORTB,0,0
movwf Temp,0 ; Save VAR so can't change between compare and save
xorwf OldPortB,0,0
movwf changedB,0
movff Temp,OldPortB

movf PORTC,0,0
movwf Temp,0
xorwf OldPortC,0,0
movwf changedC,0
movff Temp,OldPortC

movf PORTD,0,0
movwf Temp,0
xorwf OldPortD,0,0
movwf changedD,0
movff Temp,OldPortD


Tach1
btfss changedB,0
bra Tach2
infsnz Tach1Counter
incf Tach1Counter+1

Tach2
btfss changedB,1
bra Tach3
infsnz Tach2Counter
incf TachCounter+1

Tach3
btfss changedB,2
bra Tach4
infsnz TachCounter
incf TachCounter+1
Tach4
btfss changedB,3
bra Tach5
infsnz Tach4Counter
incf Tach4Counter+1

Tach5
btfss changedB,4
bra Tach6
infsnz Tach5Counter
incf Tach5Counter+1

Tach6
btfss changedB,5
bra Tach7
infsnz Tach6Counter
incf Tach6Counter+1

Tach7
btfss changedC,0
bra Tach8
infsnz TachCounter
incf TachCounter+1

Tach8
btfss changedD,5
bra Tach9
infsnz Tach8Counter
incf Tach8Counter+1

Tach9
btfss changedD,4
bra DoneForNow
infsnz Tach9Counter
incf Tach9Counter+1

DoneForNow

bcf INTCON,2 ; Clear the TIMER0 interrupt flag

INT_RETURN
ENDASM



Set the PRELOAD value for the interrupt period (must be shorter than the shortest tach half-cycle). Set the TachCounter for how many interrupts you want to count over (currently 1000). Clear all the TachCounters and set TPE to 0. Periodically check to see if TPE is set. If so, copy the TachCounters to other variables, zero the variables and start over. All done in the background and does a nice job of averaging - something you will need if there is any kind of noise present.

DanPBP
- 17th November 2009, 19:51
Thank you guys!!! I'll try the examples you gave me... To tell you the truth, this is my first time with interrupts, so, wish me luck.. :)

Daniel.