Shop OBEX P1 Docs P2 Docs Learn Events
Code help for frequency counter — Parallax Forums

Code help for frequency counter

AJMAJM Posts: 171
edited 2009-07-10 00:55 in Propeller 1
I am working on my first project and the first goal I have is to be able to accurately measure a sensors frequency. Before I hook my prop to any sensor, I want to make sure the code actually works correctly.

In the attached code I am using a counter to act as the sensor, outputting a frequency on pin 14. The signal then goes through a buffer circuit. Counter B is set up as a negative edge detector on the output of the buffer and inputs to pin 10. The program then displays the frequency on the serial terminal.

I do not have a scope but my multimeter does have a frequency setting. When connected to the output of the buffer (in this case) it reads 99.98 Hz. However, the output on the serial terminal can read anywhere from 100 to 104 Hz.

Because the output frequency is high (over 100 Hz), I think the extra cycles are being counted while the spin commands are being ran. Is this correct or am I way off in the programming/technique I am using here?

Any advise from the people here is always appreciated.

CON

  _clkmode = xtal1 + pll16x            ' Set up clkfreq = 80 MHz.
  _xinfreq = 5_000_000

  HOME = 1, CR = 13, CLS = 16, CRSRX = 14, CLREOL = 11

OBJ

  Debug         : "FullDuplexSerialPlus"

PUB Init

  ctra[noparse][[/noparse]30..26] := %00100        ''
  ctra[noparse][[/noparse]5..0] := 14
  frqa := 5_369                 '' 100 Hz ( frqa = freq*2^32 / clkfreq )
  dira[noparse][[/noparse]14] := 0                 '' Pin = Input

  ctrb[noparse][[/noparse]30..26] := %01110        '' Negative Edge Detector
  ctrb[noparse][[/noparse]8..0] := 10
  frqb~
  phsb~

  Debug.start(31, 30, 0, 57600)
  waitcnt(clkfreq*5 +cnt)
  Debug.tx(CLS)

  frqb := 1

  Main

PUB Main | frequency

  repeat
    dira[noparse][[/noparse]14] := 1               '' Pin = Output
    phsb~
    waitcnt(clkfreq + cnt)
    !dira[noparse][[/noparse]14]
    frequency := phsb
    Debug.str(String(HOME, "Frequency = "))
    Debug.Dec(frequency)
    Debug.tx(CR)

Comments

  • matbmatb Posts: 39
    edited 2009-07-09 10:28
    Maybe its the serial buffering in Debug? The time difference is a bunch more than hub access variations!

    To eliminate uncertainty (and have simpler code), use a counter to drive the pin directly. The education kit documents have examples.

    Also you should clear phsb asap. Doing it after all the serial stuff at the moment will add some error, which is probably what you are seeing.

    To algorithm more accurate, do not clear phsb, keep track of its last value and subtract.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2009-07-09 12:57
    Propeller AN01 [noparse][[/noparse]Application note #1] may be highly informative as the hardware is a bit unusual.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ain't gadetry a wonderful thing?

    aka G. Herzog [noparse][[/noparse] 黃鶴 ] in Taiwan
  • JonnyMacJonnyMac Posts: 9,197
    edited 2009-07-10 00:55
    I needed a break from work-work so I wrote the attached as an exercise. I use a second cog to count the clock ticks in a full cycle; ctra is used to count the high-phase counts and ctrb is used to count the low-phase counts; by doing this your input waveform can be asymmetric. The counts are written to the hub every other cycle (of your input waveform) and the .freq() method converts the counts to frequency.

    Probably not ideal, but does seem to work well and that the counter is running its own cog means your display update isn't waiting on the input waveform.

    [noparse][[/noparse]Edit] Made some minor code improvements and increased the resolution to 0.1Hz.

    Post Edited (JonnyMac) : 7/10/2009 4:04:41 PM GMT
Sign In or Register to comment.