Frequency Counter with decimal
DigitalBob
Posts: 1,513
Greetings All
Does anyone have a spin solution for a frequency counter that will read in decimal. Example 200.3 hertz or 1200.7 hertz, nothing high frequency maybe 10-20 KHz tops.
Thanks in advance
Bob
Does anyone have a spin solution for a frequency counter that will read in decimal. Example 200.3 hertz or 1200.7 hertz, nothing high frequency maybe 10-20 KHz tops.
Thanks in advance
Bob
Comments
http://obex.parallax.com/object/118
http://obex.parallax.com/object/241
http://obex.parallax.com/object/478
http://forums.parallax.com/showthread.php/123170
Bean
I recently had a similar problem. I knew the wavelength in clock ticks but needed an accurate frequency to three decimal places for display purposes. Note the use of the modulas operator ( // ) in line 3.
clkfreq: 80_000_000 ticks
wavelength : 1_340_005 ticks
clkfreq / wavelength = 59.701
I then displayed the two variables ( WholeFreq and FractionalFreq ) seperated by a decimal point.
Sandy
I received some good tips but no cigar. I saw this post written by someone and tweeked it to give the desired output. It works good for my needs I'm only interested in the low end 400 hz , 1800 hz. etc.. I gets it a little sloppy above 2000 hz. You can tweek the math and waitcnt to give the desired output.
{ Frequency Counter
}
CON
_xinfreq = 5_000_000
_clkmode = xtal1 + pll16x
LCD_Pin = 1 'The LCD is connected to pin A0.
LCD_Baud = 19_200 'Baud
LCD_Lines = 2 'The number of lines on this LCD
In = %0
On = 1
Off = 0
G=0.1
CountPin = 5 'Input Pin for counter
Obj
LCD : "debug_lcd" 'Creates the object LCD from "debug_lcd"
F : "FloatMath"
FS : "FloatString"
Var
long Cog
long PNCount[2] '0 is posicount 1 is neg count
Long Frequency
long X1
long X2
Pub Main | TotCnt , freq
Cog := cognew(@entry, @PNCount[0] ) + 1
If LCD.init(LCD_Pin, LCD_Baud, LCD_Lines) 'Initialize the LCD object LCD.Cursor(Off) 'Set cursor off
LCD.Backlight(True) 'Set backlight on
LCD.Cls
Repeat
LCD.Gotoxy(0,0)
LCD.str(string("pos")) 'Positive Count
LCD.dec( PNCount[0] )
' LCD.out($0D)
LCD.Gotoxy(8,0)
LCD.str(string("neg="))
Lcd.dec( PNCount[1] )
TotCnt := (PnCount[0] *100) / (PnCount[0] + PnCount[1])
LCD.Gotoxy(8,1)
Lcd.str(string("Dec")) '% Positive
Lcd.str( x2 ) 'Displays float string
Freq := (12000 * 5556 ) / ( (PnCount[0] + PnCount[1]) ) 'Tweek the math for desire reading
X1:= F.FFloat(freq) ' Converts Freq to a float
X2:=(FS.FloatToString(F.FMul(x1,g))) 'Converts float to string
LCD.Gotoxy(0,1)
Lcd.str(string("frq="))
Lcd.dec( Freq )
waitcnt(clkfreq * 1 + cnt )
lcd.cls
LCD.Backlight(True) 'Set backlight on
PUB stop
if Cog
cogstop(Cog~ - 1)
DAT
org 0
entry
{
'
Debugger Kernel add this at Entry (Addr 0)
long $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8BC0E0A
long $EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF8
'
}
'
muxz dira , PinMask ' Configure Pin as inputs (0) as Z is zero
mov addr , par 'par has address of first variable to write back which is PosCnt
add addr, #$4 'This is address of second variable to write back NegCnt
:MainLoop mov PosCnt ,#0 'set counters to zero
mov NegCnt ,#0 wc 'set counters to zero c set to zero
waitpne PinMask , PinMask 'waits for negative on input ina
waitpeq PinMask , PinMask 'waits for positive on input
:PosLoop Add PosCnt , #1 'adds 1 to positive count
Test PinMask , ina wz 'tests and sets z= 0 if both = 1
'if both are = 1 then result is 1 and z = 0
if_NZ jmp #:Posloop 'stays in loop as long as input is high z=0
:NegLoop Add NegCnt , #1 'adds 1 to positive count
Test PinMask , ina wz 'tests and sets z= 0 if both = 1
'if both are = 1 then result is 1 and z = 0
if_Z jmp #:Negloop 'stays in loop as long as input is low z=1
Wrlong PosCnt , par
Wrlong NegCnt , addr
jmp :MainLoop
' VARIABLES
PosCnt Long 0
NegCnt Long 0
PinMask long |< CountPin 'This creates a pin mask with a 1 and CountPin zeros to the right
PinState res 1
addr res 1 'register for sending data to main program
Please see my note in your other post about how to post code in the forum.
Thanks,
-Phil