How to hook up 8 wire differential wiring quadrature encoder

How to hook up 8 wire differential wiring quadrature encoder

Understanding Incremental Encoder Signals, differential wiring

The encoder I have is a 2000 ppr quadrature encoder with 8 wires.
6mm shaft, 38 mm body dia, 2000 ppr optical rotary encoder, 5v line driver

I'm trying to figure out how to connect the A-, B-, Z- wires.
If I understood the concept correctly, A+, B+, Z+ connect to interrupt pins on an Arduino or Teensy.
What do I connect the A-,B-, Z- wires to for differential wiring setup based on the article mentioned above? Do I connect them to ground?

I'm thinking of using the Teensy encoder library to try the encoder out.
encoder library pjrc forum

Also as a side question, does MCU speed make a difference in terms of the maximum frequency we can analyze from the encoder?

Please post a link to the manufacturer's data sheet for the exact encoder you have. It will have the required information.

Hi, @knightridar
You have GHS3806G2000BML5 ?

Product description

Size:2000PPR | Color:Line driver with 5V

The Incremental Rotary Encoder is designed to provide pulse feedback when the shaft is rotated. It is low cost yet compact, high quality and an incremental rotary encoder.
Widely used in Steel Industry, Textile Machinery, Port Machinery, Plastic Machinery, Lifting Machinery, Pressure Machinery, Glass Machinery, Printing Machinery, Wood Machinery, Packaging Machinery, Machine Tool, ogistics Machinery, Tire Machinery, Electronics and Solar, Elevator.

Color: Like the picture show
**power supply:**DC5-26V wide voltage or DC5V
Speed: more than 6000 r / min
Size: Shaft: 6mm Dia, Shell Size: 38mm Dia,
Output: Line Driver output with ABC A-B-C- signals ;Voltage out put ;Push-pull with ABZ 3 signals;NPN
When 3 channels: Red=VCC, Black = 0V, Green = A, White = B, Yellow = Z
When 6 channels: Red = VCC, Black = 0V, Green = A, White = B, Yellow = Z, Brown=A-, Grey=B-, Orange= Z
Note: If the encoder is not connected to the device can not be directly oscilloscope oscilloscope (open collector output without pull-up resistor when there is no voltage output) If you want the oscilloscope in AB two-phase output with two pull-up resistors. **Cable:**1meter cable side

What you have is
Red Vcc = positve supply
Black 0V = supply gnd
Green = A Signal A one of the quadrature channels.
White = B Signal B one of the quadrature channels.
Yellow = Z Sync signal, one pulse per revolution.
Brown = -A Inverted A signal.
Grey = -B inverted B signal.
Orange = -Z inverted Z signal.

Your encoder has line driver output, so you will not need pull-up resistors.

I not knowing what your project is, I can only guess you need;
Vcc, Gnd, A and B signals.
-A, -B, -Z and Z you can leave open circuit.

Can you please tell us your electronics, programming, arduino, hardware experience?

Can you please tell us your application, project?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

@TomGeorge the model number is correct. Thanks.

I not knowing what your project is, I can only guess you need;
Vcc, Gnd, A and B signals.
-A, -B, -Z and Z you can leave open circuit.

If I wanted to improve the noise issue based on the article mentioned above do I hook up the remaining 3 lines to ground? The cable I have is 1 meter long, but what if I ran a longer cable.

Differential wiring uses two wires per channel that are referenced to each other. The signals on these wires are always 180 electrical degrees out of phase, or exact opposites. This wiring is useful for higher noise immunity, at the cost of having more electrical connections. Differential wiring is often employed in longer wire runs as any noise picked up on the wiring is common mode rejected.

I've worked with open loop stepper motors sending pulses and signals and to have them rotate in specific 90,180,360 increments. Other experiences are just basic gps modules, and humidity/temperature modules and using them via already available libraries.

Some of the goals I want to try to accomplish with the encoder is to hook it up a dual shaft stepper motor via a motor coupling for closed loop feedback driven stepper motors for a gimbal or 3d printer.
This is the current board I'm looking into, their stepper drivers are pretty popular in the 3d printing hobby level world. Although this breakout board only takes in 3 wires for the encoder, I'm still wondering if it's possible to hook up the other 3 wires to avoid any potential noise issues.
trinamic 5160 bob


No you don't they are valid outputs in their own right, shorting those will damage the encoder, just leave them open circuit.
All the signals are positive with respect to ground.

A 1m cable should not have any noise pickup if you route it properly and if needed use shielded cable.
Does your encoder come with a suitably shielded and length cable.

What is the environment that your project will be in?

It sounds like you are planning, you may need to do some experimenting with hardware.

Tom... :smiley: :+1: :coffee: :australia:

From the looks of it it does look shielded, I hooked up the 8 cables to terminal blocks and will hook up wires on the other side of the terminal block to the motor controller and/or Arduino or Teensy 4.1.
The silver shielding is slightly sticking out of the black insulated wire.


Good, is very rare that the cable isn't shielded.
You can cut back some of the insulation and connect the shield to gnd.

The Teensy should be better than say a UNO, much higher speed so it will work better at high encoder pulse frequency.

Tom... :smiley: :+1: :coffee: :australia:

Thanks, I'll do that. Based on the research I've been doing I think it says to connect ground points to one common point and not daisy chain them because it can create different voltage potentials.
Encoder best wiring practices

Just curious, for the Teensy 4.1 it says:

Teensy 4.1

Special Timers
These extra timers allow delays, analog sample rate timing, carrier modulation, and other special timing tasks to be performed, without consuming any of the normal PWM-oriented timers.

    GPT1 - Generic 32 bit timer
    GPT2 - Generic Generic 32 bit Timer
    Quadrature Encoders - 4 special timers are meant for decoding quadrature signals. 

I'm assuming these are the quadrature encoder pins based on the PJRC site:

  • QuadTimer1 Module0 - Controls PWM pin 10.
  • QuadTimer1 Module1 - Controls PWM pin 12.
  • QuadTimer1 Module2 - Controls PWM pin 11.
  • QuadTimer1 Module3 - No pins accessible.
  • QuadTimer2 Module0 - Controls PWM pin 13.
  • QuadTimer2 Module1 - No pins accessible.
  • QuadTimer2 Module2 - No pins accessible.
  • QuadTimer2 Module3 - No pins accessible.
  • QuadTimer3 Module0 - Controls PWM pin 19.
  • QuadTimer3 Module1 - Controls PWM pin 18.
  • QuadTimer3 Module2 - Controls PWM pin 14.
  • QuadTimer3 Module3 - Controls PWM pin 15.
  • QuadTimer4 Module0 - No pins accessible. Used by OctoWS2811 library, ADC Library
  • QuadTimer4 Module1 - No pins accessible. Used by OctoWS2811 library
  • QuadTimer4 Module2 - No pins accessible. Used by OctoWS2811 library
  • QuadTimer4 Module3 - No pins accessible. Used by Audio for ADC timing, and ADC Library

Will hooking up to these specific pins as interrupt pins allow for faster signals / frequencies?
I don't know what are thes advantages of having these timers and seeing if anyone here does know what is so great about using them?


Yes, star rather than daisy.
I'm not familiar with Teensy I'm afraid, some other member will be more informative than I.

Tom... :smiley: :+1: :coffee: :australia:

1 Like

The standard circuit is to route the signals to a quad differential line receiver chip, being expressly designed for differential signals.

Failing that just ignore the -ve signals - the noise immunity is compromised of course, but it should work with short cables.

If you connect any of the signals to ground you'll risk damaging the driver.

1 Like

I'm working with a similar encoder (8-wire, 5v powered encoder used to track rotations/displacement for a tensile tester) and am having similar issues. I assume the "skipping" of signals received by the arduino when I use just the A+ and B+ lines is due to missing the inverse signal, but it might also be due to inadequate processing speed.

What kind of differential line receiver should I use if I want to ensure accuracy? Is that even likely to be the problem or is there another way to solve it?

If you think I should post this in a new thread I will. Still kinda new to programming; thank you!

Your code and wiring diagram?

Try one of the electronics suppliers and search for "quad differential line receiver", and make sure to pick out a digital one (not analog), and not LVDS either, you want a 5V part. Differential line drivers typically do not go to full swing as they assume a 100 ohm differential load at the other end and a receiver. Sometimes you can get away with just one of the outputs and treat it as a CMOS signal, but clearly this isn't working reliably here. You might have different grounding for one thing, a true differential line receiver will tolerate a few volts of ground offset.

BTW do you have a termination on the differential signals?

Thank you very much for that explanation, it's starting to make sense now. It would make sense that the lines are not reaching full swing. I just ordered a differential encoder to remedy this issue.

By termination do you mean placing diodes to prevent flyback/reflection of the signals? I have not done that; should I? And if so, would I want to place them on the output signals of the driver, or the output signals of the receiver?

Btw the encoder I'm using is a Chinese knockoff of an Omron E6B2-CWZ1X

Thanks again

Hi, @Eatonasher
That encoder has line driver output so no pullup required.

Its only 1000pps, can you please post your code?
What speed are you aiming to rotate the encoder at?

How are you powering your project, the encoder consumes 160mA of current.

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

No, just the standard 110 ohm (roughly) to match a twisted pair transmission line.

Hi @TomGeorge

I've been waiting to get an SN75ALS193 in the mail, but got tired (it's been months) so I picked an old AM26LS33 Differential Line Receiver.

The encoder model I got says 2000pulses/rev, and here is what I have connected right now. I haven't been able to make an encoder in Fritzing yet (can't figure out how to successfully make/modify new parts):

Right now I'm driving the encoder with the 5V pin from the arduino, but I plan on powering it separately in the enclosure via the same 5V power source I'm using to power the Raspberry Pi4 and Arduino, which is just a 5A 5V supply from Amazon.

As for the speed, I plan on running it at a maximum of ~120rpm, since my 1000rpm garage door opener motor is geared down to about 113rpm for torque reasons.

@MarkT where would I put those resistors in that fritzing diagram? I'm still confused as to the difference between adding those resistors versus pull-up/pull-down resistors.

As for the code, I'm using an example sketch I found online:

#define encoder0PinA  2
#define encoder0PinB  3

volatile unsigned int encoder0Pos = 0;

void setup() {
  pinMode(encoder0PinA, INPUT);
  pinMode(encoder0PinB, INPUT);

  // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);

  // encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);

  Serial.begin (9600);

void loop() {
  //Do stuff here

void doEncoderA() {
  // look for a low-to-high on channel A
  if (digitalRead(encoder0PinA) == HIGH) {

    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == LOW) {
      encoder0Pos = encoder0Pos + 1;         // CW
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW

  else   // must be a high-to-low edge on channel A
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == HIGH) {
      encoder0Pos = encoder0Pos + 1;          // CW
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
  Serial.println (encoder0Pos, DEC);
  // use for debugging - remember to comment out

void doEncoderB() {
  // look for a low-to-high on channel B
  if (digitalRead(encoder0PinB) == HIGH) {

    // check channel A to see which way encoder is turning
    if (digitalRead(encoder0PinA) == HIGH) {
      encoder0Pos = encoder0Pos + 1;         // CW
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW

  // Look for a high-to-low on channel B

  else {
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinA) == LOW) {
      encoder0Pos = encoder0Pos + 1;          // CW
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW

Right now, I get readings in the serial monitor, but they're not consistent/they have a tendency to increase rather than decrease. I only have it mocked up on a breadboard atm and I don't trust my jumpers to stay connected, so I'll solder up a pcb with terminals and test it that way to confirm the readings on the monitor continue to only increase.

Thank you both for your help with this, I truly appreciate it!

What is the cable length from Arduino to encoder?
What is the encoder's pulse per revolution?
What kind of resolution are you expecting (100 pulses per inch, 4 per mm of movement)?

Please post a circuit diagram, with pin labels and component names.
A hand drawn schematic would be fine.
That Fritzy does not tell me anything about the IC pins.

How long is the wire from Teensy to encoder?

Tom ... :grinning: :+1: :coffee: :australia:

1 Like

Apologies, here is the labelled circuit diagram!

I'm using an UNO just until I get it working; I'll upgrade to a teensy if the UNO doesn't have a high enough baud rate/

Encoder --> Receiver = 4ft
Receiver --> Arduino = 3in

The wire from the encoder to the Receiver is only about 4ft/1.25m long, but it has to pass directly underneath the motor, which pulls about 4 - 5A at full chooch. The wiring is shielded and I have it terminating in the monitor enclosure, where it sits right above the arduino, so I probably could have otten away with an encoder without the differential line encoder. This is the one I ordered so I would like to use it. Next time, I know I should consult the forums/experts before making decisions about what I do/don't need!

@JCA34F the wire lengths are above, and the encoder's pulse/rev is 2000. I'm using a 3/4"-16UNF lead screw to raise/lower the assembly, so that gives me 1.5875mm/rev. I would be happy with 0.001mm resolution, but I don't really want to go any higher than that. Given my current setup, I believe I should get ~0.0008mm/rev, which is under the 1 micron resolution I'm aiming for.