Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I have 6 high resoloution encoders (10k lines) that I want to interface with a micro controller. I have written code to do the quadrature decoding for all the encoders but there is just no way that a poor Arduino can handle that that many encoders at any reasonable speed, let alone do anything else while keeping track of the encoders.

What should I do in such a situation?

Unfortunately I don't have much of a background in electronics, just in programming (just a little bit).

share|improve this question
2  
How fast is it, i.e. how many counts per second do you get? –  starblue Apr 11 '11 at 5:29
add comment

3 Answers

up vote 13 down vote accepted

My pet peeve is when quadrature decoding is done in software. When done in software, the decoder frequently can't keep up, especially when the pulse rate is fast or the MCU is doing a lot of other things. I have seen many devices that use quadrature encoders on a data-entry knob, and it works fine most of the time. But the decoder would skip pulses whenever the MCU had to do something, like refresh the screen or talk over RS-232.

I do quadrature decoding in an FPGA. A 50K Gate Xilinx Spartan-3A costs less than $10 and can decode more channels than it has pins. And it'll do it with a quadrature pulse rate over 1 MHz. There are no MCUs for similar or cheaper cost that can do that.

Edit: What follows below is a summary of lots of comments, and some further elaboration on my part. Enjoy!

It's true that you can do a software approach if the pulse rate is slow enough. But when this is done, you have to make sure that the "corner cases" are covered. Things like interrupts for other peripherals (like UARTs, ADCs, etc.) can effect how often you sample the quadrature data causing the quadrature decoding process to occasionally miss pulses. These missed pulses are "ok" for some applications, like a data-entry knob, but are still annoying to me.

@Leon Heller really likes the XMOS processors for something like that. For those who don't know, the XMOS stuff is basically a simple but super fast MCU. Where most MCU's run in the <25 MIPS range, the XMOS stuff is pushing 500 MIPS. XMOS doesn't do a lot of hardware based peripherals, like UARTs. Instead they "bit-bang" it and do the UART in software. They also bit-bang things like USB and 10mbps Ethernet. Ok, I'm super-over-simplifying this, but you get the point. Here's my opinion: there are FPGA guys and there are CPU guys. If you're a CPU type of guy and don't like FPGAs then the XMOS processor might be right for you.

The topic of Gray-codes in an FPGA implementation was brought up, and implementing the up/down position counters in gray code. There are typically two reasons to use Gray-codes: if you have some asynchronous logic going on (2 or more clocks), or if you want the counters to take up less logic. Normally you wouldn't have async logic in the FPGA (other than sampling the quadrature data at the input pins), and the FPGA already has super-fast carry chains (a.k.a. binary adders). So really, under normal circumstances there isn't any need for gray-code counters for this.

You could use a CPLD for this, instead of an FPGA. This would work for 1 or 2 quadrature decoders, but as you add more decoders the interfacing to a MCU gets more complex. FPGAs are nice for this because the MCU interface could be SPI or other simple thing that doesn't take up dozens of pins on the MCU.

The "correct" way to do this in an FPGA is where the FPGA has a simple 8-16 bit counter that tracks the position. This counter is never reset after initialization, and sometimes not even then. Software (SW) would poll this position every so often, and would keep a record of the "previous position". Taking the current position and subtracting the previous position would tell the software how far the position changed.

The reason the position counter is never reset is because we're trying to avoid a "destructive read". That's when the CPU reads a register which causes something irreversible to happen-- like clearing a position counter. Sometimes destructive reads are unavoidable, like when reading a FIFO, but generally you want to avoid them. The thinking behind this is beyond this post. I tried to find a good web page that discusses them, but I failed. Sorry.

When talking about the count-rate, below, I mean how fast the position counter can go up or down. Because of the quadrature nature of the thing, the "pulse rate" is one quarter of the count rate. I'm assuming that for every full pulse we can count up/down 4 times. I know there are other ways to count (one count per full pulse), but I'm ignoring it out of principal.

Ignoring the XMOS processor (which is more like an FPGA, in the context of the next few paragraphs), MCU's are going to be limited to a max count rate of less than 500 Hz and in many cases less than 100 Hz max. Of course there might be some outliers that get higher than 1 KHz, but for most people that's hard to do. For your typical MCU you're doing good to get above 100 Hz, assuming that the MCU is not dedicated to quadrature decoding.

A typical data-entry knob has 12 to 20 pulses per revolution, or 48 to 80 counts per revolution. Assuming the knob is 1 inch in diameter, a typical but over-zealous person could get about 4 turns per second when trying to scroll through lots of data. That works out to a count rate of 192 to 320 Hz. Still within the capability of an MCU, but just barely and only with careful programming.

An FPGA, depending on exactly how the logic is written, could handle a count rates of more than 100 MHz. I've written my logic to handle count rates of up to about 50 KHz, but it can do many quadrature decoders in a very small amount of logic. In a Xilinx Spartan-3 FPGA it takes about 50 slices and 1 Block-RAM to do 32 to 512 decoders (you'll run out of pins before you run out of logic).

So, which is better, FPGA, MCU, or XMOS? As usual, it depends. It depends not only on the usual things like count rate and number of decoders, but also on what the designer is comfortable using and what else is in the system. My preference is FPGA, but that's just the kind of guy I am! :)

share|improve this answer
    
I would suggest some headings and formatting changes to make this answer perfect. –  Kortuk Apr 12 '11 at 21:51
    
I like your comment about destructive reads, but would add to it: if the processor cannot perform an atomic read of the full-width counter value, it is IMHO safer to have "piecewise" reads fetch live data than have a read of one portion latch the others. If the reads fetch live data, then the processor can read low-byte/high-byte/low-byte and figure that if the two low-byte values match, the data is good (if they don't match, try the sequence again). This approach will work even if while the main-line performs such a sequence an interrupt occurs and its handler also performs the sequence. –  supercat Jun 10 '13 at 15:51
    
By contrast, having the hardware latch the whole counter and then allow the latched value to be read out in pieces allows the code to be simplified if it can guarantee it won't be interrupted by code which also needs to read the counter, but if the simpler code is interrupted by code which reads the timer it may fail. For example, main-line code latches timer value of 0x03FF and reads half of it. Then an interrupt latches 0x0400, reads the counter, and returns. Finally, the main-line reads the other half of the counter, yielding 0x0300 or 0x04FF, depending upon which half was read first. –  supercat Jun 10 '13 at 15:56
    
BTW, I wonder if any microcontroller-readable counters implement "byte-level" graycode by e.g. having each byte (or readable unit) reported in ones-complement form if the lowest bit of the next higher byte is set? Such a design would ensure that reading all the bytes of the timer and performing the necessary xor operations would yield a legitimate reading unless multiple counts occurred between reading the LSB and the next byte, even in the scenario where a counter goes back and forth between e.g. values 0x02FF and 0x300 [which would be reported as 0x02FF and 0x03FF]. –  supercat Jun 10 '13 at 16:00
add comment

My suggestion would be to have the Arduino execute user application code, and simply talk to 3 or 6 other very low cost microcontrollers that do the quadrature decoding. The number of external micros depends on how capable they are of decoding such a high-resolution encoder at a given speed. The external micros would behave like those in mice -- they keep track of the encoder count delta since the last position query. Assuming that you're not trying to do realtime position feedback for closed loop motor control, and just want to know where each motor is at an arbitrary point in time, this could work out for you. Use SPI or I2C to talk to all of the external micros, and of course you'll need to deal with counter rollover in the event that the main controller (Arduino) doesn't request a position update at regular, guaranteed intervals.

share|improve this answer
    
Hmm, separate cheaper micros would defiantly work (and is something I might be able to pull off). Speaking of separate chips, any idea if they make dedicated quadrature decoding ICs? I guess for my application I only need snapshots of encoder positions as opposed to real time tracking. It is only important that all encoders positions are caught at the exact same time. –  Faken Apr 10 '11 at 22:19
2  
they absolutely do make quadrature decoders. I haven't used a discrete IC for this in a while, but I think it was the HCTL-2000. Make sure you pay close attention to the bandwidth of the IC, or the micro that you might use for decoding. 10k lines / rotation is extremely high resolution, so spinning the shaft too quickly could very well result in lost counts. If you don't mind my asking, what encoder are you using? –  Dave Apr 11 '11 at 0:41
1  
Ohh hey look! They make 32-bit counter/decoders. That's perfect! Though, I may still need to go through a parallel to serial IC first (outputs in 4 8-bit transfers, not enough pins on micro for 6 of them). 33 Mhz operation is way more than I need. I'm using TRD-S2500-BD encoders. –  Faken Apr 11 '11 at 1:14
    
Would it help at all to do the decoding with logic, and output "up" and "down" pulses to the Arduino? –  endolith Apr 11 '11 at 2:15
1  
@endolith but I wonder if that would still tax the arduino too much. You'd then need to make sure the Arduino can capture these rapid up/down pulses from 6 high res encoders while it's dealing with the user app. –  Dave Apr 11 '11 at 3:12
add comment

Use a $7.50 XMOS XS1-L1 chip, with six threads doing the decoding - one thread for each encoder:

http://www.xmos.com/

That leaves two threads for doing other stuff.

The XK-1A board available from Digi-Key only costs 99, and comes with the XTAG-2 debugger. It's got everything you need on it Development software is free, and I think I've seen encoder software on the users forum. The 1600 MIPS XC-1A board is another option, and also costs 99.

This is probably the easiest and cheapest way to do it.

share|improve this answer
2  
Uhh, for some reason I don't think this counts as a beginner hobbyist level anymore. –  Faken Apr 10 '11 at 21:52
1  
@Faken a 10k line encoder isn't exactly hobbyist level to begin with! Having 6 of those on one micro and expecting the micro to read them when spun at any reasonable angular velocity is asking a lot, I think. Are you direct-driving your load and require really high resolution? –  Dave Apr 10 '11 at 22:02
1  
Yea, I understand that 10k encoders are not hobbyist level stuff but to be completely honest, the only difference between a 10k encoder and a 200 line encoder is just that one is more expensive, other than that, they work pretty much the same. The difference between a 16 mhz Arduino and a 500 Mhz XMOS is not quite so simple. –  Faken Apr 10 '11 at 22:10
    
I need to direct drive because of backlash issues of gearing. I'm designing a 6 DOF linkage based coordinate measuring machine, everything is done except the electronics which I'm struggling with. –  Faken Apr 11 '11 at 0:12
1  
I think the downvote is because you suggested a quadrature decoder chip which is much more powerful, complicated, and expensive, then the chip that is running the rest of his device. –  davr Apr 11 '11 at 16:12
show 9 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.