PIC16F84A Tachometer LED routine


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10

    Default PIC16F84A Tachometer LED routine

    I'm writing a routine to a tachometer. I just doesn't work! I've searched the forum, but i haven't found anything that looks like this.


    Code:
    '****************************************************************
    '*  Name    : Tacho.BAS                                         *
    '*  Author  : Christian Lerche                                  *
    '*  Notice  : Copyright (c) 2008 Lerche                         *
    '*          : All Rights Reserved                               *
    '*  Date    : 07-10-2008                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : PIC16F84A @ 10 Mhz XT                             *
    '*          : XT osc, BODEN off, WD off                         *
    '****************************************************************
    'Include------------------------------------------------------------------------
    
    'Definitions--------------------------------------------------------------------                                     
    Define osc 10                          ' Define Osc as 10 Mhz
    DEFINE PULSIN_MAX 25000                ' Lowest RPM 600
    
    'Inputs/outputs-----------------------------------------------------------------
    TRISB = $80                            ' All PortB Output
    TRISA = $f0                            ' All PortA Output
    INPUT PORTA.4                          ' PortA.4 Input
    
    'Variables----------------------------------------------------------------------
    B0 VAR BYTE                            ' Define B0 as byte
    W1 var WORD                            ' Define W1 as word
         
    'Main program-------------------------------------------------------------------                                       
    loop:      
            IF PORTA.4 THEN                ' Wait until start of low pulse
                    GOTO MAIN1
                ELSE
                    GOTO loop
            ENDIF 
    MAIN1:
            PULSIN PORTA.4,0,W1            ' Measure pulse-width in 4µS resolution
            GOTO MAIN
    MAIN:
            W1 = W1 * 4                    ' Convert µS to mS
            W1 = (60000 / W1)              ' Revs in 60 mS
            W1 = W1 * 1000                 ' Revs in 60 sec
                GOSUB display              ' Go to display sobroutine       
            GoTo LOOP                      ' Do forever
            
    'Display subroutine------------------------------------------------------------- 
    display: B0 = W1 / 1000	               ' Find number of thousands
    	W1 = W1 // 1000	                   ' Remove thousands from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $17	                       ' Turn on fourth digit
    	Pause 1    		                   ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1 / 100	                   ' Find number of hundreds
    	W1 = W1 // 100	                   ' Remove hundreds from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1B	                       ' Turn on third digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1 / 10	                   ' Find number of tens
    	W1 = W1 // 10	                   ' Remove tens from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1D	                       ' Turn on second digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1		                       ' Get number of ones
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1E	                       ' Turn on first digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting
        Return		                       ' Return to main
                                           ' Routine copied from ledart.
    
    'Lookup table-------------------------------------------------------------------
    bin2seg:
        Lookup B0,[$40,$79,$24,$30,$19,$12,$02,$78,$00,$18],B0
    	Return
    Anyone got a clue, what is does wrong?

    Thanks in advance!

    / ThaSanta

  2. #2
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    What part does not work?
    Dave
    Always wear safety glasses while programming.

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


    Did you find this post helpful? Yes | No

    Wink

    Hi, Santa ( de bois )

    1) Just the usual gag with PORTA.4 ...

    Did you place an external pullup resistor or something to drive the pin to HIGH state ???


    2) I note 10 Mhz need a HS Osc ... ( but generally works with XT !!! )


    3)
    Code:
    MAIN1:
            PULSIN PORTA.4,0,W1            ' Measure pulse-width in 4µS resolution
            GOTO MAIN
    you'd better try

    Code:
    MAIN1:
            RCTIME PORTA.4,0,W1            ' Measure pulse-width in 4µS resolution
            GOTO MAIN

    4) your Mathematics are really bad for INTEGERS using ...


    W1 = W1 * 4 ' Convert µS to mS
    W1 = (60000 / W1) ' Revs in 60 mS
    W1 = W1 * 1000 ' Revs in 60 sec
    you'd much better use DIV32 ...



    That's the first hits ...

    Alain
    ************************************************** ***********************
    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 " !!!
    *****************************************

  4. #4
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    Sorry for letting the problem out (I was kinda tired).

    The attached image views the first digit of 4. As if the algorithm doesn't calculate the RPM correct.

    1) - I have not yet build the circuit, as I don't have a programmer.
    2) - I don't think the Simulator cares about HS or XT :-)

    3) I wrote RCTIME instead of PULSIN, but it didn't chance anything.

    Actually, after reading the manual to PBP, i don't know how to use DIV32.
    I've tried examples, but I still can't figure it out.


    - Thanks again guys. :-)
    Attached Images Attached Images  

  5. #5
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Red face is the Pic the good one ??? ... not so sure.

    Hi,

    The most annoying thing in your project is ... the PIC must drive continuously the 4 digits AND while that, must measure the rotation period.

    I think you'll quickly understand you'll have to use interrupts and ... a 16Bits timer ... what the 16F84 doesn't have aboard ...
    so, you'll also have to watch for TMR0 overflows ...to increment a 8 bits counter for the timer Upper 8 bits counting.

    Not really easy ( "asm" recommended here )... but doable.

    seeing your pain for the first steps ... I'd recommend you to switch to a 16F628a that has everything to EASILY realise such a RPM meter. ( I mean the capture module ... )

    The project is yours ... you are the one who decides !!!

    Alain
    ************************************************** ***********************
    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 " !!!
    *****************************************

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Acetronics View Post
    Hi, Santa ( de bois )
    1) Just the usual gag with PORTA.4 ...
    Did you place an external pullup resistor or something to drive the pin to HIGH state ???
    Only applies when using PortA.4 as an output...

    Quote Originally Posted by ThaSanta View Post
    2) - I don't think the Simulator cares about HS or XT :-)
    Arg! Simulators!

  7. #7
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    I think you'll quickly understand you'll have to use interrupts and ... a 16Bits timer ... what the 16F84 doesn't have aboard ...
    so, you'll also have to watch for TMR0 overflows ...to increment a 8 bits counter for the timer Upper 8 bits counting.
    I'll go along and try to use the CCP on Pic16F628A :-)
    I'll be back with updates.


    Thanks for the fast replies!
    / Lerche

  8. #8
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    edit:all good . . .
    Last edited by Archangel; - 20th October 2008 at 00:28. Reason: Remove
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  9. #9
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Here's one small problem...
    Code:
    Define osc 10                          ' Define Osc as 10 Mhz
    http://www.picbasic.co.uk/forum/showthread.php?t=558

  10. #10
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    I really think somethings wrong with the math. I just can't figure it out :/

    Now an example:
    Code:
    MAIN:
            W1 = W1 * 2                    ' To get whole period
            W1 = W1 * 4                    ' now the count is in mS
            W1 = (60000/W1)                ' Revs per 60 mS
            W1 = W1 * 1000                 ' Revs per minute
                GOSUB display              ' Go to display sobroutine       
            GoTo LOOP                      ' Do forever
    The input has a period of 12 mS (5000 RPM) - Which is 1500 increments @ 4µS.
    As I only measure the low part of the 50% duty-cycle, I multiply with 2. Full period.
    Then I multiply with 4. Now it's in mS. 12,000.
    60,000 / 12,000 = 5.
    5 * 1000 = 5000 RPM. NICE! - But i doesn't work.

    I have seriously no idea of why this shouldn't work.

    EDIT:
    And then i thought. Figure out when i goes wrong:
    So i tried to make the calculations. With a number, that wouldn't go straight up into 60,000. Example: 2000.
    2,000*2=4,000
    4,000*4=16,000
    60,000/16,000=3.75 <- I guess this is were the PIC can't follow my lead.
    3.75*1,000= 3750.
    Last edited by ThaSanta; - 20th October 2008 at 01:06. Reason: Adding more info
    / Lerche

  11. #11
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by ThaSanta View Post
    EDIT:
    And then i thought. Figure out when i goes wrong:
    So i tried to make the calculations. With a number, that wouldn't go straight up into 60,000. Example: 2000.
    2,000*2=4,000
    4,000*4=16,000
    60,000/16,000=3.75 <- I guess this is were the PIC can't follow my lead.
    3.75*1,000= 3750.
    Well, since PicBasicPro (nor the PIC itself) doesn't support floating point variables, it's not surprising...

  12. #12
    Join Date
    Apr 2007
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by ThaSanta View Post
    I'm writing a routine to a tachometer. I just doesn't work! I've searched the forum, but i haven't found anything that looks like this.


    Code:
    '****************************************************************
    '*  Name    : Tacho.BAS                                         *
    '*  Author  : Christian Lerche                                  *
    '*  Notice  : Copyright (c) 2008 Lerche                         *
    '*          : All Rights Reserved                               *
    '*  Date    : 07-10-2008                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : PIC16F84A @ 10 Mhz XT                             *
    '*          : XT osc, BODEN off, WD off                         *
    '****************************************************************
    'Include------------------------------------------------------------------------
    
    'Definitions--------------------------------------------------------------------                                     
    Define osc 10                          ' Define Osc as 10 Mhz
    DEFINE PULSIN_MAX 25000                ' Lowest RPM 600
    
    'Inputs/outputs-----------------------------------------------------------------
    TRISB = $80                            ' All PortB Output
    TRISA = $f0                            ' All PortA Output
    INPUT PORTA.4                          ' PortA.4 Input
    
    'Variables----------------------------------------------------------------------
    B0 VAR BYTE                            ' Define B0 as byte
    W1 var WORD                            ' Define W1 as word
         
    'Main program-------------------------------------------------------------------                                       
    loop:      
            IF PORTA.4 THEN                ' Wait until start of low pulse
                    GOTO MAIN1
                ELSE
                    GOTO loop
            ENDIF 
    MAIN1:
            PULSIN PORTA.4,0,W1            ' Measure pulse-width in 4µS resolution
            GOTO MAIN
    MAIN:
            W1 = W1 * 4                    ' Convert µS to mS
            W1 = (60000 / W1)              ' Revs in 60 mS
            W1 = W1 * 1000                 ' Revs in 60 sec
                GOSUB display              ' Go to display sobroutine       
            GoTo LOOP                      ' Do forever
            
    'Display subroutine------------------------------------------------------------- 
    display: B0 = W1 / 1000	               ' Find number of thousands
    	W1 = W1 // 1000	                   ' Remove thousands from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $17	                       ' Turn on fourth digit
    	Pause 1    		                   ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1 / 100	                   ' Find number of hundreds
    	W1 = W1 // 100	                   ' Remove hundreds from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1B	                       ' Turn on third digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1 / 10	                   ' Find number of tens
    	W1 = W1 // 10	                   ' Remove tens from W1
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1D	                       ' Turn on second digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting 
    	B0 = W1		                       ' Get number of ones
    	   Gosub bin2seg	               ' Convert number to segments
    	PortB = B0	                       ' Send segments to LED
    	PortA = $1E	                       ' Turn on first digit
    	Pause 1    	                       ' Leave it on 1 ms
    	PortA = $1F	                       ' Turn off digit to prevent ghosting
        Return		                       ' Return to main
                                           ' Routine copied from ledart.
    
    'Lookup table-------------------------------------------------------------------
    bin2seg:
        Lookup B0,[$40,$79,$24,$30,$19,$12,$02,$78,$00,$18],B0
    	Return
    Anyone got a clue, what is does wrong?

    Thanks in advance!

    / ThaSanta

    Please check this line:

    loop:
    IF PORTA.4 THEN ' Wait until start of low pulse


    Should it be:

    IF PORTA.4 = 0 THEN ' Wait until start of low pulse

    Andy

  13. #13
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Andy Wood View Post
    Please check this line:
    loop:
    IF PORTA.4 THEN ' Wait until start of low pulse
    Should it be:
    IF PORTA.4 = 0 THEN ' Wait until start of low pulse
    Andy
    Unless he's just making sure that the timing loop doesn't start in the middle of the pulse...

  14. #14
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Andy Wood View Post
    Please check this line:

    loop:
    IF PORTA.4 THEN ' Wait until start of low pulse


    Should it be:

    IF PORTA.4 = 0 THEN ' Wait until start of low pulse

    Andy
    - As Skimask says: I am making sure it is not starting from the middle of a period
    / Lerche

  15. #15
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Question

    Hi Christian,

    I'd like to be sure of one thing : what do you use as a rotation detector ???

    ... as in your calculations, the pulsin signal is supposed to be equal to the rotation period, something hurts me ... but what ???

    Alain
    ************************************************** ***********************
    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 " !!!
    *****************************************

  16. #16
    Join Date
    Oct 2008
    Location
    Denmark
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Acetronics View Post
    Hi Christian,

    I'd like to be sure of one thing : what do you use as a rotation detector ???

    ... as in your calculations, the pulsin signal is supposed to be equal to the rotation period, something hurts me ... but what ???

    Alain
    As it is, I am only using a simulator. I do not have a programmer.

    Actually, it's supposed to measure the RPM of a computer-fan. 50% duty-cycle. :-)
    / Lerche

  17. #17
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    ThaSanta, Here is a snipit of code I wrote about 4 years ago to do exactly what you are requesting..

    ASM
    PutMulResult macro Const32
    MOVE?CB low Const32, R2
    MOVE?CB low (Const32 >> 8), R2 + 1
    MOVE?CB low (Const32 >> 16), R0
    MOVE?CB low (Const32 >> 24), R0 + 1
    endm
    ENDASM

    PULSIN B_IN,1,POINTER1 'MEASURE HIGH PULSE
    IF POINTER1 > 0 THEN
    @ PutMulResult 15000000 ' Load PBP internal vars Max= 2,147,483,648
    POINTER2 = DIV32 POINTER1 ' Divide 15000000/(PERIOD/2)
    SCRATCH = R2 ' Get remainder of Div32
    ' Change remainder to Decimals
    SCRATCH = SCRATCH * 10000 ' Multiply remainder * 10,000
    SCRATCH = DIV32 POINTER1 ' Divide remainder by original divisor
    ELSE
    POINTER2 = 0
    SCRATCH = 0
    ENDIF
    LCDOUT $FE,LINE(1)
    PAUSEUS 100
    LCDOUT DEC5 POINTER2,".",DEC4 SCRATCH

    I hope it works for you... It did for me...

    Dave Purola,
    N8NTA

Similar Threads

  1. Conway's Game Of Life
    By wellyboot in forum mel PIC BASIC Pro
    Replies: 45
    Last Post: - 28th May 2020, 06:14
  2. Free Project - 245 LED Display
    By T.Jackson in forum Code Examples
    Replies: 221
    Last Post: - 16th August 2009, 04:59
  3. Single digit 7 Seg LED clock - PIC16F88
    By thirsty in forum Code Examples
    Replies: 4
    Last Post: - 17th July 2009, 08:42
  4. new and need help
    By smeghead in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 3rd November 2008, 20:19
  5. LCD will not start
    By btaylor in forum mel PIC BASIC Pro
    Replies: 49
    Last Post: - 24th May 2007, 02:30

Members who have read this thread : 0

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