PDA

View Full Version : Code help for frequency counter



AJM
07-08-2009, 09:50 PM
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[30..26] := %00100 ''
ctra[5..0] := 14
frqa := 5_369 '' 100 Hz ( frqa = freq*2^32 / clkfreq )
dira[14] := 0 '' Pin = Input

ctrb[30..26] := %01110 '' Negative Edge Detector
ctrb[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[14] := 1 '' Pin = Output
phsb~
waitcnt(clkfreq + cnt)
!dira[14]
frequency := phsb
Debug.str(String(HOME, "Frequency = "))
Debug.Dec(frequency)
Debug.tx(CR)

matb
07-09-2009, 06:28 PM
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.

Loopy Byteloose
07-09-2009, 08:57 PM
Propeller AN01 [Application note #1] may be highly informative as the hardware is a bit unusual.

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

aka G. Herzog [ 黃鶴 ] in Taiwan

JonnyMac
07-10-2009, 08:55 AM
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.

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

Post Edited (JonnyMac) : 7/10/2009 4:04:41 PM GMT