Simple encoder pulse count
joethumphrey
Posts: 25
Hello all,
I'm a complete newb on this but I have been assigned a project that I'm desperately trying to get started on.
After looking it seems the propeller will do what I need. I'm need to so some inline ISO spec verification on a conveyor.
I cant seem to get the simplest part going though. Which is to read an encoder to derive belt speed.
I have a 5000 pulse encoder that with be running a 1/2" wheel for 10000 pulses an inch @ 56 " per sec. Or 560,000 pulses a sec.
How would I point the pins used to the counter on a cog?
I can see the return from the encoder with the microphone to vga by swapping in the pins connected vs the microphones. I'm using the demo board btw.
If could get that part squared away I think it's just as simple to capture the cnt at those edge points aswell and I can figure out belt speed via the differential .
Kind of a hodge podge trying to get a constant return from the counter.
But all it displays is the pin number on screen.
I'm a complete newb on this but I have been assigned a project that I'm desperately trying to get started on.
After looking it seems the propeller will do what I need. I'm need to so some inline ISO spec verification on a conveyor.
I cant seem to get the simplest part going though. Which is to read an encoder to derive belt speed.
I have a 5000 pulse encoder that with be running a 1/2" wheel for 10000 pulses an inch @ 56 " per sec. Or 560,000 pulses a sec.
How would I point the pins used to the counter on a cog?
I can see the return from the encoder with the microphone to vga by swapping in the pins connected vs the microphones. I'm using the demo board btw.
If could get that part squared away I think it's just as simple to capture the cnt at those edge points aswell and I can figure out belt speed via the differential .
Kind of a hodge podge trying to get a constant return from the counter.
But all it displays is the pin number on screen.
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OBJ
text : "vga_text"
PUB start | i,a
ctrb := %01010
ctrb := 4
frqb := 1
'start term
text.start(16)
repeat 14
'repeat i from $A1 to $a2
'text.out(i)
text.str(string($A,12,$B,12,$C,2,"cnt"))
text.dec(cnt)
text.str(string($A,14,$B,1,$C,6,"test",$C,2))
text.dec(ctrb)
repeat
text.str(string($A,12,$B,6))
text.hex(i++, 8)
Comments
Is there a way to have a look at Your encoder setup? I am having trouble visualizing how it reads belt speed.
I will assume that Your code formatting was thrashed by the forums, and that everything is indented as it should be??
From what I could see, You get stuck in this repeat loop... It's the last three lines You have written, Your code will never leave this section after it enters..
and as fast as the Prop is, You might only see one number on screen, maybe try some waitcnt's...
Also check the sub forum, robotics, and search around for encoder's,
One of The resident encoder expert's likes to lurk in that forum.
Just mention dynamic braking, and He will be along shortly...
Here's the idea. You would need to call this with cognew passing the input pin (assumes high-going) and the address of your speed variable. This will run in the background and 10x per second update the belt speed which is express in units of 0.1"/second
One is for the Parallax wheel encoder the coding just uses ina and logic
the other is for a different encoder and uses the propeller counters
feel free to adopt them to your needs
This does what I wanted but I cant seem to keep it from rebooting every time the counter gets to roughly 235 pulses.
The "if wait..." seems to have brought on the rebooting but why?
UPDATE: Seems fixed now after removing the "if"'s . Still accumulates the pulse count without them.
Strange how it crashes the system though.
I have set the accumulator for the read to both positive and negative add. So a pulse in either direction gives an add to the total.
Which of course isn't right. On my 5000 pulse encoder I get 10000 per rev now.
So after commenting out the "waitpne" and its adder I'm getting run away numbers. They are alot higher than they should be.
Adding the check for waitpne and all is back to just double.
I am missing something simple here but what?
Gives double, counting both trailing and rising edges, but how does that work with the pin being set to only rising?
Gives, very high, run away numbers.
with the code shown you can play with the variable count and the waitxxx till the cows come home
It just aint doing what you think
frqa := 1 <---- is the amount to accumulate in phsa for each event set by ctra
phsa := 0 <---- clears the counter
ctra := %01000<<26 + 4 <---- sets the mode and pin # - counting begins now
waitcnt(x+cnt) <---- accumulation time -- counter is now busy counting inphsa
counter := phsa <---- FETCH THE COUNT (accumulation continues in phsa)
Post edit ( because a lot of newbees see this stuff )
Using the waitxxx, count++ you are doing the accumulation by reading the pins directly so when you remove the waitpne the cog waits for pin high and bumps the count then repeats but the prop is so fast that the pin is still high so it bumps again and again and again till it finally goes low and the cycle repeats after the next high and you end up with a meaningless high count, In the case of the two active waitxxx's you get a bump on the positive edge and again on the negative edge, to count pulse by pulse remove one count++ but you still need to have both waitxxx to see the high and then the low so the cog can recognize the pulse. just reverse the order of the waitxxx to see positive pulses or negative pulses.
using ctra,freq,phsa the cog is doing it for you. You select the type of event and tell it what pin and off it goes. They are different ways of doing the same thing but this method is faster.
you should check out the counters tutorials.
Note that the discrepancy between the menu setting (in Hz) and the captured pulses has to do minor math errors in the synth object.
I just updated my earlier post you might want to re read it
Hope I helped too-
Of course, I see it now. I had the right approach to counting but mistakingly added twice. It was so simple. Wait for both pos and neg edges like I have, just don't add for each.
Could someone show me where I'm using the spin stuff? I thought the code there was assembly? I can see I've got a ways to go.
It may be better to give a better picture of what I need to do here.
I'm looking at different methods of collecting data for ISO specing inline for production.
I make gift cards.
Bit amplitude, distance , and time are the points I need to collect.
First thing I need, the pulse accumulator. I know with a 1/2 wheel on a 5k pulse per rev encoder I'll get 10k per inch or 1/10000th " resolution.
So , with using card detect from a pickup, I'll trigger the read and at each peak of card bits I'll gather the encoder , clock, and amplitude from the peak. With those pieces I can derive and information I need.
IE.. card speed to run against a voltage gain algorithm for comparison against spec cards. Encoder record separation for bit interval distance.
I'll have to work into it a bit decoder to verify sentinel locations but after that I think the standard f2f chips will do the full decoding off the same read for actual data returns to correlate data to specimen .
Thank you everyone, I've got at least a start here on what I need, a few more hundred hours of reading everything and I should be getting data.
Also for someone else needing something like this or for ridicule.
data displayed on vga:
This is Spin code:
This is that code translated to Assembly (by me, the Propeller Tool doesn't compile Spin to native PASM):
Again... the Spin code is not fast enough for your 560kHz pulse rate. What you can do, however, is put a counter in edge mode like I demoed above and let the counter do all the hard work. That IS possible in Spin because you're using a counter to count, and it does that while other code is running.
I'm looking at the code you posted most recently and I think you are missing what is being said, if I'm wrong I apologize.
The point is that there are two independent ways of counting transitions or pulses on i/o pins
The first is the repeat, waitxxx, count++ and I'm sure you understand that code now.
This method in spin is the slowest and doing the same thing in assembly is a bit faster,
either way you do not need to setup anything in the counters for this method to work.
The second method is to use one of the two independant HARDWARE counters available in each cog
You activate them by setting values into the ctra,frqa,phsa registers (or b for the second counter) and then
read the phsa (or b) register whenever you need the count.
This is the fastest method available on the propeller.
Got one more issue.
I can not get the proper response from setting one pin low using the samples you provided.
That should set the pin to check for low, right?
Using a LV-21a laser pickup, the out goes low on detect. If I set it to high it works in reverse. I get counting until I trigger the detect as the pin was set to for high. But on low setting I get nothing.
I've tried swapping the equal/not equals. Removing each as well with no luck.
Is there something else to detecting low on a pin that I'm missing? From the examples I can find they look similar.
Is there some out put that has to be switched on to make the pin high to wait for low or do I need to supply a check voltage on outside?
Thanks again, Joe.
Zero shifted right by any value is still zero. If you want to use P4 then it should be 1 << 4
And... waitpne is used to wait for a pin to go low. If your encoder is using an active-low pulse then this is what you want: look for low, look for high (end of pulse), update count.
Reset mask to 1 and installed pullup , all is well.
Thank you again.
I can't seem to make this work. All I'm looking to do is use that as a global boolean flag , either low, card in and 1 or high = no card and 0.
What am I missing this time?
Got It
Corrected:
I've chopped up the ADC demo script to experiment with amplitude recording but I cant seem to get it to work at the same time as another function.
They are running on separate cogs with separate variables yet if both are loaded neither work. But they work if one or the other is commented out, noted below in bold.
I've moved the pins around to get some physical separation but nothing different.
Anyone see what's causing this?