Counting Limitations?
bbaker
Posts: 16
I start a COG and use :
· Freq.Synth("A",1, 4_800)
In the top COG I want to monitor a pin for a trigger and then count form pin 1 ( which is at 4,800 hz). IF I trigger my "Monitoring Pin, I only get a count from pin 1 of up to abot 450.
Here is part of the code,
CON
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
PUB Compare | time, t, tt, deltat
· dira[noparse][[/noparse]23]~~
· dira[noparse][[/noparse]16]~~
· repeat
··· waitpeq (|< 4,|<4, 0)· 'monitor pin 4
··· waitpne(|<4, |<4, 0)
··· t:= SystemCounter
··· waitpeq (|< 4,|<4, 0)
··· waitpne (|< 4,|<4, 0)
··· tt:= SystemCounter
··· deltat := tt- t
··· TV.dec(deltat)
··· TV.out(13)
PUB SystemClk
· dira[noparse][[/noparse]1]~~·· 'Audio
· dira[noparse][[/noparse]0]~~
· Freq.Synth("A",1, 4_800)
· repeat
··· waitpeq (|< 1,|< 1, 0)
··· SystemCounter := SystemCounter +1
Any ideas?
·
· Freq.Synth("A",1, 4_800)
In the top COG I want to monitor a pin for a trigger and then count form pin 1 ( which is at 4,800 hz). IF I trigger my "Monitoring Pin, I only get a count from pin 1 of up to abot 450.
Here is part of the code,
CON
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
PUB Compare | time, t, tt, deltat
· dira[noparse][[/noparse]23]~~
· dira[noparse][[/noparse]16]~~
· repeat
··· waitpeq (|< 4,|<4, 0)· 'monitor pin 4
··· waitpne(|<4, |<4, 0)
··· t:= SystemCounter
··· waitpeq (|< 4,|<4, 0)
··· waitpne (|< 4,|<4, 0)
··· tt:= SystemCounter
··· deltat := tt- t
··· TV.dec(deltat)
··· TV.out(13)
PUB SystemClk
· dira[noparse][[/noparse]1]~~·· 'Audio
· dira[noparse][[/noparse]0]~~
· Freq.Synth("A",1, 4_800)
· repeat
··· waitpeq (|< 1,|< 1, 0)
··· SystemCounter := SystemCounter +1
Any ideas?
·
Comments
Sorry, not enough data...
As far as i can see you check pin 1 from time to time (around each 40 µs) for a HIGH state, this HIGH state should occur 100 µs each 200 µs, so your SystemCounter increases for one or two (or maybe even three) during a high state and not at all during the low state.
BTW: There is no need to start any COG for using the timers...
Then I need to know how much the System Counter increases for each cycle on Pin 4. So If pin 4 goes High, Low, High then Low, I want to know how many times the SystemCounter increased. So I set T:= SystemCounter when the first pulse hits, Then I wait until the second pulse hits tt:= Systemcounter. then I get the delta.
The problem, IF Pin 4 has a 1hz pulse the delta is only at 470.... I tried Pin 4 at .5hz, and I get an 800 number.
Does this help???
I explained that you do not do that.
No.
I have also seen that in your program
This is something you are hiding so far! How do you do that??
At least good to have some consistency.
No, please provide the missing part of the program... Or is pin4 triggered by some external hardware??
Am I not in a repeat, and I wait for the pin to go high, then I add 1 and then repeat and wiat for the pin to go hig again?
On Pin 4 I had a Hall Effect, counting the rotation of a shaft. Then when I got strange numbers I am now just using a switch. I push.
Your misunderstanding is that you expect the REPEAT loop is synchronized by some magic to the frequency.
EITHER the loop is faster than the sound you generate, then you meassure an unclean multiple of it.
OR the loop is too slow, then you get only a few samples at all.
And WAITPNE and WAITPEQ wait for the level, not for the edge!
It looks like you are trying to build a tachometer (or a basic frequency counter). I believe that there are object libraries that simulate the BASIC Stamp's FREQIN function (which measures a frequency)
Based on your original posting it looks like you are missing pulses in your loop. Basically it looks like you depend on this code in the repeat loop to be incrementing the SystemCounter variable and you're using pin 4 as a gate/index input. I guess I don't know if that loop would be fast enough but it should be given you've got 200uS to notice you're looping.
For what its worth most of the frequency input code uses the internal counters which are running at the clock rate (80Mhz in your case) and then just measure the time between zero crossings. That gives the time of a single cycle of the wave form and when inverted gives you the frequency.
Have you tried slower frequencies? If you're just missing pulses in the monitoring loop you should be able to adequately test that by starting at 100hz or so and moving up until the count differs from what you expect.
--Chuck
I get a reading here from 24,000 going up to 38,800 when I optimize the loop (++, constant)
This is as expected, in fact the loop is nearly twice as fast as I estimated.
I triggered Pin 4 by this:
So the problem is in parts of your program you are still hiding. Alas - this is a common practice nowadays..
How did you define SystemCounter BTW?
Post Edited (deSilva) : 2/24/2008 2:18:02 AM GMT
Poppycock! Those are always the same two or three instructions initializing a counter. Those routines have been written as an exercise, and - yes - they should be used for a clean programming style
Which means: You may be quite accurate pressing it for 1 sec, but releasing it can generate many glitches...
The physics behind bouncing at switch release is a little bit unclear... I lived under the misconception for many years that there is no bouncing at all in that situation (there are some electromagnetic effects when breaking a flow of current of course...), but in my recent class my students proved me that this is not so... They had to use the switches from the EDU-Kit
But you have an implicite debouncing by the TV-routines which take some time after it, and also should see any such effects by display of multiple values...
Please post your complete code.
Post Edited (deSilva) : 2/24/2008 11:19:19 AM GMT
From what·I can understand you are trying to measure the speed of rotation of a shaft (as Chuck said) but you are trying to do it by measuring the period of one revolution·(speed=1/period). I presume you are using this method as the speed is very low - you mention 1 Hz. There is a very easy way to do this without·generating a frequency on another pin:
··This is a bit 'dirty' as it uses the cnt register (you could set up a counter to count clock pulses and use the phsa register instead). You will notice I have removed one pair of waitpeq/waitpne from the repeat loop which means you will monitor every revolution(or pulse) rather than every other as in your code. There·are some·caveats: whatever code is in the repeat loop must complete before the next pulse arrives or you will effectively get a period of half that expected. Also very long periods greater than the max value of cnt will not work.
Your deltat will be·number of clock·cycles so you will need to know the clock frequency if you want the deltat in·real time units - at 80Mhz period_ms is in milliseconds.
There is a potential issue when the cnt register rolls over to zero·- I think this is OK but I'm not sure why (@deSilva I'm sure you have expalined this in another post I read but I can't for the life of me find it again!)
Hope this helps
Paul
Using CNT is not dirty.. It is AS EXACT as the counters themselves (12.5 ns), as the offset produced by SPIN is compensated for by the subtraction!!
Post Edited (deSilva) : 2/25/2008 4:37:05 PM GMT
I am now using CNTB, and I am then waiting for a cycle and then getting PHSB. Then I reset PHSA.
It works much better
THANKS
But it is not quite clear to my what you do now...