Third Encoder Channel

Yo. I’m new to encoders. From what I can understand, the default code at Kevin Watson’s website only allows for two channels: the first channel uses analog inputs 1 & 6, and the second uses analog inputs 2 & 8. Does anyone know how to create a third encoder channel? Any help will be highly appreciated. Thank you.

First of all, they are digital I/O channels, not analog. You can use DIO3-6 for the next interrupt input (phase A) and almost any unused digital channel for phase B.

It’s not hard, but you do have to know what you’re doing to get it right.

We’re using three encoders. Two of them are on pins 1&7 and 2&8, using essentially Kevin’s code. The third is on pins 3&9, with a few lines of interrupt initialization and service routine copied from Kevin’s interrupts.c to dispatch the third encoder’s handler when INT4 occurs. There is also an extra check to call the handler only when INT4 was triggered by a falling edge of the signal on pin 3. (That part of the code seems a little inconsistent, as if the input pin were going low and then high again before we had a chance to look at it. I’m considering wiring in a hardware pulse-stretch circuit to deal with it.)

To avoid extra interrupts that we would just have to ignore, we have nothing connected to pins 4-6.


The simplest way to do this is with a D-type flip-flop (e.g., 74ACT74, 74HCT74, 74LS74, etc.). The encoder’s phase-A signal goes to the the clock input and the RC interrupt input. The phase-B signal goes to the flip-flop’s D input and the Q output goes to the RC digital input formally used by the phase-B signal. I prototyped this circuit and saw a pretty dramatic increase in the maximum count rate that the RC could handle.


Three quick questions:

  1. Must interrupts 3-6 be enabled/disabled as a package? i.e. you cannot ONLY enable 3, but not 4-6? I am using two encoders and the Hall Effect sensor, and need only 3 interrupts, and would rather not have to enable 6 of them.

  2. If Q1 is true, and we enable 3-6, should we move the phase-B signal on I/O 6 to 7 in order to avoid unnecessary interrupts?

  3. Does phase stretching circuit described in the threads above allow a faster count rate because it prevents the phase-B state from changing (to the wrong state) before the interrupt is serviced?

I know some of these should be pretty obvious, but Team 188 is running the Grayhill 63R256 encoders, and our count rates are pretty high. I’m hoping to stave off any interrupt issues that might arise =).


Yes, but it’s not a big deal. If you’re not using the other three interrupts, just treat the interrupt the same way you would the first two. The only added step is to determine which edge caused the interrupt to fire off.

Yes, definitly. Just edit encoder.h to specify which digital input you’ve moved it to.

Yes, and it works really well.

The above circuit will increase your maximum count rate by a factor of four.


Here’s a schematic of the circuit described above.


hi, I tried doing the same thing, but I ran into problems because interrupts 3-6 are “ganged together”. how do I reference one at a time? I couldn’t figure out how to clear the interrupt flag either. basically, are there any magic lines of code to access one instead of all 4. we’re going to need a third interrupt also (the arm), and since our team is pushing the building to the last minute, I can’t afford have code messing up too much. thanks.

The magic lines of code are what I cribbed from Kevin’s interrupts.c example.

Initialization is easy (easier than the other two interrupts, because there’s no rising/falling edge selection). Testing to see which pin caused the interrupt involves remembering the state of PortB between interrupts and comparing the current state to see where they differ. My software also specifically checks to make sure the pin is in the proper state, so that I’m only calling the service routine on the desired edge of the signal.

Built it =)

It runs great!!! Thanks!


Hmmmm…is it possible to have a fourth encoder channel. How do I check for which Interrupt’s (3-6) logic state has changed if I used a fourth encoder? Thanks.

Here are our encoder files which will help you.

Team236 (7.6 KB) (7.6 KB)

Thank you very much. I will test it tonight…


Thanks for the help. I see you have a robot.h included in your user_routines_fast.c. Is there something in it that we would need to get it all to work?

Team 1008

We were unable to get the scripts to work as advertised. What finally worked was changing the list of commands into a switch…case series of statements that stepped through the commands in much the same way as the code in robot.c does. We used variables for the parameters which are then used by the called function. We did use the functions in robot.c and wrote additional ones for our arm.

“It’s in the blood!”

I’m not concerned about a third encoder, but that is not to say I don’t need help.
Encoders were the last thing on our minds putting the robot together.
Now the team would like to use them to get accurate distance measures.
The problem I am thinking exists is with Kevins code, Digital’s 1,2,6&8 are used for the encoders, and I assume the interrupt routines.
We are using those digitals already on the robot. (1-11 and 17,18 are all used)

Where specifically do I need to change the interrupt code to have the interrupts function for say… digitals 12,13,14,15.
I understand needing to change the user_routines.c file for INPUT/OUPUT but interrupts confuse me. :confused:
Also, I see in encoder.h that Kevin is #define ing the XXX_Encoder_Phase_B_Pin’s but not the Phase_A_Pins? Am I missing something? :confused:

Thanks in advance for your assistance.


Digital inputs 1 and 2 are permanently connected inside the robot controller’s CPU to the interrupts used by the encoder code. You can’t do anything about that. There is a third external interrupt which is triggered on any change of digital inputs 3 through 6, but using it is a bit more complicated than the first two. So far as I know, none of the other digital inputs can cause interrupts.

  1. Can I change at least digital 6&8 to something else.
    We have a wiring harness that is pulled into dig 1-11. This can be moved up to 3-13, but has to stay together…

  2. Do I need to change anything in the Interrupt routines if the answer to #1 is yes?



Yes, you can move the encoder Quad B connections on digital inputs 6 & 8 to any other digital input pins.

You’ll need to change the following two lines found in encoder.h to reflect the new digital inputs.

#define LEFT_ENCODER_PHASE_B_PIN rc_dig_in06
#define RIGHT_ENCODER_PHASE_B_PIN rc_dig_in08

I will mod the code tonight (This work thing keeps getting in the way of robotics).

Thanks for the quick responses.