Arduino boards, quadrature encoders and interrupts

Hello all,

I'm not sure if I'm in the right part of the forum for this, but it seemed the closest …

I've built a robot, a common design of two wheels and a caster, and I've reached the stage of construction where I want to get the steering and general motor control sorted out. The two motors have quadrature encoders on them ( I think they're magnetic … is that possible? They certainly have rotating magnets in them and they're not mechanical or optical ) . The robot is based on an Arduino Uno clone.

Anyhoo, my question is, if I have two signals each from two quadrature encoders, that makes four digital inputs needed. I've read on this site that the Uno only has two interrupt pins, pin 2 and pin 3. Does this mean I've got to get a Leonardo or Mega 2560 or one of the other boards which has at least 4 interrupt pins to replace the Uno in the robot?

But I've also read that there are all sorts of different kinds of interrupts and interrupt pins, and I don't know which, if any, I need to use for the sort of interrupt needed for polling quadrature encoders.

I've never used interrupts before, and I spent hours last night reading and watching tutorials without being able to find a clear answer; they all seemed to either pass over this point or assume I already knew it.

Your options are

  1. Get a new board that has enough external interrupts (Since you probably do need 2 per to fully utilize the encoder, and yes they can be magnetic).
  2. Mux the two, which means you use a Multiplexing (Mux) circuit to look at one, then the other, back and forth. This means you won't be able to know the exact speed of both at all times, but figure out if that is a problem.
  3. Ignore half of the Encoder, and just use it to get RPM from the motors, and assume the robot knows what direction the wheels are spinning. This means you only need 1 interrupt per motor, rather than 2. It will be less fine detail, but do you really need it?

Anyhoo, my question is, if I have two signals each from two quadrature encoders, that makes four digital inputs needed. I've read on this site that the Uno only has two interrupt pins, pin 2 and pin 3. Does this mean I've got to get a Leonardo or Mega 2560 or one of the other boards which has at least 4 interrupt pins to replace the Uno in the robot?

No you can still utilize/decode two encoders using only the two user interrupt pins. So each encoder has one channel wired to a user interrupt pin and the other channel wired to any digital input pin. What you lose is possible resolution which very well may not be an issue in your application. An encoder has a step rating specification, often called steps per revolution. If an encoder is rated as say 128 steps/rev then using the proper coding in the ISR code you can utilize the encoder as having 128, 256, or 512 steps. Only that last case of 512 requires that both encoder channels need to be able to trigger a user interrupt.

Another possibility is to look into pin-change interrupts (there are library code available) where you can any digital pin be able to generate an interrupt. But I would only use that method if you need the maximum 4 X step rating.

mirith, retrolefty,

Thanks for replying. You've given me something to chew on.

I don't need high accuracy. The robot is just for fun, to chuff around the house tormenting the dogs and the husband, but I would like to be able to read the direction it's going from the encoders.

I understand about the multiplexing, though I'm not sure I'd know how to go about it, but I don't quite follow this bit …

If an encoder is rated as say 128 steps/rev then using the proper coding in the ISR code you can utilise the encoder as having 128, 256, or 512 steps. Only that last case of 512 requires that both encoder channels need to be able to trigger a user interrupt.

How can you extract a higher resolution from a device than it's actually putting out? And why don't you need a user interrupt except in the last case?

How can you extract a higher resolution from a device than it's actually putting out? And why don't you need a user interrupt except in the last case?

It's a product of how the encoder manufactures rate their encoders (what they mean by the word 'step') and the nature of a 2 channel digital quadrature encoder. A 'step' for an encoder is represented as four possible state changes in the two bit value. The coding can utilize all 4 or 2 or just one of these state changes per step to define the increments one can have per revolution.

Using interrupts in not a factor one way or another, in that you can fully decode a quadrature two channel encoder just using digitalReads. Interrupts just makes the process faster and non-blocking, which may or may not to a factor depending on the application and the bit rate of the encoder signals at the maximum speed you need to process.

Thanks retrolefty,

That makes sense. I shall go away and think deeply about it :-).

Why do you think you need to use interrupts?

How fast do you anticipate the pulses to be?

by defination, a quadrature encoder has to have two channels.
many devices use one magnet on the spinning bits and only output frequency that can be calculated to RPM.
a quadrature encoder has to have two channels. then, has multiple pulses per rotation.

if the magnets rotate, then there would need to be multiple sensors. if your devise has a quadrature encoder, it may not be involved with the rotating magnet ? there could be an additional sensor.

My motors are 133 rpm, and each has a quadrature encoder attached. I’ve run them and looked at the output on my CRO; two nice clean square waves running 90 deg out of phase.

I’m sure the magnets are part of the encoder, as I paid extra for motors with encoders and I had to put them together from a small kit, which included installing magnetic, rubber-backed discs on each motor shaft over the sensors. Does that make sense?

I’ve read that you need interrupts to read encoders with any degree of accuracy, because otherwise the timing of the reads depends on the timing of your basic Arduino loop, and pulses may be missed. I think it’s about time I tackled them anyway, as I do want to learn about them and stop being intimidated by such scary-looking code.

As for what I need the encoders for, I want to be able to tell direction of travel and distance, and maybe speed also, if it’s not too difficult, as the motors don’t run at exactly the same speed and the bot drifts to the right atm.

There’s time for me to investigate the whole subject though, as the Uno which was my robot’s brain has died, and I’m not sure which board to get as a replacement.