Reading Encoder strip values in P2
I am creating sample code in c++ to read encoder strip values.
This is used for calculate motor steps for DC motor.
previously i was using QEI library for Nucleo 144(https://os.mbed.com/teams/IoTKitV3/code/QEI/docs/tip/QEI_8cpp_source.html).
And using QEI lib with X2_ENCODING macro i am getting proper values in Nucleo144 board.
So i am creating similar support for P2. In QEI lib there is ISR which is continuously checking pulses for Forward and reverse directions.
So for P2 i have created this function to run on another cog to monitor pins.
But i am not getting proper values in P2. for forward direction its taking both forward and reverse pulses and same for backward direction also.
And i am sure that its not about calculation(ISR in QEI lib code) because same calculation works in Nucleo 144 board. So not sure whats wrong here. attaching my sample code for P2.
Not needed...all P2 pins are capable of QEI with zero processor overhead. Search the forum for quadrature encoder.
As others have indicated, you can use P2 smart pins to handle encoder input without using a spare cog. Note, though, that you cannot preset the S/P encoder value to anything but zero, and there are no built-in end limits. In my Spin object I have user variables for a preset value (which becomes an offset from the physical encoder read) and low and high limit values.
Ideas (translated from my Spin code):
One of my clients makes camera control platforms so we get a lot of use out of encoders.
Sample Quadrature code using smart pin to count the pulses:
The code requires that you use two pins next to each other and greater. In this case pin 21 and plus 1 is 22.
The commented code is what the "_pinstart" does for you.
Hello @JonnyMac what is encLo and encHi variables? and what will be their default values?
i am taking encA as pin 25. and have created volatile int encOffset = 0,
also can i take preset variable as volatile int?
Right now i have created this variables
volatile int encOffset = 0;
int encLo = 0;
int encHi = 1500;
int preset = 0;
encHi as maximum 1500 encoder steps.
Is this correct as per your description?
Thank you very much @evanh , this is really great.
But where can i find smart pin configuration details? any link or manual?
@iseries , really appreciate your help. I have used your code on pin 25 26 and its counting pulses. but when i read pulses from QEI lib in Nucleo 144 i was getting around 1500 count, and with this smart pin code i am getting 930 steps. So is there possibility we can increase count resolution? seems like pulses are missing?
Also where you have find smart pin configuration details for P2 in c++? any link or manual available for it?
It simply decodes the quadrature. How are you physically generating the pulses....rotary/linear encoder? Presumably a 5v device. How are you interfacing to the P2?.
I am using linear optical encoder which used by printers.
this is standard circuit which nedds to be placed in between encoder pins and controller pins.
Mike's code does a divide by 4 (right-shift 2). You're one did a divide by 2. And mine didn't do any dividing.
Hardware details are all in the Silicon Document - https://www.parallax.com/propeller-2/documentation/
It's a very terse document but the details are all there.
Oh yes, understood. to make it divide by two i have to make >>1.
Now getting double pulses around 1800.
Yes after looking smart pin sample code for Quadrature read, i think its worth to explore other capability of P2 smart pins.
You'll like them.
On that note, the low level pin drive config is capable of performing pull-up function for inputs where you've got PNP or NPN (like above) sensors.
The 100 kR resistors I wouldn't bother with. The 3k3 pull-ups can be replaced by driving output high with, say, 1.0 mA setting.
PS: I guess the 100 kR resistors were there to prevent saturation spikes from bouncing off the input protection diodes. I don't know for sure but I'd guess the 1 mA drive circuit will peter out a little below VIO supply volts and thereby perform the same job of preventing saturation spikes also.
PPS: On the other hand, the capacitors should prevent any bouncing in the first place. The 100 kR resistors just seem overkill.
In my Spin code, the values of encLo and encHi are passed via the start method (along with the encoder a and b pins and other configuration values). The variables encLo, encHi, and encOffset are global to the module; preset is a local parameter and does not have to be declared in the variable space.
In other threads you seemed disinterested in looking as Spin, but I'm attaching my encoder object for your reference -- it will help you make sense of the scope of variables.
I didn't want to muddy the water and so waited for you to reply but I interpret encLo/encHi to be "soft limit switches" (I do similar)
So, IOW, we have the equivalent of X1, X2, X4 line-count multiply, like a dedicated quad-counter device?.....
Yes, sort of. Think of the volume control on your car radio. You can spin the knob clockwise forever, but the max volume is 100; anti-clockwise will stop changing at 0. This is how those low and high limit values work with the encoder object. In an application that requires actual limits, those should be handled by the application (I did this with a moving target on a rope project for JonyJib).
Thank you for spin2 file.