Faster encoder quad decode?
Mickster
Posts: 2,693
in Propeller 1
The drag, is having to write the encoder count to the hub.
Is it feasible to simply toggle the decoded up/down count outputs that are hard-wired to the CTRA and CTRB of another cog and subtract B from A, or is there an alternative to this?
Is it feasible to simply toggle the decoded up/down count outputs that are hard-wired to the CTRA and CTRB of another cog and subtract B from A, or is there an alternative to this?
Comments
My current motion controller, the Galil 4183, is rated at 15M quad counts/sec.
Even MC's QEI is rated at 2.5M quad counts/sec.
The alternatives could be to
a) Lower the bandwidth needed, eg by having the COG do a highspeed compare and then send a difference, so the HUB link does not have to follow the highest count rates.
In most quad apps, when you hit highest MHz, you are nowhere near a control point, just in transit to the next 'way point'.
or
b) Use a SPLD/CPLD/Small FPGA to do the Quad - that could be Qa.Qb -> CeUP and CeDN, for your 2 Ctr value diff idea.
In that case, you would clock out at 40 or 20MHz to clock the PLD state engine.
I think that means CeXX are 2 SysCLK wide so counters INC by 2, tho maybe those CeXX can be CLK gated.
I've not seen Tsu, Th numbers for Prop counters for CLK out to Ctr in ?
Some of those delays could be significant.
How many channels do you need ?
c) Choose the smallest FPGA that can take one P1V COG and integrate as many Quad Counters as you need.
This moves to multiple Vcc supplies, and smaller packages.
d) Find a small MCU with a high speed Quad Ctr.
but with two cogs I think its possible to do better with each catching transitions on one pin.
Each cog writes its own count and you would sample them both and sum them to get the complete count.
I tried to extend that to handle beyond the invalid state into overlapping of normal valid states but it would blow up way too easy.
Yes, I have many options for performing the actual decode in external hardware but I want to see what I can achieve with minimal external circuitry. The six encoder line-driver outputs (CHA, -CHA, CHB, -CHB, CHI, -CHI) will interface directly to the Prop via a 422 line receiver as CHA, CHB, CHI.
On reviewing my OP, I realize that its's not absolutely clear that my question was regarding the feasibility of using one cog for performing the quad decode and another cog for writing the count to the hub. This being achieved via cog-to-cog hard wiring.
I am dedicating one cog per encoder for a total of two encoders, one for motor feedback and one for load feedback.
In theory, I can already achieve 2M quad counts/sec @80MHz. I am actually very happy with this so the OP question is more of a curiosity than a requirement.
Cheers!
Each cog sees both pins, but only waitpeq's on one of them. After a change it reads the other pin
to C and does a SUMC or SUMNC to update its counter and writes it.
Sure, you could use a COG to duplicate what a CPLD would be doing, and use 2 pins as the 'cog-cog' connection. (CEu/CEd)
I'm not sure you buy much peak speed, (2 MHz is only 10 cycles) but you do bypass the HUB.
Since this COG is doing only PLD work. maybe you can fit two Quad to CEu/CEd engines with modest speed impact ?
Did you look at unrolling the loop and using velocity to change how often you update the HUB ?
ie low speed rates update HUB every edge, but above some speed (> 100kHz) you switch to (eg) 4 or 8 edge
HUB updates.
My old code was in Basic but was just a simple state machine so will be easy enough to convert to Pasm. It might be just what you are after as it did nothing else other than present the count as an 8-bit binary output on some pins. I'll see if I can dig it up ... ha! now I remember my code wasn't a state machine, that was Hippy's. I then added what I had been up to to Hippy's original.
I've included Hippy's original plus a couple of my variants ...
It's a table based approach to reading an encoder. The sample code runs at about 1.6Msps and is hub aligned. You could cheat and remove the hub write to get it to 2Msps.
Forgive me if I misunderstand but regardless of how
frequently I access the hub, I cannot accept losing even a
single count during the worst case of a 22 clock-cycle hub-
write as this is a position control system. Velocity control
would be a different matter.
Aha! I had a similar idea. Although I need to keep track of
absolute position at high velocity/resolution, the hub updates
don't need to happen for every change of encoder state
because my PID sample time is only approximately 2KHz. So
a means of accumulating counts for a different cog to take its
own sweet time updating the hub is what I am shooting for.
Every quad-decode routine that I have seen for the Prop,
updates the hub for every change of state.
I have opted not to take the table based approach but,
instead, simply "Jmp" to separate procedures based on the
current state of the assigned (not limited to contiguous)
inputs.
For a rough timing test, I modified the code for a worst case
scenario of having to always test both inputs and write to the
hub for every iteration. The result was approximately 2.5M
iterations/sec but this is obviously an average of 7 to 22
clock-cycle hub writes so I cannot expect to reliably capture
2.5M quad counts/sec.
The following PropBasic source is self-explanatory.
The down side is at very low speeds, you may want more often updates, and how to choose that 'gear change' ?
Another pin ? HUB read adds another delay, but maybe in an unrolled loop that can be done ?
ie Does the gear-change cost as much as you gain ?
There is a common enough trick of counting instructions between hub accesses to keep in sync with the hub rotation. With this you get the fastest reads and writes possible. A mere three instructions of filler for tightest timing, seven fillers for next best window, then eleven, and so on.
The trick is not to go one too many. One too few instructions is not so bad.
As far as interface devices go, THIS caught my eye recently.