Converting milliseconds to frequency


Closed Thread
Results 1 to 23 of 23
  1. #1
    Join Date
    Aug 2007
    Posts
    23

    Question Converting milliseconds to frequency

    I have code written to measure the time period of a square waveform using pulsin . I measure the low time and the high time and add them together and send it to an LCD. It is quite accurate (comparing to scope) and the refresh time is fast as the frequency varies. Knowing that frequency is 1/time, how can one go about doing the math in PBP to calculate the frequency of this waveform? Thanks.

    This is either very easy or a bigger problem than it seems.

    Here is the main loop: I found that I needed to do the 4/5ths thing to get the time more accurate.


    loop: pulsin PORTA.1,0,x
    x = x / 100

    pulsin PORTA.1,1,y
    y = y / 100

    z = x + y
    z = z * 4
    z = z / 5

    LCDOUT $fe, $C0
    LCDOUT " "
    LCDOUT $fe, $C0
    LCDOUT #z

    Goto loop
    Last edited by chips123; - 1st September 2007 at 01:47. Reason: More information

  2. #2
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    i may be able to help, but ive got a few questions:

    is the variable z a byte or a word?
    what is the unit of z? *edit* Cancel that question... Just read the thread topic
    what resolution is required? i.e. whats the smallest change in frequency that you would need to detect?
    what is the highest and lowest frequency you need to detect?
    Last edited by Kamikaze47; - 3rd September 2007 at 19:57.

  3. #3
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Default

    Thanks for the reply.

    I made all variables words to give myself plenty of room, at least for now.
    Ultimately, I want to get to pulses per minute, ie. RPMs with a range from maybe 240 RPM (4 cycles per sec) to maybe 4000 or 5000 (66 Hz to 85 Hz), give or take. I am flexible to a point. As far as resolution goes, something like 100 RPM increments (~2 Hz ?). Make any sense?

  4. #4
    Join Date
    Jul 2007
    Location
    Grass Valley CA
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    Frequency is the reciprocal of time. For example, if you measure your square wave as 16.66...milliseconds, you have a 60 Hz. frequency.

    Now, dependent on whether your milliseconds are floating point (many decimal places), you can measure frequency with concomitant resolution. That is, if time is an integer and you only have choices of 16 or 17 milliseconds, the frequency comes out 62 Hz. or 58 Hz. respectively while the actual waveform is 60 Hz..

    Jim

  5. #5
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Default

    With my millisecond values are integers, I don't expect 100% accuracy. Using PBP, how do I get from say, 16mS to 62Hz ?

    Scott

  6. #6
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    You can write a subroutine to determine the RPM from the z value. If to the nearest 100rpm is acceptable, this is the relevant data:

    Code:
    z           rpm
    -------------------------
    <10         out of limits
    10          6000
    11          5500
    12          5000
    13          4600
    14          4300
    15          4000
    16          3800
    17          3500
    18          3300
    19          3200
    20          3000
    21          2900
    22          2700
    23          2600
    24          2500
    25          2400
    26          2300
    27          2200
    28-29       2100
    30          2000
    31-32       1900
    33-34       1800
    35-36	    1700
    37-38	    1600
    39-41	    1500
    42-44	    1400
    45-48	    1300
    49-52	    1200
    53-57	    1100
    58-63	    1000
    64-70	    900
    71-80       800
    81-92       700
    93-109      600
    110-133     500
    134-171     400
    172-240     300
    241-400     200
    401-1200    100
    >12000      out of limits
    If you need help on how to write a subroutine to do this then let me know and i can help you out.

  7. #7
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Default

    I am a bit of a rookie. Some direction would be much appreciated.

  8. #8
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    I had a few spare mins so i wrote up a subroutine that would work. Im sure its not the most elegant piece of code, but it will do what you want just fine.

    It will take the z value and store a relavant value into rpm. The value in rpm will be in hundreds of rpms. So if you write the value of the variable rpm to your lcd, followed by "00" it will display in rpms.

    If rpm=0 after the subroutine has run then the input was out of range.

    Code:
    convert_to_rpm:
    IF z<10 THEN rpm=0
    IF z=10 THEN rpm=60
    IF z=11 THEN rpm=55
    IF z=12 THEN rpm=50
    IF z=13 THEN rpm=46
    IF z=14 THEN rpm=43
    IF z=15 THEN rpm=40
    IF z=16 THEN rpm=38
    IF z=17 THEN rpm=35
    IF z=18 THEN rpm=33
    IF z=19 THEN rpm=32
    IF z=20 THEN rpm=30
    IF z=21 THEN rpm=29
    IF z=22 THEN rpm=27
    IF z=23 THEN rpm=26
    IF z=24 THEN rpm=25
    IF z=25 THEN rpm=24
    IF z=26 THEN rpm=23
    IF z=27 THEN rpm=22
    IF z>27 AND z<30 THEN rpm=21
    IF z=30 THEN rpm=20
    IF z>30 AND z<33 THEN rpm=19
    IF z>32 AND z<35 THEN rpm=18
    IF z>34 AND z<37 THEN rpm=17
    IF z>36 AND z<39 THEN rpm=16
    IF z>38 AND z<42 THEN rpm=15
    IF z>41 AND z<45 THEN rpm=14
    IF z>44 AND z<49 THEN rpm=13
    IF z>48 AND z<53 THEN rpm=12
    IF z>52 AND z<58 THEN rpm=11
    IF z>57 AND z<64 THEN rpm=10
    IF z>63 AND z<71 THEN rpm=9
    IF z>70 AND z<81 THEN rpm=8
    IF z>80 AND z<93 THEN rpm=7
    IF z>92 AND z<110 THEN rpm=6
    IF z>109 AND z<134 THEN rpm=5
    IF z>133 AND z<172 THEN rpm=4
    IF z>171 AND z<241 THEN rpm=3
    IF z>240 AND z<401 THEN rpm=2
    IF z>400 AND z<1201 THEN rpm=1
    IF z>1200 then rpm=0
    return

  9. #9
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Default

    Thanks. A bunch of if-thens came to my mind as well. I just was not sure about it. I think I'll try it.

  10. #10
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Let us know how it goes

  11. #11
    Join Date
    Apr 2007
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by chips123 View Post
    With my millisecond values are integers, I don't expect 100% accuracy. Using PBP, how do I get from say, 16mS to 62Hz ?

    Scott
    Time and Frequency are reciprocal, so you can use a constant (in this case 1000) and divide you mS value into it. For example:

    1000 / 16mS = 62Hz.

    Or if you had 40mS -

    1000 / 40mS = 25Hz etc.

    You are probably kicking yourself right about now

    Regards,

    Andy

  12. #12
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    That would work, but that kind of division in PBP would take up a lot more processing time than the IF...THEN statements above.

  13. #13
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default

    I may not be understanding something here.

    For the basic math, I would have said:

    rpm=60000/z

    where z is in milliseconds.

    That would work, but that kind of division in PBP would take up a lot more processing time than the IF...THEN statements above.
    My question is: Why would doing that single division take longer than going through multiple IF...THEN statements (40-something of them in the example) until one is found where the condition is satisfied?

    Thanks to whomever clarifies this for me!
    Last edited by RussMartin; - 5th September 2007 at 05:38.
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  14. #14
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Thumbs up

    Thanks Andy.....kick, kick, kick...
    And Russ...equally good insight. I'll kick myself once for you too.
    Almost too obvious, I have been away from math for too long.

    Kamikaze...I tried your solution and ran into an exceeded address 3fff, if I remember correctly. I got sidetracked and have not investigated that further yet.

    Appreciate the input.
    Scott

  15. #15
    Join Date
    Jul 2007
    Posts
    53


    Did you find this post helpful? Yes | No

    Question Then, when should we use lookup ???

    All this thread bring back a question that I had in mind for a while. I was wondering at which point is that better (faster) to use lookup instead of calculated values?

    I know that I can find thread like "Sine wave power inverter" where a lookup table was used to increase calculation's speed. But is this only a trial an error process or can someone bring up guidelines that will lead to use one solution or the other?

    J-P
    Last edited by GrandPa; - 5th September 2007 at 03:48.

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


    Did you find this post helpful? Yes | No

    Question

    One more thought . . . instead of 40 IF THEN loops would't SELECT CASE be more appropriate? I throw this out there, having NEVER used select case, because you see, I want to learn too . . .
    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.

  17. #17
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default

    That would work, but that kind of division in PBP would take up a lot more processing time than the IF...THEN statements above.
    My question is: Why would doing that single division take longer than going through multiple IF...THEN statements (40-something of them in the example) until one is found where the condition is satisfied?

    Thanks to whomever clarifies this for me!
    I'm sure that SELECT CASE could be used, or LOOKDOWN (or should it be LOOKUP?), depending on the strategy, and maybe more effectively than IF...THENs. In all of those cases, though, it still looks like a bulky approach. I'm still not convinced that the single 16-bit division isn't going to be not only simpler but faster.

    Any thoughts? Is this one of those balancing acts between compact code and speed of operation?

    Scott, how often do you need to update the display with new information?
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

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


    Did you find this post helpful? Yes | No

    Default

    Here is all the IF/THENS in ASM
    Code:
    	LABEL?L	_convert_to_rpm	
    
    	CMPGE?BCL	_z, 00Ah, L00001
    	MOVE?CB	000h, _rpm
    	LABEL?L	L00001	
    
    	CMPNE?BCL	_z, 00Ah, L00003
    	MOVE?CB	03Ch, _rpm
    	LABEL?L	L00003	
    
    	CMPNE?BCL	_z, 00Bh, L00005
    	MOVE?CB	037h, _rpm
    	LABEL?L	L00005	
    
    	CMPNE?BCL	_z, 00Ch, L00007
    	MOVE?CB	032h, _rpm
    	LABEL?L	L00007	
    
    	CMPNE?BCL	_z, 00Dh, L00009
    	MOVE?CB	02Eh, _rpm
    	LABEL?L	L00009	
    
    	CMPNE?BCL	_z, 00Eh, L00011
    	MOVE?CB	02Bh, _rpm
    	LABEL?L	L00011	
    
    	CMPNE?BCL	_z, 00Fh, L00013
    	MOVE?CB	028h, _rpm
    	LABEL?L	L00013	
    
    	CMPNE?BCL	_z, 010h, L00015
    	MOVE?CB	026h, _rpm
    	LABEL?L	L00015	
    
    	CMPNE?BCL	_z, 011h, L00017
    	MOVE?CB	023h, _rpm
    	LABEL?L	L00017	
    
    	CMPNE?BCL	_z, 012h, L00019
    	MOVE?CB	021h, _rpm
    	LABEL?L	L00019	
    
    	CMPNE?BCL	_z, 013h, L00021
    	MOVE?CB	020h, _rpm
    	LABEL?L	L00021	
    
    	CMPNE?BCL	_z, 014h, L00023
    	MOVE?CB	01Eh, _rpm
    	LABEL?L	L00023	
    
    	CMPNE?BCL	_z, 015h, L00025
    	MOVE?CB	01Dh, _rpm
    	LABEL?L	L00025	
    
    	CMPNE?BCL	_z, 016h, L00027
    	MOVE?CB	01Bh, _rpm
    	LABEL?L	L00027	
    
    	CMPNE?BCL	_z, 017h, L00029
    	MOVE?CB	01Ah, _rpm
    	LABEL?L	L00029	
    
    	CMPNE?BCL	_z, 018h, L00031
    	MOVE?CB	019h, _rpm
    	LABEL?L	L00031	
    
    	CMPNE?BCL	_z, 019h, L00033
    	MOVE?CB	018h, _rpm
    	LABEL?L	L00033	
    
    	CMPNE?BCL	_z, 01Ah, L00035
    	MOVE?CB	017h, _rpm
    	LABEL?L	L00035	
    
    	CMPNE?BCL	_z, 01Bh, L00037
    	MOVE?CB	016h, _rpm
    	LABEL?L	L00037	
    
    	CMPGT?BCB	_z, 01Bh, T1
    	CMPLT?BCB	_z, 01Eh, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00039
    	MOVE?CB	015h, _rpm
    	LABEL?L	L00039	
    
    	CMPNE?BCL	_z, 01Eh, L00041
    	MOVE?CB	014h, _rpm
    	LABEL?L	L00041	
    
    	CMPGT?BCB	_z, 01Eh, T1
    	CMPLT?BCB	_z, 021h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00043
    	MOVE?CB	013h, _rpm
    	LABEL?L	L00043	
    
    	CMPGT?BCB	_z, 020h, T1
    	CMPLT?BCB	_z, 023h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00045
    	MOVE?CB	012h, _rpm
    	LABEL?L	L00045	
    
    	CMPGT?BCB	_z, 022h, T1
    	CMPLT?BCB	_z, 025h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00047
    	MOVE?CB	011h, _rpm
    	LABEL?L	L00047	
    
    	CMPGT?BCB	_z, 024h, T1
    	CMPLT?BCB	_z, 027h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00049
    	MOVE?CB	010h, _rpm
    	LABEL?L	L00049	
    
    	CMPGT?BCB	_z, 026h, T1
    	CMPLT?BCB	_z, 02Ah, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00051
    	MOVE?CB	00Fh, _rpm
    	LABEL?L	L00051	
    
    	CMPGT?BCB	_z, 029h, T1
    	CMPLT?BCB	_z, 02Dh, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00053
    	MOVE?CB	00Eh, _rpm
    	LABEL?L	L00053	
    
    	CMPGT?BCB	_z, 02Ch, T1
    	CMPLT?BCB	_z, 031h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00055
    	MOVE?CB	00Dh, _rpm
    	LABEL?L	L00055	
    
    	CMPGT?BCB	_z, 030h, T1
    	CMPLT?BCB	_z, 035h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00057
    	MOVE?CB	00Ch, _rpm
    	LABEL?L	L00057	
    
    	CMPGT?BCB	_z, 034h, T1
    	CMPLT?BCB	_z, 03Ah, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00059
    	MOVE?CB	00Bh, _rpm
    	LABEL?L	L00059	
    
    	CMPGT?BCB	_z, 039h, T1
    	CMPLT?BCB	_z, 040h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00061
    	MOVE?CB	00Ah, _rpm
    	LABEL?L	L00061	
    
    	CMPGT?BCB	_z, 03Fh, T1
    	CMPLT?BCB	_z, 047h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00063
    	MOVE?CB	009h, _rpm
    	LABEL?L	L00063	
    
    	CMPGT?BCB	_z, 046h, T1
    	CMPLT?BCB	_z, 051h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00065
    	MOVE?CB	008h, _rpm
    	LABEL?L	L00065	
    
    	CMPGT?BCB	_z, 050h, T1
    	CMPLT?BCB	_z, 05Dh, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00067
    	MOVE?CB	007h, _rpm
    	LABEL?L	L00067	
    
    	CMPGT?BCB	_z, 05Ch, T1
    	CMPLT?BCB	_z, 06Eh, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00069
    	MOVE?CB	006h, _rpm
    	LABEL?L	L00069	
    
    	CMPGT?BCB	_z, 06Dh, T1
    	CMPLT?BCB	_z, 086h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00071
    	MOVE?CB	005h, _rpm
    	LABEL?L	L00071	
    
    	CMPGT?BCB	_z, 085h, T1
    	CMPLT?BCB	_z, 0ACh, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00073
    	MOVE?CB	004h, _rpm
    	LABEL?L	L00073	
    
    	CMPGT?BCB	_z, 0ABh, T1
    	CMPLT?BCB	_z, 0F1h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00075
    	MOVE?CB	003h, _rpm
    	LABEL?L	L00075	
    
    	CMPGT?BCB	_z, 0F0h, T1
    	CMPLT?BCB	_z, 00191h, T2
    	LAND?BBW	T1, T2, T2
    	CMPF?WL	T2, L00077
    	MOVE?CB	002h, _rpm
    	LABEL?L	L00077	
    
    	CMPGT?BCB	_z, 00190h, T1
    	CMPLT?BCB	_z, 004B1h, T2
    	LAND?BBW	T1, T2, T2
    
    	CMPF?WL	T2, L00079
    	MOVE?CB	001h, _rpm
    	LABEL?L	L00079	
    
    	CMPLE?BCL	_z, 004B0h, L00081
    	MOVE?CB	000h, _rpm
    	LABEL?L	L00081	
    
    	GOTO?L	_convert_to_rpm
    And here is the WORD division in ASM.
    Code:
    	LABEL?L	_TEST	
    
    	MOVE?CW	003E8h, _FREQ
    
    	MOVE?CW	010h, _SPEED
    
    	DIV?WWW	_FREQ, _SPEED, _ROTATIONS
    
    	GOTO?L	_TEST
    Do not know about CASE either.
    Last edited by mackrackit; - 5th September 2007 at 20:32.
    Dave
    Always wear safety glasses while programming.

  19. #19
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Thumbs up

    Thanks, Dave! That was a lot of extra effort to answer the question, but I appreciate it. I'm sure others will, too!

    Scott--what do you think?
    Last edited by RussMartin; - 5th September 2007 at 22:31.
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

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


    Did you find this post helpful? Yes | No

    Default

    No problem, PBP did all of the work.
    Dave
    Always wear safety glasses while programming.

  21. #21
    Join Date
    Aug 2007
    Posts
    23


    Did you find this post helpful? Yes | No

    Thumbs up

    Russ...The 60000 math thing worked great. The digits changing on the LCD actually looks quite natural and "smooth". It doesn't look jerky. It is faster that you can read.

    I applied all of this to another project where I am driving a stepper motor as a position indicator, ie. a needle on a scale. I am quite satisfied with it.

    The only issue I see with my current calculations is that a change in a millisecond at the high end of the scale represents a larger change in RPM than a millisecond does at the lower speeds. This makes the needle seem a bit twitchy at the higher speeds. I plan to see what I can do to improve that somewhat.

    I initially attempted this project using COUNT . It worked, but moving the needle was painfully slow.

    Thanks for all the input
    Scott
    Last edited by chips123; - 6th September 2007 at 01:54.

  22. #22
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default

    Scott--Can you give us a better idea of the position indicator circuit and approach? Maybe we can come up with a way to damp the flutter.
    Last edited by RussMartin; - 6th September 2007 at 04:56.
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  23. #23
    Join Date
    Mar 2006
    Location
    China
    Posts
    266


    Did you find this post helpful? Yes | No

    Default What PIC and osc fq?

    Hi,

    What frequency do you run the PIC on? The faster you run it the more resolution you will get. My experience with Pulsin has been between great and failure and in the end I usually end up having to write my own code using a Timer. Timers are not that difficult to use and if you have a built in HPWM with capture and compare function it is not that bad at all :-)

    If you don't have that Darryl's instant interupts can be used for this as well. Especially together with external interupt sources. or a simple if-then loop or wend or whatever loop is also ok.....

    With a high ocs frequency and a timer you can get even parts of ms. 40 MHz would give you 0.1 ms in resolution. It would of course overflow the timer on low rpm's but then we just check for that and if it happens change the prescaler and try again... or we first do a Pulsin (same as now) to get the basic settings and then we do a new measurement right after using the best possible prescaler and a 16-bit timer to get a great value.


    You said you wanted the FQ right? Do the measurement with a timer over a longer time (i.e 16 periods (the ccp can be set up to capture several periods by itself)). Then you will get an even better resolution, the more periods you measure over the better it will be. I guess the stuff you are measuring dont change rpms that crazy fast either. What is spinning?

    /me
    Last edited by Jumper; - 6th September 2007 at 11:13.

Similar Threads

  1. HPWM command and oscillator frequency
    By RussMartin in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 8th March 2009, 22:41
  2. HPWM10 Frequency Updating
    By duncan303 in forum mel PIC BASIC Pro
    Replies: 17
    Last Post: - 19th January 2008, 12:30
  3. How do I convert an internal variable into frequency
    By schlaray in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 13th February 2007, 07:26
  4. inaccurate frequency using TMR1 PI18F452
    By nkarpovich in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 14th October 2006, 16:22
  5. frequency measurement
    By big-x in forum General
    Replies: 2
    Last Post: - 25th November 2005, 00:53

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