speedometer without timer1


Closed Thread
Results 1 to 9 of 9
  1. #1

    Default speedometer without timer1

    I'm using Darrel's sspwm.inc program to generate a 2khz pwm signal which works very well. I now need a speedometer function. I have an incomming square wave pulse train from the vehicle speed sensor which pulses at approx 4000/minute at 60mph.

    I have spare adc inouts so i was looking at a simple rc filter and measuring a cap voltage. Or i could use a freq to voltage ic LM2907 etc but i don't really want another ic on the board. So can I use ccp without access to timer1 as that's used by sspwm.inc.

    I probably can't use count or pulsin for the same reasons, the software pwm must continue in the background and the hpwm is already in use generating a 20khz signal.

    Any Ideas?

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Talking Re: speedometer without timer1

    Name:  ball_askme.jpg
Views: 536
Size:  8.2 KB

    "Crystal ball help me... crystal ball... tell me which PIC the OP's using... maybe he could use Timer 0 for it's counting purpose?

    Crystal ball tell me more about the OP's requirement...."

    Last edited by mister_e; - 6th February 2011 at 11:08.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    Quote Originally Posted by mister_e View Post

    "Crystal ball help me... crystal ball... tell me which PIC the OP's using... maybe he could use Timer 0 for it's counting purpose?

    Crystal ball tell me more about the OP's requirement...."

    LOL Mister E

    Pic is 16F88

    I think timer 0 is only 8 bit so can't count high enough?

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    It really depend what you need to do with the incoming pulse. Timer0 also have Prescaller/divider, you can play with the acquisition time, and maybe use the overflow interrupt (if any for TMR0).

    We don't know the purpose of your 2 PWMs... hard to suggest things.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    The two pwms have to continue unaffected in the background.

    What about the RC idea and using the adc to acquire the voltage?

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    Sure less flexible & accurate than the Timer idea.

    Look @ the classic LM2917... Frequency to Voltage converter. That must mean something
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  7. #7
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    You can use a timer interrupt. You can use TMR0 or just "piggyback" on Darrel's TMR1 interrupt in the SSPWM routine.

    The only caveat is that the period of that interrupt must be shorter than the narrowest pulse (either high or low) that your speedometer sensor puts out.

    I have written (and posted) a routine that would do what you want. Mine is written in asm, but could be written in PBP as well.

    Below is a section. It measures the speed of 9 fans by watching the tachometers.

    A couple of things to note -

    It must be written as an ISR.
    The interrupt time is determined by PRELOADH and PRELOADL.
    The routine runs for an exact number of interrupts before stopping (FanClock is the counter) 1000 is the number here.
    So if you interrupt at 1mSec intervals, this routine will run for 1 second before being restarted in the main loop.

    To use:

    Set your interrupt rate.
    Determine how many counts you need to get the accuracy you want (which determines
    how long you need to count and therefore, the maximum update rate of your speedometer).

    If you get 1 cycle (1 high period and one low period) per foot, and you have a 50% duty cycle, then you will get 88 cycles per second with a high period of 5.6 mSec and a low period of 5.6 mSec. To account for jitter, your interrupt period would have to be 5 mSec or less. You would have 166 transitions (low->high + high -> low) in one second. If you set FanCounter to time out in .3614 seconds (say 100 counts with a 3.614 mSec update rate), the count would be in exact mph with a .3614 second update rate. Longer counting intervals and faster interrupts gives more accuracy and less jitter.


    You need clear TPE before you start.
    Check TPE in your main loop. If it is set, the routine has completed. Transfer the contents of the FanxCounters to another set of variables (call them FanYcounters, clear all the FanXcounters, Clear FanClock and Clear TPE. Now your main loop can read FanYcounters and display the mph, or RPM, or whatever.

    You don't have to stop TMR0 on most chips to reload it. You do have to stop most of the other timers before reloading. Check your datasheet.
    The routine runs for an exact number of interrupts before stopping. You need clear TPE before you start.

    Code:
    Asm                            
    ReadTachs
             movff    PreloadH,TMR0H  ; Preload depends on clk speed
             movff    PreloadL,TMR0L
             infsnz  MasterClock
             incf    MasterClock + 1
            
             btfsc   TPE,0
             bra     DoneForNow
            
    ;CheckFans         
             infsnz  FanClock        
             incf    FanClock + 1
                
             movlw   0x03 - 1          ; Real value is 1000 = 0x3E8, but must have one less
             cpfsgt  FanClock + 1      ; to compare with greater than
             bra     FanRoutine
             movlw   0xE8 - 1          ; Likewise, subtract one here, too.
             cpfsgt  FanClock
             bra     FanRoutine
             bsf     TPE,0
             
             clrf    FanClock
             clrf    FanClock + 1
             bra     DoneForNow
                    
    FanRoutine
                  
             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
           
             
    Fan1       
             btfss   changedB,0
             bra     Fan2
             infsnz  Fan1Counter
             incf    Fan1Counter+1
           
    Fan2        
             btfss   changedB,1
             bra     Fan3
             infsnz  Fan2Counter
             incf    Fan2Counter+1
                    
    Fan3        
             btfss   changedB,2
             bra     Fan4
             infsnz  Fan3Counter
             incf    Fan3Counter+1
    Fan4        
             btfss   changedB,3
             bra     Fan5
             infsnz  Fan4Counter
             incf    Fan4Counter+1
           
    Fan5       
             btfss   changedB,4
             bra     Fan6
             infsnz  Fan5Counter
             incf    Fan5Counter+1        
           
    Fan6       
             btfss   changedB,5
             bra     Fan7
             infsnz  Fan6Counter
             incf    Fan6Counter+1 
                     
    Fan7        
             btfss   changedC,0
             bra     Fan8
             infsnz  Fan7Counter
             incf    Fan7Counter+1  
               
    Fan8        
             btfss   changedD,5
             bra     Fan9
             infsnz  Fan8Counter
             incf    Fan8Counter+1               
                  
    Fan9        
             btfss   changedD,4
             bra     DoneForNow
             infsnz  Fan9Counter
             incf    Fan9Counter+1  
                         
    DoneForNow
            
             bcf     INTCON,2   ; Clear the TIMER0 interrupt flag
           
            INT_RETURN	 		; WAS RETFIE FAST      Return from the interrupt
    ENDASM
    Charles Linquist

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    could you do a "pulse-in" once or twice a second with a limit of 1/4 or 1/3 second so program continues, that uses a 10 micro-sec resolution and 16 bit count, all in basic ?

    don
    Amgen Marine

  9. #9
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: speedometer without timer1

    Pulsin has an inherent problem that the duty cycle has to be constant, and often it is not. A cycle is both a "low" time plus a "high" time. It is also a blocking command. While you can do a

    PULSIN pin,0,lowtime
    PULSIN pin,1,hightime

    Period = lowtime + hightime

    Speed (or RPM, etc) = constant/Period

    To get the correct period even if the duty cycle varies somewhat, you should know that PULSIN can't read the hightime immediately following the lowtime.
    It reads the lowtime, misses the next hightime, skips the following lowtime, and then reads the hightime.

    If your sensor puts out a good clean signal, then the PULSIN method is the easiest. But also remember, that at very slow speeds, your code will be sitting around for a long time waiting for the next transition.


    The good thing about my routine is that it runs in the background and averages over the sample period (I usually use about 0.5 sec), so the results are very stable, even with noisy inputs.

    And... There is nothing that keeps you from writing your ISR in PBP. Use Darrel Taylor's Instant Interrupts.

    Just -

    read the port bit on a timer interrupt
    compare it with the last read of that bit
    if it has changed, increment a counter
    do the above for a fixed amount of time
    read the counter.
    Charles Linquist

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts