Decoding EAW0J Absolute Encoder with Siemens S7-1200 1214C

David Krause16 min read
S7-1200SiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Decoding an EAW0J-B24-AE0128L Absolute Encoder on a Siemens S7-1200 1214C

The EAW0J-B24-AE0128L is a mechanical, brush-style absolute contact encoder that produces 128 unique codes over a single rotation. It is wired as a rotary potentiometer replacement: a common terminal is fed from +24 V DC, and the seven wiper contacts close unique combinations of bits to ground (or to the supply, depending on polarity). The challenge on the Siemens SIMATIC S7-1200 1214C DC/DC/DC is that the encoder is purely mechanical, so the seven outputs are read as ordinary digital inputs, the seven-bit pattern is a non-sequential Gray code, and the firmware does not provide a built-in decoder block. The application must therefore convert the seven-bit Gray code to a seven-bit binary word, then translate that word to a linear position 0–127 using a 128-byte lookup table supplied in the encoder datasheet (the datasheet itself documents a 256-byte code conversion table in ROM for full direction-aware decoding).

This article walks through the full implementation: hardware wiring on the 1214C, building the Gray-to-binary conversion, populating the 128-element lookup table, scaling the result to engineering units, and verifying the decoded position with a watch table and a JGY-370 DC motor commissioning sequence.

1. Overview of the Hardware Stack

Item Model / Part Role
PLC Siemens SIMATIC S7-1200, CPU 1214C DC/DC/DC (6ES7214-1AG40-0XB0 or later FW) Controller, reads seven 24 V inputs and runs the decode FB
Absolute encoder EAW0J-B24-AE0128L, 128 states, 7-bit parallel output, B24 = 24 V supply Position feedback to a JGY-370 DC gear-motor
Industrial Ethernet switch SIMATIC NET CSM 1277 (6GK7277-1AA10-0AA0) Unmanaged switch for PG/HMI and PROFINET traffic
Motor JGY-370 DC gear-motor Driven load; encoder is mounted on the shaft for absolute position feedback

The 1214C DC/DC/DC provides 24 V sensor supply on the bottom of the module, integrated digital inputs rated 0–28.8 V with a 1.5 mA typical input current, and supports HSC (high-speed counter) inputs on I0.0–I0.5 / I0.6–I1.1 depending on firmware. The EAW0J is not an incremental encoder with A/B quadrature, so HSC is not required: the seven static contact closures are read at ordinary input update rate (typically 1–10 ms for the onboard DI).

Encoder type matters. The EAW0J is a contact-closure absolute encoder. There is no pulse train, no SSI, no PROFINET, no RS-485, and no analog output. Each of the seven output pins is either open or closed relative to the common terminal. This rules out HSC, "CTRL_HSC", SSI, and TM PosInput technology modules. Plan on seven digital inputs, not two or three.

2. Prerequisites

  • SIMATIC S7-1200 CPU 1214C DC/DC/DC with firmware 4.2 or later (TIA Portal V15.1+ is recommended for the latest HSP).
  • TIA Portal with the S7-1200 HSP for the 1214C.
  • EAW0J-B24-AE0128L datasheet (contains the 256-byte code conversion table referenced as "ACETAB: 256 byte code conversion table (ROM)").
  • 24 V DC power supply, fused, with sufficient headroom for seven encoder contact closures (~7 mA per input at 24 V).
  • SIMATIC NET CSM 1277 unmanaged switch for PG/PC and HMI connection.
  • Eight-conductor shielded cable (one for common, seven for bit lines) terminated to a 24 V compatible connector strip or encoder pigtail.

3. Wiring the EAW0J to the 1214C

The EAW0J is a single-pole multi-throw mechanical device. Treat each of the seven wipers as a passive contact to the common terminal. Wire the common to +24 V and the seven outputs to digital inputs I0.0 through I0.6 (or any other contiguous DI byte). The PLC will see a logical 1 on any input whose contact is closed.

Encoder terminal Function PLC terminal (example)
Common (COM) +24 V supply to encoder 24 V sensor out (terminal L+ on the 1214C)
Bit 0 (LSB) Position contact 0 I0.0
Bit 1 Position contact 1 I0.1
Bit 2 Position contact 2 I0.2
Bit 3 Position contact 3 I0.3
Bit 4 Position contact 4 I0.4
Bit 5 Position contact 5 I0.5
Bit 6 (MSB) Position contact 6 I0.6

Connect the encoder cable shield to the cabinet ground bar at one end only. Set the input filter for the seven used inputs to 6.4 ms (the default "Standard" filter) so contact bounce does not cause misreads. If the mechanical contact bounce is severe, push the filter to 12.8 ms.

Opto-isolated inputs are slow. The 1214C onboard DI update is governed by the input filter. The seven DI cannot track a shaft that is rotating faster than a few hundred RPM. For slow positioning of a JGY-370 gear-motor (typical output speed 30–200 RPM), the filter is acceptable. For high-speed applications, external latching or a different encoder family is required.

4. Understanding the Code Pattern

The encoder datasheet documents that position 0 produces a seven-bit pattern of 1111111 (decimal 127), position 1 produces 0111111 (decimal 63), and position 9 produces a code equivalent to decimal 72. The bit pattern is not a simple binary up-counter. The relationship between shaft angle and pattern is published in the datasheet's 256-byte code conversion table, which contains one entry per code (0–255) and the corresponding position. Because the encoder only ever presents 128 unique 7-bit codes, the upper 128 entries in the ROM table are duplicates or directional information.

The seven-bit sequence used is a form of Gray code. In a Gray code, only one bit changes between consecutive codes, which is exactly what a mechanical contact encoder can produce without transient false codes. The order of the 128 codes in the datasheet is the order the encoder presents them as the shaft rotates in one direction. To get a "linear" position (0, 1, 2, ..., 127), the application must convert each seven-bit Gray code to a seven-bit binary index and then use that index to look up the position in the datasheet's conversion table.

Shaft position Gray code (g6..g0) Gray value (decimal) Binary (b6..b0) Binary value (decimal)
0 1 1 1 1 1 1 1 127 1 0 0 0 0 0 0 64
1 0 1 1 1 1 1 1 63 0 1 1 1 1 1 1 63
2 0 0 1 1 1 1 1 31 0 1 0 0 0 0 0 32
... ... ... ... ...
9 0 0 0 0 0 0 1 (illustrative) 1 0 0 0 0 1 0 0 4

The first column above (shaft position) is what the application ultimately needs. The second column is what the seven input pins present. The fourth column is the seven-bit binary value computed by the XOR chain in the next section. The fifth column is the integer index used to drive the 128-byte lookup table.

5. Gray Code to Binary Conversion Algorithm

The standard Gray-to-binary conversion uses a left-to-right XOR chain. The MSB of the binary number equals the MSB of the Gray code, and each subsequent binary bit is the XOR of the previous binary bit with the current Gray bit. The conversion can be implemented with no library; it is seven logic operations.

For a 7-bit Gray code g6..g0 and 7-bit binary b6..b0 (with g6 and b6 the MSB):

b6 := g6;
b5 := b6 XOR g5;
b4 := b5 XOR g4;
b3 := b4 XOR g3;
b2 := b3 XOR g2;
b1 := b2 XOR g1;
b0 := b1 XOR g0;

The result b6..b0 is an unsigned integer 0..127. If the application needs a signed value centered around mid-scale, subtract 64 to get a range of −64 to +63.

6. Building the 128-Byte Lookup Table

Once the seven-bit binary value is computed, it indexes a 128-element array that translates the binary value to a linear position 0..127 in the order the datasheet specifies. The array can be implemented as a data block in TIA Portal.

Create a global DB named DB_EAW0J_Decode with the following declaration:

// Data block DB_EAW0J_Decode
{
   GrayToBin : ARRAY[0..127] of USINT := [127, 63, ...];   // binary value for each shaft position
   BinToPos  : ARRAY[0..127] of USINT := [0,   1,  2, ...];  // linear position for each binary value
}

The GrayToBin array is the output of the Gray-to-binary conversion; you fill it once with the 128 values computed by the XOR chain applied to the encoder's contact table. The BinToPos array is the inverse mapping: it takes the seven-bit binary value b6..b0 (interpreted as an integer 0..127) and returns the linear position. Both arrays are taken directly from the datasheet's 256-byte conversion table.

Practical filling technique. Open the encoder datasheet's PDF, copy the 128 entries, paste them into a spreadsheet, and then paste the result into a TIA Portal DB initial value column. For very large tables, generate the DB from source by exporting the DB and pasting the values into the source file, replacing 0x with the Siemens 16# prefix. Then recompile the project and the DB is populated.

7. TIA Portal Implementation

Implement the conversion in a function block, then call the FB once per scan (or once on demand) with the seven-bit input image. The FB returns both the raw binary index and the linear position 0..127.

7.1 FB Interface

Section Name Type Comment
Input RawByte BYTE Image of the seven encoder inputs (bits 0..6)
Input UseLookup BOOL TRUE = apply the 128-byte lookup table; FALSE = use the raw binary value
Output BinaryValue USINT 0..127 seven-bit binary index
Output LinearPosition USINT 0..127 linear shaft position (after lookup)
Output GrayValue USINT 0..127 raw Gray code read

7.2 Structured Text Implementation

FUNCTION_BLOCK FB_EAW0J_Decode
VAR
    g0, g1, g2, g3, g4, g5, g6 : BOOL;
    b0, b1, b2, b3, b4, b5, b6 : BOOL;
    binVal                       : USINT;
    linPos                       : USINT;
END_VAR

// 1. Read the seven-bit Gray code from the input byte
g6 := RawByte.%X6;
g5 := RawByte.%X5;
g4 := RawByte.%X4;
g3 := RawByte.%X3;
g2 := RawByte.%X2;
g1 := RawByte.%X1;
g0 := RawByte.%X0;

// 2. Convert Gray to binary with the XOR chain
b6 := g6;
b5 := b6 XOR g5;
b4 := b5 XOR g4;
b3 := b4 XOR g3;
b2 := b3 XOR g2;
b1 := b2 XOR g1;
b0 := b1 XOR g0;

// 3. Pack the binary bits into an integer 0..127
binVal.%X6 := b6;
binVal.%X5 := b5;
binVal.%X4 := b4;
binVal.%X3 := b3;
binVal.%X2 := b2;
binVal.%X1 := b1;
binVal.%X0 := b0;

GrayValue   := RawByte AND 16#7F;   // diagnostic: raw pattern
BinaryValue := binVal;

// 4. Look up the linear position in the datasheet table
IF UseLookup THEN
    LinearPosition := DB_EAW0J_Decode.BinToPos[binVal];
ELSE
    LinearPosition := binVal;
END_IF;

The XOR operator on BOOL variables in TIA Portal is XOR. The .%X6 notation addresses bit 6 of a byte or USINT. Pack the seven resulting bits back into a USINT with the same .%X6 style. The lookup is a single array index operation, which executes in O(1) regardless of the array size.

7.3 Ladder Logic Equivalent

For a pure ladder implementation, place the FB on a single rung and supply the seven %I0.0..%I0.6 bits as RawByte inputs. Inside the FB, do not split the conversion into 127 rungs of comparison as the earliest draft suggested. The XOR chain is seven contacts in series-parallel and is cleaner than a comparison ladder.

      %I0.0 ----+-------( g0 )
      %I0.1 ----+-------( g1 )
      %I0.2 ----+-------( g2 )
      %I0.3 ----+-------( g3 )
      %I0.4 ----+-------( g4 )
      %I0.5 ----+-------( g5 )
      %I0.6 ----+-------( g6 )

   [ Gray->Bin XOR chain: 7 rungs, each one ( --[ XOR ]-- ) ]

   [ Output: LinearPosition := DB_EAW0J_Decode.BinToPos[binVal] ]

Each rung of the XOR chain looks like:

      b6       g5
   --| |---(XOR)--( b5 )--

The ladder form is functionally identical and is preferred by maintenance staff who are not yet familiar with Structured Text.

8. Scaling to Engineering Units

For a 128-state encoder, the resolution is 360°/128 = 2.8125° per step. The application can convert the linear position to degrees, motor turns, or user units.

// Real, degrees
PositionDeg := INT_TO_REAL(LinearPosition) * 2.8125;

// Real, fraction of full scale
PositionNorm := INT_TO_REAL(LinearPosition) / 127.0;

// Integer, 0..10000 (0.01 % steps)
PositionEPU := (INT_TO_REAL(LinearPosition) * 10000) / 127;

Use the integer engineering-unit value as the closed-loop setpoint for the JGY-370 driver. The JGY-370 typically accepts a 0–5 V or 0–10 V analog command; scale the integer to an analog output (AQ) on the 1214C, or use a PWM output filtered to DC.

9. Verification Procedure

  1. Open TIA Portal and download the project to the 1214C. Confirm the CPU is in RUN with no diagnostic errors.
  2. Create a watch table that contains RawByte, GrayValue, BinaryValue, and LinearPosition from the FB instance DB.
  3. Power the encoder. Verify the seven input LEDs on the 1214C module match the pattern printed on the encoder body for position 0.
  4. Manually rotate the encoder one step clockwise. Confirm the watch table's LinearPosition increments by exactly 1.
  5. Continue rotating through all 128 steps. Confirm the count is monotonic and returns to 0 after step 127.
  6. Reverse direction. Confirm the count decrements by 1 per step. A miscount in reverse indicates the datasheet's 256-byte conversion table should be used in its directional form, not the simple 128-entry version.
  7. Drive the JGY-370 from position 0 to position 127 and back with the motor driver. Confirm the motor moves the same number of mechanical steps in both directions.

10. Diagnostic and Troubleshooting Matrix

Symptom Likely cause Fix
Watch table shows a constant value Encoder common not connected to 24 V, or cable broken Verify 24 V on the encoder common terminal with a multimeter
Pattern changes but LinearPosition jumps randomly Gray-to-binary XOR chain wired in the wrong order Confirm b6 = g6 is the first stage, then chain down to b0
Count goes 0, 1, 3, 2, ... Bits are read MSB-first instead of LSB-first, or vice versa Swap the bit order in the Gray-to-binary block; re-verify against datasheet
Count decrements when shaft rotates clockwise Bit-to-position mapping uses the reverse-rotation half of the 256-byte table Re-populate BinToPos from the forward-rotation half of the datasheet table
Some positions are skipped Input filter too long, or input is bouncing past a step Reduce input filter from 12.8 ms to 6.4 ms; verify the JGY-370 does not over-shoot the step
DI LEDs flicker when shaft is stationary Contact bounce on the EAW0J mechanical wipers Increase the input filter on the seven used channels; debounce in software with a 10 ms ON-delay
Watch table value matches datasheet but is not linear (e.g. position 0 → 127, position 9 → 72) Application is reading BinaryValue instead of LinearPosition Use the LinearPosition output of the FB; the binary value is a diagnostic
Value is stable for several scans then jumps Common-mode noise on the encoder cable; ground loop Connect shield at the cabinet end only; verify 24 V supply is clean

11. Performance and Timing

The 1214C reads the seven DI in a single input-image update, which is 1.0 ms by default at OB1 cycle time. The XOR chain executes in seven logic operations. The array lookup is a single indexed load. End-to-end latency from shaft step to LinearPosition valid is therefore less than 2 OB1 cycles, typically 1.5–2 ms. A JGY-370 with a 30 RPM output shaft moves 360°/30 = 12°/s, or 0.012°/ms; the PLC latency is well within the 2.8125° step size, so there is no risk of missing a step at any reasonable slew rate.

If higher update rates are required, call the FB from a cyclic OB (such as OB30 at 2 ms) instead of OB1. The HSC and high-speed counter functions on the 1214C are not used here, because the EAW0J is not an incremental encoder.

12. Integration with S7-1200 Technology Objects

If the application later migrates to a real SSI or PROFINET absolute encoder, the same TIA Portal project can host a TO_PositioningAxis with an SSI absolute encoder. The Siemens Technology Object framework reads the absolute value on startup, monitors the value during operation, and supplies the position to the axis control. For that migration, refer to the official Siemens FAQ on encoder parameterization for SIMATIC S7 Technology objects, which documents how the absolute value is read on startup and why it cannot be monitored as easily as the incremental actual value.

See the official Siemens KB attachment: Encoder parameterization FAQ for SIMATIC S7 Technology (V12). This reference applies to TO_PositioningAxis with SSI/PROFINET encoders and is not a direct solution for the EAW0J mechanical encoder, but it is the correct reference for the next step in the migration path.

13. Recommendations and Migration Path

  • Keep the EAW0J decode FB as a reusable block in the project library. It can serve any 7-bit Gray-code contact encoder from the same vendor family.
  • If the application grows beyond 128 states, upgrade to an SSI absolute encoder. The S7-1200 supports SSI on the onboard DI or on a TM PosInput module. The same XOR chain logic is no longer required; the SSI handler in TIA Portal returns a scaled position directly.
  • If noise on the mechanical encoder becomes a problem, the EAW0J family includes a 1024-state variant. A 1024-state contact encoder still uses 10 bits, but the input filter and OB30 cycle time on the 1214C will be the limiting factor rather than the XOR chain.
  • For PROFINET-based absolute encoders, use the SIMATIC S7-1200 PROFINET port and configure a PROFINET IO device. The TIA Portal device configuration handles the decode entirely on the encoder side, and the application sees a 32-bit scaled position.

Which TIA Portal language is best for this decode?

Structured Text (SCL) is the cleanest choice for the seven-bit XOR chain and the array lookup. Ladder logic works for maintenance staff who prefer graphical representation, but ST avoids the 127-rung comparison ladder. Either language can be used to host the FB described above; the choice is a maintenance preference, not a technical constraint.

Do I need a special function block or library to convert Gray code to binary?

No external library is required. The conversion is seven XOR operations: b6 := g6; b5 := b6 XOR g5; down to b0 := b1 XOR g0. This is implemented in TIA Portal with built-in boolean operators and adds no project dependencies. The 128-entry lookup table is then a single indexed array access.

Why is the encoder value not linear (for example, position 0 reads 127, position 9 reads 72)?

The seven-bit pattern is a Gray code, not a binary up-counter. Each seven-bit code maps to a unique position through the datasheet's 256-byte conversion table, but the binary value of the seven-bit pattern is not equal to the shaft position. Use the lookup table (BinToPos) to convert the seven-bit binary value to the linear position 0..127, not the raw seven-bit value directly.

Can I use the high-speed counter (HSC) inputs of the 1214C for the EAW0J?

No. The EAW0J is a contact-closure absolute encoder, not an incremental encoder with A/B quadrature. The HSC is designed for pulse trains, not for static contact patterns. Read the seven EAW0J output pins with ordinary digital inputs and decode in software. If the application later migrates to an incremental encoder, then the HSC inputs can be used with the CTRL_HSC instruction.

What is the maximum rotation speed the 1214C can track with the EAW0J?

The seven onboard DI are filtered with a 0.1–12.8 ms input filter. With a 6.4 ms filter and a 360°/128 = 2.8125° step, the maximum rotation is roughly 1 step per 6.4 ms, or 156 steps/s = 439°/s = 73 RPM. In practice, the JGY-370 gear-motor (typical 30–200 RPM) runs below this limit. For higher rotation, use an SSI or PROFINET encoder on a TM PosInput or onboard PROFINET port.

Back to blog