PBPro Maths Help


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

    Default PBPro Maths Help

    Dear All

    I have some old code i use to calaculate vehicle speed in mph from a pulsing speed sensor.

    Code:
     
    CheckSpeed:     'Pulsin measures VSS pulse. In no pulse in the timeout, result will be 0 
     pulsin VSS,1,Local   'Measure length of a VSS pulse in 5us (8mhz) units (Timeout 0.32768s)
     if Local = 0 then JumpSpeed  'If Local = 0 pulsin has timed out and vehicle is moving at < 1.5mph
     Local = Local / 11   'Divide Local by 11 to enable results to fit into 16 bit Integer Maths
     ActualSpeed = (7908 / Local) + 1 'Returns Speed in mph accurate to 1 mph Approx!
    I am constrained by the 16 bit maths but am sure there will be a better way with the pbpro maths experts to code my formula. The code above works but is a bit inacurate and I end up adding 1mph on at the end to get it something like right. Any ideas please.

    ASFAIK the VSS speed sensor outputs around 4000 pulses per mile
    Last edited by retepsnikrep; - 30th April 2011 at 01:56.

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


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Have you thought of doing it a slightly different way? Most sensors have some jitter, so averaging out several samples gives a better result. Also, the duty cycle often isn't constant. To be really accurate, you have to take width of a positive half-cycle and add it to the width of a negative-half cyle.

    I had enormous problems measuring the speeds of small fans using PULSIN. In order to get a stable, accurate result I had to average so many samples together the routine was taking too long.

    Below is an ISR written in assembly that does the job perfectly.
    It is run on a timer interrupt, so you can use any pin. The interrupt period is adjusted to be less than the period of the smallest half-cycle you need to measure.
    In the example below, it is 1mSec. TPE is a flag that gets set after a certain number of interrrupts (1000 in this case), so it will measure over 1 second.

    To use it, you clear Fanclock and Fan1Counter and TPE

    Your main loop checks for TPE being set. If it is, it transfers the contents of Fan1Counter to another variable (call it SPEED), clears FanClock, Fan1Counter and TPE.

    Now the variable SPEED always has the number of transitions (twice the pulse rate). It runs totally in the background. The rest of your program really doesn't need to know your timer exists. All it has to do is read SPEED and clear the variables.

    Since you are getting ~4K pulses / mile, you will get a little less than 1 pulse per foot of travel. 60MPH = 88 ft/sec. So you could count for a little less than 1/2 second (change 3E8 to something a little smaller than 1F4) and you will get an answer in MPH. No fancy math required.


    Code:
    ReadTach
     
             movlw   0xEC              ; Reload TMR0 with 65535 - 10000
             movwf   TMR0H
             movlw   0x7E
             movwf   TMR0L
     
             bcf     INTCON,2           ; Clear the TIMER0 interrupt flag
     
     
     
     
             btfss   TPE,0
             bra     CheckFans
             bra     DoneForNow
     
    CheckFans         
             infsnz  FanClock        
             incf    FanClock + 1
     
             movlw   0x03 - 1          ; 1000 = 0x3E8, but must have one less
             cpfsgt  FanClock + 1      ; to compare with greater than
             bra     FanRoutine
             movlw   0xE8 - 1          ; Again, subtract one
             cpfsgt  FanClock
             bra     FanRoutine
             bsf     TPE,0
             clrf    FanClock
             clrf    FanClock + 1
             bra     DoneForNow
     
    FanRoutine
     
             movf    PORTB,0,0
             movwf   Temp,0
             xorwf   OldPortB,0,0    ' XOR current with old to detect change
             movwf   changedB,0
             movff   Temp,OldPortB
     
    Fan1       
             btfss   changedB,0   ' Fan is connected to PortB.0
             bra     DoneForNow
             infsnz  Fan1Counter
             incf    Fan1Counter+1  ; increment the counter
     
    DoneForNow
     
    INT_RETURN
    Charles Linquist

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Thanks for that Charles i probably should have added i am using a 16F88 pic running at 8mhz, TMR1 (16bit) is already in use for another interrupt driven routine. Darrell's SSPWM routine.

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


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    It would still work with that part (I think). I normally run this on a TMR0 interrupt (in an 18F part). You could make the speed interrupt a low priority interrupt, and let the SSPWM be high priority. That way, the speed interrupt wouldn't screw up your PWM.

    You could get by with 8 bit counters (ex fan1counter in my example) in your application. I used a 16 bit counter because I often need to measure the speed of
    15,000 RPM fans.
    Charles Linquist

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    I will try that later Charles.
    I was hoping for some help using DIV32 and that sort of thing to reduce errors in my 16 bit maths

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Still hoping for some guidance on the div32 type maths to improve the accuracy of my current 16 bit maths

  7. #7
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Hi, Retep ...

    first you have to declare a dummy var ... and a Div flag

    then ...

    Code:
     
     
    IF Local > 32767 then    ' see PBP manual ... for the Why ???
       Local = Local/2
       Div = 1
    Else
       Div = 0
    ENDIF
     
    Dummy = 11
    Dummy = Dummy*7908 ; operation needed by PBP ...
    ActualSpeed = DIV32  Local
     
    IF Div THEN ActualSpeed = Actualspeed / 2    ' Ooops ! not *2 ...
     
    ActualSpeed = ActualSpeed + 1
    Last edited by Acetronics2; - 6th May 2011 at 07:19.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Thanks for the help so far, here is a different formula though.
    How to convert that to use max resolution and div 32 command etc.

    3600sph / (count * 0.000005 * 4550)

    Count will be a maximum of 10,000

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: PBPro Maths Help

    Does this code look correct to implement the formula?


    'Formula Speed = 3600 / (Local * 0.000005 * 4550)

    Dummy = Local * 5
    Local = 10000
    Dummy = Dummy * 4550
    Dummy = DIV32 Local
    Count1 = 36000
    Local = Count1 * 10000
    Speed = div32 Dummy
    Speed = Speed / 1000

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