Menu

Want to make a frequency meter

Help
Ryan
2016-08-23
2016-10-23
1 2 > >> (Page 1 of 2)
  • Ryan

    Ryan - 2016-08-23

    I would like to make a frequency meter that will read the frequency on a pin and store it as a varible so that i can edit it and transmit that varible out, i would like to use a 12f683 to do this, i m not to familiar with the timers and interrupt stuff, my range would be from about 200khz to 800khz that i want to measure, any help would be greatly appreciated,
    Thanks

     
  • Ryan

    Ryan - 2016-08-26

    Heres what I got so far, just trying to get an accurate time value, its not calculated yet, but it does not transmit the varible until i disconnect the input pin, like the interrupt keeps it from sending out?

    chip 12F683, 8 'mhz

    config INTRC_OSC_NOCLKOUT, MCLRE=off, WDT=off, boden=off', OSC=INTOSC

    dir gpio.0 out 'serial
    dir gpio.1 in 'freq
    dir gpio.2 out
    dir gpio.3 in
    dir gpio.4
    dir gpio.5
    dim lcdvalue as Word
    dim LCDValueTemp as word
    InitSer 1, r9600, 1, 8, 1, none, normal

    define SendAHigh Set gpio.0 ON

    define SendALow Set gpio.0 OFF

    'on interrupt Timer1Overflow call IncCounter
    DataCount = 0
    dim lcdvaluetemp as word
    dim lcdvalue as word
    InitTimer1 Osc, PS1_1
    Dim TimerValue As Word
    dim full as word
    full = 0

    main:
    serprint 1, "testing"
    Do
    ClearTimer 1
    TMR1L = 0 'Need to do this according to the PIC datasheet
    TMR1H = 255
    TMR1L = 82
    Wait Until readad(an1) > 17 'gpio.0 = Off
    StartTimer 1
    On Interrupt Timer1Overflow Call IncCounter
    Wait Until readad(an1) < 17 'gpio.2 = off
    StopTimer 1
    IntOff

    'Read the timer
     TimerValue = Timer1
    
     'bin2ascii2(full_H)
     serprint 1, "freq="
    

    Bin2ascii full

    full = 0
    'Log the timer value
    'EPWrite(DataCount, TimerValue_H)
    'EPWrite(DataCount + 1, TimerValue)
    'DataCount = datacount + 2
    

    wait 250 ms
    IntOn
    Loop
    goto main

    Sub IncCounter
    TMR1L = 0
    TMR1H = 255
    TMR1L = 82
    full=full+1
    end sub

    sub Bin2ascii (LCDValue)#NR
    sertho = 0
    SERCEN = 0
    SERDEC = 0
    SERUN = 0
    LCDValueTemp = 0

    lcdvaluetemp = lcdvalue / 1000
    SERtho = LCDValueTemp + 48
    if sertho > 48 then Sersend 1, Sertho
    LCDValue = lcdvalue - LCDValueTemp * 1000

    lcdvaluetemp = lcdvalue / 100
    SERCEN = LCDValueTemp + 48
    Sersend 1, sercen
    LCDValue = LCDValue - LCDValueTemp * 100

    LCDValueTemp = LCDValue / 10
    SERDEC = LCDValueTemp + 48
    Sersend 1, serdec
    LCDValue = LCDValue - LCDValueTemp * 10
    SERUN = LCDValue + 48
    SerSend 1, serun
    end sub

     
  • kent_twt4

    kent_twt4 - 2016-08-27

    Well that is a start, and something to build on. Need more information as to the type and nature of the signal being measured. Is the frequency being measured a digital or analog?, squarewave, sinewave, or?

    At first look, it looks like a period measurement of some kind is taking place. So a different methodology than the original question. My vision is not so good, so could be off on your intent.

    If this is indeed a high frequency measurement, than one would be counting the number of peaks over a convienant period of time like 100ms, 250ms, 500ms, 1000ms. With a 8:1 prescale, Timer1 1/(8000000/4) * 65535 = 0.26214 sec, so that could be used for the sample period. CCP could also be used here, as it has a mirrored set of Timer1 registers and a special software interrupt. Then use the T0CKI pin for the high frequency input to Timer0 and check for overflows, and read of the TMR0 register, at the end of the period.

    I would not be afraid to check the timer overflow flags in software, could save on valuable instructions. Not sure about using the adc here, but then that just depends on the first questions.

     
  • mkstevo

    mkstevo - 2016-08-28

    There was this post: Measure Pulse Width which details how to measure the period of a pulse. As frequency can be determined from the period, maybe you could adapt some of the principles detailed?

    I remember thinking at the time how elegant it looked, and much better than my attempts to do something similar on another 'Basic' product.

     

    Last edit: mkstevo 2016-08-28
  • Ryan

    Ryan - 2016-08-29

    Im trying to measure the frequency of a inductor circuit so the waveform is kinda a sawtooth, thats hy i was using the adc so i could adjust the trigger levels, my goal is to get the period then mathmaticly make it into the frequency for display, if i could count the peaks over a period that would work as well, i just need to get a accurate measurement or count that i can work with to get the end result.

    Would the measure pulses width example be easy to adapt to a 12f683? im not to familiar with the timers and ccp/interupt uses?
    Thanks

     
  • Ryan

    Ryan - 2016-08-29

    I tried using this, but not getting what i would expect, likely i didn't configure something right with the ccp stuff:

    InitTimer1 Osc, PS1_8

    main:
    serprint 1, "testing"
    do 'MAIN LOOP
    PULSE_IN 'Get positive pulse width.
    Bin2ascii PULSE_WIDTH
    Loop

    MACRO PULSE_IN 'Measure Pulse Width
    'Configure CCP1 to Capture rising edge
    CCP1CON = 5 '00000101
    StartTimer 1
    CCP1IF = 0

    do while CCP1IF = 0 'Wait for rising edge
    loop
    TMR1H = 0: TMR1L = 0 'Clear timer to zero
    CCP1IF = 0 'Clear flag
    'Configure CCP1 to Capture Falling Edge
    CCP1CON = 4 '00000100'

    do while CCP1IF = 0 'Wait for falling edge
    loop
    StopTimer 1 'Stop the time
    Pulse_Width = TIMER1 'Save the timer value
    CCP1IF = 0 'Clear the CCP1 flag
    End MACRO
    goto main

    I cut of the top section just to save room

     
  • kent_twt4

    kent_twt4 - 2016-08-30

    I think the way forward is to use the comparator module to measure the triangle pulses. The 12f683 data sheet figure 8.1 describes the situation at hand. Use mode CM<2:0> = 100 for the internal CVref and Cout. Next look at section 8.9 for the conditions required to export the internal Cout to the Timer1 Gate and synchronize them. Use the VRCON register to setup the CIN+ voltage reference level.

    Timer0 is left to measure the period. With the huge prescaler, one should be able to set just about any sort of period required. That would require counting interrupts on overflow. I would be inclined to count the overflows in software and increment a variable each time. But for simplicity it would be easy to set up an interrupt. Take a look at Help, and set up a "On Interrupt Timer0Overflow Call XXXX" to increment the counter till the period measured is obtained. Read the Timer1 Registers for the number of pulses the comparator has measured.

    An alternate scenario is to use Timer0 to count pulses and Timer1 to measure the period. Then reverse roles and send COUT externally to use T0CKI for Timer0 input to do the pulse counting and Timer1 for the period measurement.

    If accuracy is a requirement then a crystal OSC would be handy.

     
  • Ryan

    Ryan - 2016-08-30

    whew....over my head a bit, the timer comparator stuff gets complex, could you help me out a bit here please

     
  • Ryan

    Ryan - 2016-08-30

    I read thru the datasheet and from what i get the example i posted 2 posts ago should be working?any idea why its not?

     
  • kent_twt4

    kent_twt4 - 2016-08-31

    I set up a 10kHz triangle wave from an old Elenco Electronics function generator. Fed it into the comparator in the 011 configuration which uses the internal Vref and outputs on COUT pin. The COUT pin is multiplexed with Timer0 T0CKI pin. The COUT makes a nice square wave at Vdd. So lets try that out for counting pulses.

    When bumping up to 100kHz and beyond, prescales may need to be changed, along with my methodology for loading the counting variable. Anyway with the prescale at 64 I picked up 156 or 157 counts (.9984 or 1.001 sec). Not too scientific. Haven't used the TMR1 for the period or tried a crystal osc yet.

    Was having problems with the prescaler, until I figured out the Option_Reg should be written as a whole, and not just the bits.

    #chip 12F683, 8 'mhz
    
    dir gpio.0 out 'serial
    dir gpio.1 in 'freq
    dir gpio.2 out  'COUT
    'dir gpio.3 in
    'dir gpio.4
    'dir gpio.5
    dim lcdvalue as Word
    dim LCDValueTemp as word
    InitSer 1, r9600, 1, 8, 1, none, normal
    #define SendAHigh Set gpio.0 ON
    #define SendALow Set gpio.0 OFF
    
    CMCON0 = b'00010011'
    'CMCON1: Clear T1GSS for Timer 1 Gate source
    'Set CMSYNC to synch COUT with TIMER1 clock
    'T1GSS = 0
    'CMSYNC = 1
    CMCON1 = 1
    'adusted VR bits to approximately 50% duty cycle
    VRCON = b'10001110'
    'Enable Timer1 gate, set prescale 1:4
    'T1CON = b'11110001'
    'Option_Reg:
    Not_GPPU = 1
    INTEDG = 0
    T0CS = 1
    PSA = 0
    PS2 = 1    '111=256, 110=128, 101=64, 100=32
    PS1 = 0    '011=16, 010=8, 001=4, 000=2
    PS0 = 1
    Dim COUTTicks as Word
    Dim Overflow as Word
    On Interrupt Timer0Overflow Call IncrCounter
    ' for 10 kHz signal PS = 64 Get 10001 ticks
    'for 100 kHz signal PS = 256 Get
    Main:
    Do
    'TMR1L = 0
    'TMR1H = 0
    overflow = 0
    TMR0 = 0
    wait 1 s
    COUTTicks = TMR0
    COUTTicks_H = overflow '* 256
    
    SerPrint 1,Overflow
    SerPrint 1,",  "
    SerPrint 1,COUTTicks
    sersend 1,10
    sersend 1,13
    wait 2 s
    Loop
    goto Main
    
    sub IncrCounter
    overflow += 1
    end sub
    
     
  • Ryan

    Ryan - 2016-08-31

    Kent,
    When i run your code I just get "0, 0" no matter what i put on the input pin, also i dont see a command to start the timer? and to be clear the Cout is internally connected and I dont need to add an external jumper correct?
    Thanks for all your help by the way

     
  • kent_twt4

    kent_twt4 - 2016-09-01

    I think you need to reconcile the input signal voltage to the VRCON register bits. This is the behavior that I have observed also. May have to use a voltage divider, as I noticed a more stable behavior at lower input signal for some reason. Could be trial and error here. Do you have a scope, and verified the type of input?

    When you say an inductor is involved, this isn't a switching power supply?, as heavy filter caps make that DC with x amount of noise on top of that.

    Timer0 runs continously no matter what, a system clock if you will. No external jumper required for Cout with comparator in 011 config and T0CS = 1.

     
  • Ryan

    Ryan - 2016-09-01

    I used a function generator and a scope and put in 1v, 2v, 3v, 4v and 5v waveforms at 7khz and still got nothing out but "0, 0". my end circuit is actually using two transistors to oscilate when a inductor is hooked up and then the frequency of the circuit gives you the ability to calculate inductance value, so no caps at all on the input.

     
  • kent_twt4

    kent_twt4 - 2016-09-02

    I was using the pk2 programmer and also tried a li-ion battery for power. I found that the pk2 power at 5v seemed to work better than the battery. Then I got to thinking the red button pk2 has internal weak pullups on the DAT and CLK lines for debugging if remember correctly. I experimented with 10k pullup on the input, and it certainately didn't hurt, might have helped.

    But in playing with pullups and pulldowns and scratching around I may have killed the CIN- pin on the 12f683. Or, it may have been about the time I put a new battery in, and needed to mess with the VR bits some more. In any case, have moved on to a 12f1822, with new config registers to play with now. Using the same 64 prescale as before it moves up and down now from 9kHz to just over 100kHz no problem. It gets the expected 390 Timer0 overflows plus the remainder TMR0 register at 100kHz.

    My Elenco is on battery power so the signal voltage is constantly decreasing. It starts around 4V and is now just under 3V with the newer battery. When playing with the 12f683 it may have been under 2V at the end of the old battery.

    Suggest scoping the COUT pin, comment out (i.e. ignore) the Option register bits ffor now and verify that a square wave is produced. Until then, shooting in the dark. If you have another 12f683 try that too.

     
  • Ryan

    Ryan - 2016-09-02

    So just taking stabs at it i discovered that if I put the input pulse on the gpio.2 pin i actually get counts but nothing when its on the gpio.1 pin? at a prescaller of 1_256 i get a result of "1, 390" with a input of 100khz, does that seem in the ballpark, and if so why? i put the scope on my cout pin and didn't see a waveform coming out before i tried poking around also?

     
  • kent_twt4

    kent_twt4 - 2016-09-02

    Very good. This is a sqaure wave input? I had thought were talking a triangle wave, and thus the reason for the comparator. If a sqaure wave, then by all means hook it up to the GPIO.2 and forget the comparator altogether.

    So on to the math :). 100kHz has 1cycle/T or T= 0.00001 sec. With the TMR0 prescale at 256 there will be 256 ticks before one tick is incremented in the register. With one 1 TMR0 overflow and XXX from the TMR0 register, it would be T x ((1 x (256*256) + XXX * 256) ticks during the one sec time. Timer0 is only an eight bit timer so 390 is not a plausable result from the TMR0 register. I recollect getting 390 overflows or "390, xxx" though when the prescale was 64.

    Lots to play with there to make it more efficient, accurate, responsive etc.

     
  • Ryan

    Ryan - 2016-09-02

    I am still using a triangle waveform, and it is picking it up. and i believe to issue with the number on the ticks was because you had put in a line that set the high 4 bit of the ticks to the overflow (the 7th line down after the DO command). So what do i need to take put to elimiante the compartor uses?

     
  • Ryan

    Ryan - 2016-09-02

    Also when i tried bumping the pic up to 20mhz with a resonator (OSC=XT) it no longer works?

     
  • kent_twt4

    kent_twt4 - 2016-09-02

    My Elenco must have some weak sauce, it will not drive the T0CKI pin directly :(. To get rid of the compartor stuff, then comment out CMCON0, CMCON1, and VRCON. Also no need for dir "GPIO.1 In"

     
  • kent_twt4

    kent_twt4 - 2016-09-02

    For 20Mhz usually need to go OSC=HS for the extra drive current.

     
  • Ryan

    Ryan - 2016-09-06

    Thanks Kent, it is working, took some signal conditioning to get my input to swing the full 5 volt range, but it is working reading upto at least 1 mhz, :-)

     
  • kent_twt4

    kent_twt4 - 2016-09-06

    Glad to see your meter is up and running :).

    Well, you do bring up one of more valuable traits of the comparator module, which is having a variable Vref to measure a range of analog inputs, outputing a square wave at Vdd, and saving external parts in the process.

     
  • William Roth

    William Roth - 2016-09-26

    Good to see y'all figured it out.

    For future reference, Microchip offers much more capable chips than 12F683 for signal measurement duties. These chips have 2 dedicated 24-bit Signal Measurement Timers that can work in various modes, one mode being a period timer. Using the SMT will improve pertormance, accuracy and resolution while reducing the code to just a few lines once the registers are configured.

    These chips include: 12F1612, 16F1613/14/15/18/19 as well as the 18F188xx chips.

    These chips are supprorted by GCB but need to use a Pickit3 with MPLAB IPE for full programming functionality.

    There is some support for the older Pickit2/Pickit3 GUI and command line programming applications but this is limited by the inability to setup more than 2 config words with these older depricated programming applications.

    Another option is to use the Curiousity Develoment Board for the 12F/16F series or the Xpress Board for the 18F188xx series.of chips.

     
  • kent_twt4

    kent_twt4 - 2016-09-26

    These chips have 2 dedicated 24-bit Signal Measurement Timers that can work in various modes, one mode being a period timer.

    These chips include: 12F1612, 16F1613/14/15/18/19 as well as the 18F188xx chips

    Did not know this, hard to keep up, much better range and resolution.

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.