Hi all... as I promised this is the code...

This is a home project so code is GPL... see comments...

The hardware can and must be adjusted by serial port, see comments on the header of the file...

This code "as is" can count up to 5Mhz (in a proteus/isis simulation can reach to about 12 Mhz, but 5Mhz as clock/4 is the max safe value...)

on +5v RB3 the internal code will *8 the input freq
on +5v RB4 the internal code will *64 the input freq
both RB3 and RB4 at +5v will *8*64 the input freq

This ARE NOT push buttons, this is TTL levels

This is as you may guessed by now for prescaling purposes

Feel free to make any comments/suggestions/critics/etc...

On the next weeks I will build it for real (no more proteus/isis simulations) and will comment the results to the list.

This is my first complex code that will be burned to a "production" pic, so I'm very excited about it.

Cheers to all and thanks to all who give me ideas and tips about this...

Again: sorry any misspelling/typo/grammar etc... I'm a native Spanish speaking person, I'm trying to do my best at English...

El 03/08/13 11:05, Ing. Pavel Milanes Costa escribió:
Hey!!! ... this way works 130% (thanks Oliver Seitz)

I explain:

I use a PIC16F88, I set the isr routine for 1ms interrupt and counting
for 500ms, this is TMR0...

TMR1 is in pulse counter with prescaler 1:1, on overflow the interrupt
of TM1 increment a internal counter as a way of internal postcaler

Each 500ms the TMR1 and his internal postcaler is read & cleared.

Then the freq is computed, with a trick...

The pic is running XTAL at 20Mhz, so XTAL/4 is 5 Mhz (maximum freq to
measure), that is 5000000 pulses per seconds or 2500000 each 1/2 sec. or
38 * postcaler + remaining pulses... so postcaler is a byte var...

But the ISR of TMR0 & TMR1 puts a delay on the reading that depends on
the things the pic is doing in each cycle of the forever loop.

I adjust the delay as a percent of useful time on each postcaler cycle,
feeding the pic with almost full count before postcaler get incremented
and get by serial port the internal count, as I knows the freq I can say
how much pulses has to count for exact and how much pulses are the pic
counting...

For my experimentation the percent of adjust if in the order of 99%
(99.0298891% of the pic reading in my last calibration) and of course
this correction factor must be scaled to every postcaler count, normally
a postcaler count will be poscaller * 65536, but to adjust I compute
65536 * 99.0298891%  so.

Freq = poscaler * (65536 * 99.0298891%)
Freq = Freq + (pulses * 99.0298891%)

As we want an accurate reading, we have to work wit decimal shifting the
decimal point and div then, so

Corr_postcaler_pulses = (65536 * 99029) /100000 -- this is a constant
Corr_pulses = (pulses * 9903) / 10000
Freq = (postcaler * Corr_postcaler_pulses) + Corr_pulses

And as I'm reading 1/2 sec

Freq = Freq * 2

This give me an accuracy of about +/- 10 Hz at 5Mhz (4.99M) in the
proteus simulation, I know that the stability of the 20Mhz XTAL and the
source under measure will mask this error, but nevertheless this is GOOD
accuracy..

This is the best method I have tried and the freq_meter is in his 4.0
version (aka 4th method)

Then with a external prescaler of 8 (5Mhz * 8) I can count up to 40
Mhz... the external prescaler can be a pair of 74hc74 (3 half in 3 bit
count = /8  this can work up to 60-80 Mhz range)

Here I can find a 250 Mhz /64 & /65 prescalers as well as 1Ghz /2 & /4 &
/8 external prescaler,

So, I can make it with 5 scales

1Ghz    (/8 + /64 = out max 1.9Mhz, error max ~10Khz)
250Mhz    (/64 = out max 3.9Mhz, error max ~1.2Khz)
40Mhz    (/8 = out max 5.0Mhz, error max ~150hz)
5Mhz    (direct, error max ~20hz)
500Khz    (direct, error max ~2hz)

The core counting engine is working, I'm working on the lcd output
formatting, external prescaling & serial interface to externally adjust
for freq compensation via serial on the final hardware.

I'm thinking also in a abbreviated/full display option kind of

145.170051 Mhz => 145.170 Mhz
  51.110402 Mhz =>  51.1104 Mhz

For "masking" the error when full accuracy is not needed

And even a averaging of the last n readings for stable display numbers
and accurate readings on > 100 Mhz freqs when the error gets bigger

When I have a working piece of this functions I will post the example to
the list.

Thanks to all for the ideas and tips...

Cheers.

El 31/07/13 09:50, Oliver Seitz escribió:
My way would be:

On overflow, increment an additional upper counter, and just leave the
timer running until the time has passed. You can use variables as big as
you want in JAL. So there's no need for prescalers, as long as the timer
can keep up with the external frequency.

On 18F26K22 chips, for example, in asyncronous mode, the timers can
count 16MHz. Counting one second, the timer could overflow
(16000000/65536=) 244 times, so only an additional one-byte variable is
needed to count that frequency with 1Hz resolution.

To count hundreds of MHz, you need to start with a high setting on the
external prescaler, for you can't know if the frequency is too high for
the timer and it might miss pulses then.

A microcontroller can easily do thousands of interrupts per second
without "going crazy", don't worry. I've had programs where interrupts
occured only a few microseconds after another. This was on 64MHz, though.

Greets,
Kiste


------------------------------------------------------------------------
    *Von:* Ing. Pavel Milanes Costa <[email protected]>
    *An:* [email protected]
    *Gesendet:* 14:46 Mittwoch, 31.Juli 2013
    *Betreff:* Re: [jallib] Freq Counter? + break a _usec_delay()
    instruction?

    Hi to all...

    Last night I was thinking on the bed before sleep... I think there is
    another more elegant KISS solution...

    On overflow, STOP the counting (unset TMR1ON), and then stop the
    counting and the overflow process...

    As simple as that...

    I will try it in the afternoon, I will update to all about the
progress
    of this instrument...

    Cheers...


    El 30/07/13 23:44, Ing. Pavel Milanes Costa escribió:
     > Hi all again.
     >
     > With your ideas and code I'm writing a frequency meter.
     >
     >  From 0hz to 280 Mhz using various "prescalers" in conjunction
    (variable
     > time of sampling + internal prescaler of TM1 + external
prescalers)
     >
     > The most interesting features is that it "will have" an "auto
scale"
     > feature, for make readings with the more exact method for the
    freq being
     > measured (aka. minimizing the error for that freq)
     >
     > But... (as always) I have a problem...
     >
     > I need to BREAK the counting of a running _usec_delay()
    instruction from
     > a interrupt routine...
     >
     > I explain (code attached):
     >
     > I start counting TMR1 pulses on RB6 for 1 sec time lapse, and with
     > interrupts on the overflow of it I detect the need of jump on the
    "range
     > / scale", then I change any of the sampling period, internal
    prescaler
     > and/or external prescaler to suit the next scale and then you
have a
     > autorange freq. meter...
     >
     > The problem is found when I measure a freq that is much BIGGER
    for the
     > initial sampling period of 1s...
     >
     > Think on it and dive in the code....
     >
     > 7110khz (7110000 pulses in ONE second) is around 108 interrupts
    in ONE
     > second... so the autorange function goes crazy and get to the
top of
     > scale from overloaded interrupts per seconds...
     >
     > The obvious solution is breaking the _usec_delay() instruction
    from the
     > interrupt routine... that will require asm which I do not
know... or
     > another dirty trick...
     >
     > But, Hey!... I realize NOW that using another timer for setting
the
     > sampling period can be the solution... (GGGGGRRRRR somebody
    suggest this
     > before and I have not listen to it...)
     >
     > Yes, forcing the timer of the sampling period to timeout an
thereof
     > ending the sampling period will be the way...
     >
     > I will try that tomorrow, nevertheless, the code is attached,
    comments,
     > suggestions, etc, will be welcomed...
     >
     > I have the proteus project if anyone like to try it...
     >
     > Just ignore the lcd for now and attach a serial console at 38_400
    bauds
     > to the PIC and see the debug info...
     >
     > The code is a work in progress, no optimization or cleaning yet...
     >
     > Cheers... and enjoy it
     >
     > PS: Forgive my english if you found an error or two, I'm a spanish
     > speaking person...
     >
     > El 27/07/13 22:41, Ing. Pavel Milanes Costa escribió:
     >> Hi all.
     >>
     >> I'm here reading and searching but I can't find a way of counting
     >> asynchronous TTL pulses with jal/jallib over a given time slot...
     >>
     >> It must be done with the timer module of the pic... (I think...)
     >>
     >> I explain:
     >>
     >> I want to make a frequency counter for zero to 250 Mhz, with 2
    external
     >> prescaler, using direct counting for low freq's, med prescaler
    to about
     >> 50 Mhz and a dedicated prescaler for above 50 Mhz - 250 Mhz+
     >>
     >> But I have not a clue how to use the timer1 as an asynconous
16 bit
     >> pulse counter of the PIC16F88 I have for the project.
     >>
     >> Output will be to a cheap 4bit LCD or UART serial to a PC, click
    will be
     >> HS 20 Mhz XTAL...
     >>
     >> Other candidate is a PIC16F628 in my junkbox.
     >>
     >> Math is not a problem when I can say something like:
     >>
     >> <pseudo-code>
     >> a = count(pin_b1,100) -- count pulses on pin B1 for 100ms
     >> </pseudo-code>
     >>
     >> Any clue, sample code or tip is welcomed.
     >>
     >> 73 de CO7WT, Pavel in Cuba Island.
     >>
     >

    --
    You received this message because you are subscribed to the Google
    Groups "jallib" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [email protected].
    <mailto:[email protected].>
    To post to this group, send email to [email protected].
    <mailto:[email protected].>
    Visit this group at http://groups.google.com/group/jallib.
    For more options, visit https://groups.google.com/groups/opt_out.



--
You received this message because you are subscribed to the Google
Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/jallib.
For more options, visit https://groups.google.com/groups/opt_out.




--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/jallib.
For more options, visit https://groups.google.com/groups/opt_out.

Attachment: feq_counter_16F88_v4.1.jal
Description: application/wine-extension-jal

Reply via email to