Photoelectric Rotary Encoder (H38S100B) | LabJack
« Close

Datasheets and User Guides

App Notes

Software & Driver


Photoelectric Rotary Encoder (H38S100B)



Rotary Encoders

Rotary encoders are devices that allow the conversion of a motor's angular position into a digital or analog output. For the majority of motor control applications, this feedback is necessary in order to tell how far the motor has traveled at a given instant. With this information the application can dynamically change the speed or duration of the motor's spin to ensure it reaches its desired position at the desired time.  There are two general classifications of encoders, absolute and incremental encoders.  Absolute encoders allow position to be recalled after a power-cycle event while incremental encoders keep track of relative location (from a set-point).  Rotary encoders generally output a square wave with each pulse representing a set amount that the motor has moved. An application can then count these pulses and using the known number of encoder pulses in one revolution, extrapolate how far the motor has moved.

Incremental Encoders

Incremental encoders typically output data in the form of two digital signals to indicate both position and direction of rotation, this digital waveform looks like two square waves that are 90 degrees out of phase as can be seen in the figures below.  Incremental encoders that output these signals are sometimes referred to as quadrature encoders.  In the case of an optical encoder, this is achieved through the use of an LED, a patterned disk, and a high speed  photo-sensor. As the encoder turns, the patterned disk either allows the light from the LED to pass through to the photo-sensor or it gets blocked.  This produces the desired square wave behavior. The disks have two patterns that are ninety degrees out of phase, which produces the two out of phase square waves. By identifying which of the square waves is leading the other, the direction of the motor's motion can then be identified. 


Wiring an Encoder with a T-Series LabJack

Both the T4 and T7 have support for interpreting quadrature input. Most encoders, including the H38S100B have four connections, phase A, phase B, VCC and GND. The two phases must be plugged into two quadrature enabled I/O lines that are a member of one of the following pairs: 


T4 Capable DIO: DIO4+DIO5, DIO6+DIO7, DIO8+DIO9 (aka FIO4+FIO5, FIO6+FIO7, EIO0+ EIO1)


T7 Capable DIO: DIO0+DIO1, DIO2+DIO3, DIO6+DIO7 (aka FIO0+FIO1, FIO2+FIO3, FIO6+ FIO7)

The even I/O line should be connected to phase A and the odd I/O line should be connected to phase B. On a T7 an example of a proper connection is phase A connected to FIO0 and phase B connected to FIO1. On a T4, an example of a proper connection is phase A connected to FIO4 and phase B connected to FIO5 as in the figure below. Any VCC and ground on the T-Series device will be sufficient for the other signals. 

Sometimes, a quadrature encoder will also have an optional Z phase which sends a pulse after each full rotation. T-Series devices are capable of enabling an I/O line to receive this Z phase as a reset so the encoder only keeps track of the position relative to a single rotation. For more information on the quadrature in functionality of the T-Series see Quadrature In [T-Series Datasheet].  

To test the functionality of a quadrature encoder after wiring, the VCC and GND signals can be connected on a T-Series device and the two phases can be monitored on different channels of a scope. When the encoder is moved, the two expected out of phase waves should be visible on the scope as seen below. 

Clockwise Scope Shot
Counter-Clockwise Scope Shot

LJM Library Psuedocode

Data from Quadrature Encoders can be read from T-Series devices on multiple platform types (Windows, Mac, Linux, and single board computers) by using the LJM library and starting with our published example code. If the device's Ethernet or WiFi connection types are used, larger SCADA systems or Modbus Client Applications that implement the Modbus TCP protocol can also be used.  There are also a few 3rd party applications capable of communicating with LabJacks.

Connecting to a LabJack

The first step in the majority of LabJack applications is to open a connection to a device utilizing the LJM library. This is done utilizing the LJM_Open function which can be passed the device type, an identifier representing the serial number or IP address of the device, and the connection type to open a specific device. The open function can also be called with LJM_Open(LJM_dtANY, LJM_ctANY, LJM_idANY,...) and it will open any connected device. After opening the connection to the device, the open function will return a handle that can then be used to read from or write to the LabJack device for the body of the application. After the application body is finished, it is best practice to close the connection to the device using the LJM_Close function. For more on connecting to a LabJack device see LJM - Opening and Closing.

Configuring a LabJack

The Quadrature Input section of the T-Series datasheet shows an example of configuring a device's DIO6 and DIO7 I/O lines in the example section.  Below are the registers that need to be written to configure the device to use DIO0/DIO1 (aka FIO0/FIO1):

LJM_eWriteName(handle, "DIO0_EF_ENABLE", 0);    //Make sure DIO-EF is disabled on DIO0
LJM_eWriteName(handle, "DIO1_EF_ENABLE", 0);    //Make sure DIO-EF is disabled on DIO1

LJM_eWriteName(handle, "DIO0_EF_INDEX", 10);    //Set feature index for DIO0 to quadrature.
LJM_eWriteName(handle, "DIO1_EF_INDEX", 10);    //Set feature index for DIO1 to quadrature.

LJM_eWriteName(handle, "DIO0_EF_ENABLE", 1);    //Enable quadrature DIO-EF on DIO0, for A phase.
LJM_eWriteName(handle, "DIO1_EF_ENABLE", 1);    //Enable quadrature DIO-EF on DIO1, for B phase.

Configuration Registers
Name Start Address Type Access

DIO#(0:22)_EF_ENABLE             1 = enabled. 0 = disabled. Must be disabled during configuration. Note that DIO-EF reads work when disabled and do not return an error.

44000 UINT32 R/W

DIO#(0:22)_EF_INDEX             An index to specify the feature you want.

44100 UINT32 R/W

Reading Data

Once configured, if an application is keeping track of the encoder's state the data can be obtained by reading the correct DIO#_EF_READ_A register. If the application needs the LabJack to keep track of the encoder's relative position and re-set the encoder count back to zero, the DIO#_EF_READ_A_AND_RESET register can be read. Detailed information about the registers that can be read is found in the datasheet.

// Read the quadrature input's current count and don't reset the count back to zero
LJM_eReadName(handle, "DIO0_EF_READ_A");

// Read the quadrature input's current count and re-set the count back to zero
LJM_eReadName(handle, "DIO0_EF_READ_A_AND_RESET");

Read Registers
Name Start Address Type Access

DIO#(0:22)_EF_READ_A             Reads an unsigned integer value. The meaning of the integer is dependent on selected feature index.

3000 UINT32 R

DIO#(0:22)_EF_READ_A_AND_RESET             Reads the same value as DIO#(0:22)_EF_READ_A and forces a reset.

3100 UINT32 R

Stream Mode

If quadrature input results are required at faster rates than are capable through the use of command response commands, data can also be read by streaming. After configuring the DIO_EF feature, and adding both the DIO0_EF_READ_A and STREAM_DATA_CAPTURE_16 registers. See the Reading with LJStreamM section below for more details.

Stream Registers
Name Start Address Type Access

STREAM_DATA_CAPTURE_16             If a channel produces 32-bits of data the upper 16 will be saved here.

4899 UINT16 R

Reading with Kipling and LJLogM

The fastest and easiest way to load and test code is by using Lua Script and loading it to the T7 device using LabJack's Kipling application, which will automatically handle connections to the device. Lua Script can also be loaded to a LabJack device manually using the method described here.  Note, neither Kipling or LJLogM calculate the 2's compliment of the _READ_A register so the _READ_A_F register is required.  When the value becomes higher or lower than ~2^23-1, integer level precision will be lost.  This is true for our example .lua script as well.

LabJack Kipling using T4 or T7 to read incremental rotary encoder

Reading with LJStreamM

A T-Series device can be configured so that quadrature input or rotary location data is read at rates faster than 100Hz and buffered by the device to get hardware-timed position data. This is demonstrated by using LJStreamM as follows:

LabJack Kipling using T4 or T7 to read incremental rotary encoder

Calculating Location

In order to fully utilize a T-Series device's quadrature input mode with a 32-bit value that automatically rolls over the DIOx_EF_READ_A register's result needs to be turned into a signed integer by performing a 2's compliment calculation. Calculating the position in degrees from zero for the H38S100B is done by following the following the below steps:

encoderCountsPerRevolution = 400

// Read the quadrature input's current count and don't reset the count back to zero
rawValInCounts = LJM_eReadName(handle, "DIO0_EF_READ_A");
relativeLocationInCounts = twosCompliment(rawValInCounts) // Typically looks like (-1 * (~rawValInCounts + 1)), "~" is the bitwise not operator.

// Calculate Number of Revolutions
numRevolutions = relativeLocationInCounts / encoderCountsPerRevolution

// Convert counts to degrees
degreesFromZero = relativeLocationInCounts % encoderCountsPerRevolution * 360 / encoderCountsPerRevolution

Example Application (Windows Only)


Connect to and Configure a device:

LabJack example incremental rotary encoder application - device parameters 1. Configure Device Parameters (DT, CT, ID): Configure Device Connection Parameters to determine what device gets opened.
LabJack example incremental rotary encoder application - phase pairs and counts per revolution 2. Phase Pairs and Counts per Revolution: Configure which I/O lines the rotary encoder is connected to using the phase pairs option. Also define the number of encoder counts per revolution in order to properly calculate the encoder's rotational position.
LabJack example incremental rotary encoder application - configure/start 3. Configure/Start: Connect to a device & configure it's quadrature input capabilities. Pressing this button will force the program to try connecting to a device by the defined connection parameters and then configure the device to use the defined phase pairs or I/O lines.
LabJack example incremental rotary encoder application - device status Device Status: Verify that the device has been opened. If the device status field illuminates green and says "OPEN" rotary position data will be read from the device and calculated.
LabJack example incremental rotary encoder application - re-zero control Zero/Reset: Re-define the zero location of the stepper motor.

LabVIEW Examples Notice:

This example is the .exe of our "Quadrature_Input_Example_Application" available to be downloaded on our LabVIEW for LJM webpage and utilizes the producer-consumer design pattern.  A simpler example "" is located in the folder:


The majority of a T-Series' device features can be used using the "Write Read Loop with" located:


Referenceable: Quadrature Input FAQ & Troubleshooting

FAQ & Troubleshooting Tips

Q: I'm not getting any counts. A:
-- Clamp a jumper wire in GND and tap the other end randomly to the inside back of both quadrature inputs. It is hard to get a predictable number of pulses to be registered, however it is possible to get some seemingly random + and - counts to be triggered.  This variance has to do with debouncing I/O lines.
-- Try following Kipling's "Configuring & Reading a Counter" tutorial. This is a good getting started tutorial to follow before using any DIO_EF feature implemented by T-Series devices. Using the counter feature is the easiest way to see if any signal is coming out of a rotary encoder. For instance, in applications where only speed is required, the quadrature input mode is not required. Speed can be calculated by keeping track of how many counts are incremented over a given period of time.

Further Research

More information about the difference between absolute and incremental encoders in video form as well as some potential applications in two videos by RealParse, "What is Encoder?" and  "What is the Difference between Absolute and Incremental Encoders?".