Overview: Why the S7-200 Cannot Use HSC with an Absolute Encoder
The SIMATIC S7-200 family (CPU 221/222/224/224XP/226) integrates High-Speed Counters (HSC0–HSC3) that are designed exclusively for incremental pulse trains. The HSC inputs are qualified for quadrature, pulse-and-direction, and up/down pulse trains from incremental encoders. STEP 7 Micro/WIN and the HSC wizard do not provide a technology object or function block that natively decodes a parallel multi-bit absolute position word from a single scan.
An absolute encoder such as the Omron E6C2-AG5C presents a stable multi-bit code word on its parallel output lines. For 256 counts/rev the word is 8 bits wide; for 1024 counts/rev the word is 10 bits wide. The code is non-incremental: more than one bit changes between adjacent mechanical positions, which is exactly why Gray code is used. Only one Gray bit toggles at a time, so a single sample of the input byte is always a valid code. Because the parallel word is not a pulse train, HSC counters cannot be used. The eight Gray-coded bits are read as a standard digital input byte and converted to binary in the user program, typically inside a subroutine executed every scan.
Omron E6C2-AG5C Encoder Specifications
The E6C2 is a 40 mm-diameter absolute rotary encoder. The model suffix decodes as follows (verify against the nameplate and the Omron E6C2 datasheet shipped with the unit):
| Suffix token | Meaning |
|---|---|
| E6C2- | Series: 40 mm absolute rotary encoder |
| A | Output code: Gray (not BCD, not natural binary) |
| G | Output configuration: NPN open-collector (sinking) |
| 5C | Resolution and shaft code (cross-check against the Omron datasheet for exact counts per revolution) |
Key electrical characteristics to verify on the datasheet before wiring:
| Parameter | Typical value | Engineering note |
|---|---|---|
| Supply voltage Vcc | 12 VDC ±10% or 24 VDC ±10% (model dependent) | Check the encoder label; E6C2-AG* variants are commonly 12 VDC |
| Output type | NPN open-collector | Pull-up required; PLC inputs must accept a sourcing signal |
| Output code | Gray, parallel | Number of output lines = log2(resolution) |
| Resolution variants | 256, 360, 720, 1024 counts/rev (model dependent) | 8 lines for 256, 9 lines for 512, 10 lines for 1024 |
| Max response frequency | 20 kHz (model dependent) | Sets the maximum mechanical RPM |
| Shaft speed | ≤ 6000 rpm (model dependent) | Derate for continuous operation |
| Cable | Pre-wired or connectorised; 8–10 conductors + supply | Use shielded cable, drain grounded at one end only |
S7-226 Digital Input Wiring and Sinking/Source Considerations
The S7-226 provides 24 digital inputs at 24 VDC nominal. The S7-200 input structure is a PNP (sourcing) type: it sources current out of the I terminal, so the input is ON when the connected sensor pulls the line to +24 V (positive switching). The Omron E6C2-AG5C is NPN open-collector (sinking): it pulls the output line down to 0 V when active, otherwise the line floats.
There are two correct wiring approaches:
- External pull-up resistor — Fit a 2.2 kΩ to 4.7 kΩ resistor from each encoder output line to the +24 V PLC supply. The NPN transistor pulls the line low when OFF; when ON the transistor opens and the pull-up drives the line to +24 V. The PLC sees a clean sourcing logic level.
- Level-shifting interface module — Use a sinking-to-sourcing converter (Phoenix Contact MINI-MCR, Wago 857, or equivalent) between the encoder and the PLC. Preferred when the encoder is 12 VDC and the PLC is 24 VDC, or when the cable is long.
Typical pin assignment for an 8-bit E6C2-AG5C (verify against the datasheet):
| Wire colour (typical) | Signal | Connect to |
|---|---|---|
| Red | +V (12 or 24 VDC per model) | Encoder supply +V |
| Black | 0 V (common) | Encoder supply 0 V (bond to PLC 0 V at one point) |
| Brown | Gray bit 0 (LSB) | I0.0 with 2.2 kΩ pull-up to +24 V |
| Orange | Gray bit 1 | I0.1 with 2.2 kΩ pull-up to +24 V |
| Yellow | Gray bit 2 | I0.2 with 2.2 kΩ pull-up to +24 V |
| Green | Gray bit 3 | I0.3 with 2.2 kΩ pull-up to +24 V |
| Blue | Gray bit 4 | I0.4 with 2.2 kΩ pull-up to +24 V |
| Violet | Gray bit 5 | I0.5 with 2.2 kΩ pull-up to +24 V |
| Grey | Gray bit 6 | I0.6 with 2.2 kΩ pull-up to +24 V |
| White | Gray bit 7 (MSB) | I0.7 with 2.2 kΩ pull-up to +24 V |
| Shield/drain | Cable shield | Earth ground at panel entry only |
Gray Code to Binary Conversion Theory
Gray code is a reflected binary code in which exactly one bit changes state between adjacent integer values. Converting an N-bit Gray word to a binary integer is performed by XOR-ing the Gray MSB into the next bit, then that result into the next, cascading down to the LSB. The recurrence is:
B[N-1] = G[N-1]
B[i] = B[i+1] XOR G[i] for i = N-2 down to 0
Equivalently, using the bitwise form that is more convenient in a byte-oriented PLC:
B = G XOR (G >> 1) XOR (G >> 2) XOR ... XOR (G >> (N-1))
Worked example (8-bit, position 5):
| Position | Decimal | Binary | Gray |
|---|---|---|---|
| 0 | 0 | 0000 0000 | 0000 0000 |
| 1 | 1 | 0000 0001 | 0000 0001 |
| 2 | 2 | 0000 0010 | 0000 0011 |
| 3 | 3 | 0000 0011 | 0000 0010 |
| 4 | 4 | 0000 0100 | 0000 0110 |
| 5 | 5 | 0000 0101 | 0000 0111 |
For position 5, Gray = 0b00000111. Applying the cascade:
B7 = 0
B6 = B7 XOR G6 = 0 XOR 0 = 0
B5 = B6 XOR G5 = 0 XOR 0 = 0
B4 = B5 XOR G4 = 0 XOR 0 = 0
B3 = B4 XOR G3 = 0 XOR 1 = 1
B2 = B3 XOR G2 = 1 XOR 1 = 0
B1 = B2 XOR G1 = 0 XOR 1 = 1
B0 = B1 XOR G0 = 1 XOR 1 = 0 → 0b00000101 = 5 ✓
S7-226 Program Structure and Memory Map
The S7-226 has the following relevant resources (refer to the S7-200 System Manual for full specifications):
| Resource | Quantity | Use in this application |
|---|---|---|
| Digital inputs | 24 (I0.0–I0.7, I1.0–I1.5, I2.0–I2.7) | I0.0–I0.7 read the 8 Gray bits |
| Digital outputs | 16 (Q0.0–Q0.7, Q1.0–Q1.7) | Status and alarm outputs (e.g. position-error flag) |
| High-Speed Counters | HSC0 (I0.0/I0.1/I0.2), HSC1 (I0.6/I0.7/I1.0/I1.1), HSC2 (I1.2–I1.5), HSC3 (I0.1) | Not used; must be disabled to free I0 for parallel data |
| User program | 8 KB / 16 KB / 24 KB depending on order number | Gray-to-binary routine and position scaling |
| Data memory V | 5 KB (CPU 226) or 2 KB (CPU 224) | Position, scaled distance, error flags, turn counter |
| Scan time | typ. 0.8 ms per 1 K boolean | Subroutine call adds < 200 µs for 8-bit conversion |
Suggested memory map (assign final symbols in the STEP 7 Micro/WIN Symbol Table):
| Symbol | Address | Type | Description |
|---|---|---|---|
| GrayByte | VB100 | BYTE | Process image of I0.0–I0.7 (the live Gray word) |
| BinaryByte | VB101 | BYTE | Converted binary position 0..255 |
| BinaryWord | VW101 | WORD | 16-bit view of the binary position (zero-extended) |
| PrevPos | VW103 | WORD | Previous position for monotonicity and wrap detection |
| TurnCount | VD105 | DWORD | Software multi-turn counter (coarse resolver equivalent) |
| PosError | V109.0 | BOOL | Latched error: more-than-1-LSB jump between scans |
| PosReal_mm | VD110 | REAL | Scaled distance in mm |
| Origin | VD114 | REAL | Homing offset (retained in EEPROM via V-memory copy) |
| Scratch | VB110 | BYTE | Working copy of Gray word used by the subroutine |
Ladder Logic Implementation: Gray-to-Binary Subroutine (SBR0)
The subroutine reads input byte IB0, performs the XOR cascade in V-memory, and stores the result in VB101 / VW101. The conversion uses 6 SRB+XORB pairs (the seventh shift, G>>7, contributes all zeros and is omitted). Each shift moves one more bit of the running Gray word into position; each XOR folds that bit into the binary result.
Complete subroutine SBR0 — 8-bit Gray to binary:
// SBR0 : Gray8_to_Bin
// Inputs : VB100 = Gray code byte (8 bits)
// Outputs: VB101 = binary value 0..255
// Method : B = G XOR (G>>1) XOR (G>>2) ... XOR (G>>6)
Network 1 // Snapshot input and initialise
MOVB IB0, VB100 // GrayByte = current encoder word
MOVB VB100, VB110 // Scratch = working copy of Gray
MOVB 0, VB101 // BinaryByte = 0
Network 2 // B ^= (G >> 1)
SRB VB110, 1 // Scratch = G >> 1
XORB VB110, VB101 // Result ^= Scratch
Network 3 // B ^= (G >> 2)
SRB VB110, 1 // Scratch = G >> 2
XORB VB110, VB101 // Result ^= Scratch
Network 4 // B ^= (G >> 3)
SRB VB110, 1 // Scratch = G >> 3
XORB VB110, VB101 // Result ^= Scratch
Network 5 // B ^= (G >> 4)
SRB VB110, 1 // Scratch = G >> 4
XORB VB110, VB101 // Result ^= Scratch
Network 6 // B ^= (G >> 5)
SRB VB110, 1 // Scratch = G >> 5
XORB VB110, VB101 // Result ^= Scratch
Network 7 // B ^= (G >> 6)
SRB VB110, 1 // Scratch = G >> 6
XORB VB110, VB101 // Result ^= Scratch
// VB101 now holds the binary value 0..255
// VW101 (word view) is automatically zero-extended by STEP 7 Micro/WIN
Monotonicity check and multi-turn wrap detection (called from OB1 immediately after SBR0):
Network 10 // Detect wrap and update turn counter
// If new position == 0 and previous == N-1, increment turns
// If new position == N-1 and previous == 0, decrement turns
// Replace 255 with the actual resolution-1 value (e.g. 359 for 360 PPR)
AB= VB101, 0 // new position == 0?
AB= VW103, 255 // previous == 255 (N-1)?
EU // positive edge on both
INCD VD105 // TurnCount++
AB= VB101, 255 // new == 255 (N-1)?
AB= VW103, 0 // previous == 0?
EU
DECD VD105 // TurnCount--
Network 11 // Latch position-error flag
// If |new - previous| > 1 LSB after turn-counter update, raise PosError
MOVW VW101, VW200 // copy for ABS
ABS // VW200 = |new - previous|
AW> VW200, 1
S V109.0, 1 // PosError = 1
Step-by-Step Commissioning Procedure
- Verify the encoder nameplate. Confirm Vcc, output type, resolution, and the wire colour code against the Omron E6C2 datasheet supplied with the unit. Do not trust generic pin-out tables.
- Power the encoder separately if it is 12 VDC; do not back-feed 24 V from the PLC. Bond the encoder 0 V to the PLC 0 V at a single point in the panel to avoid ground loops.
- Wire the eight Gray bits to I0.0–I0.7 with a 2.2 kΩ pull-up resistor on each line to +24 V at the PLC terminal strip. Keep the cable in a separate conduit at least 100 mm from VFD and motor power cables.
- Disable HSC0, HSC1, HSC2, and HSC3 in the PLC configuration. The S7-200 firmware may rewrite the process image of any input assigned to a counter, which corrupts the Gray byte. Use System Block → Input Filters to set the filter for I0.0–I0.7 to 0.2 ms (faster rotation requires it; default 6.4 ms is too slow for 8-bit transitions at moderate RPM).
- Create a Status Chart in STEP 7 Micro/WIN with the symbols GrayByte (VB100), BinaryByte (VB101), PrevPos (VW103), TurnCount (VD105), PosError (V109.0). Set the chart to "Continuous Poll" at 100 ms.
- Manually rotate the shaft one full revolution. Observe that BinaryByte increments monotonically from 0 to N-1 and that TurnCount increments once on the wrap (or decrements on reverse rotation). All N steps must appear, none skipped.
- Download the Gray→binary subroutine and place an unconditional call to SBR0 at the top of OB1. The subroutine must run every scan to track motion; do not gate it behind a permissive.
- Scale the binary value to engineering units. Distance per LSB = total travel / counts per revolution × gear ratio. For a 256-count encoder geared so one revolution = 1.0 m, distance = BinaryByte × 3.90625 mm. Store the scaled real in VD110 using ITD + DTR + MULR + ROUND.
- Add the homing sequence. At machine start, command a slow jog to the reference marker, capture the absolute position as the origin, and store the offset in VD114. Subtract the offset from every live position to obtain a machine-zeroed coordinate.
- Save the project to EEPROM via "Program → Copy Program to EEPROM" so the origin offset and V-memory retentive range are retained across power cycles. Configure VD114 as retentive in System Block → Retentive Ranges.
- Force a power-cycle at mid-position and confirm the position is recovered to within ±1 LSB. This validates the absolute property of the encoder and the correct retention of the homing offset.
Verification and Diagnostic Checks
Use the STEP 7 Micro/WIN Status Chart to validate the following acceptance criteria before the encoder is placed in production control:
| Test | Expected behaviour | Pass criterion |
|---|---|---|
| Power-on at a fixed position | BinaryByte holds a stable value that does not change with the PLC in STOP | Stable for ≥ 10 s |
| One full mechanical revolution CW | BinaryByte increments from 0 to N-1 | All N steps appear once, none skipped |
| One full mechanical revolution CCW | BinaryByte decrements from N-1 to 0 | All N steps appear once, none skipped |
| Stop at a calibrated dial-gauge position | BinaryByte matches the expected position | ± 1 LSB |
| Power-cycle at mid-position | BinaryByte returns to the same value within ±1 LSB | No drift, no re-homing required |
| Static noise with shaft locked | BinaryByte does not toggle while the shaft is mechanically fixed | Zero transitions over 60 s |
| Scan-time impact | OB1 scan time increases by < 200 µs after adding the subroutine | Verified in "PLC → Information → Scan Cycle Time" |
| Multi-turn continuity | TurnCount increments on (N-1 → 0) and decrements on (0 → N-1) | Count matches revolutions applied to the shaft |
Alternative: SSI Absolute Encoders on S7-1200/1500
Newer Siemens platforms offer native absolute encoder support that removes the parallel-wiring and Gray-conversion burden entirely. The S7-1200 (with a CM1241 RS422/485 or an SM1281 SSI module) and the S7-1500 (TM PosInput 2 or the technology object SSI_Absolute_Encoder) read SSI-protocol encoders over a single twisted pair, deliver the position pre-scaled in engineering units, and handle multi-turn counting inside the technology object itself.
Configuration reference: SSI absolute encoder (S7-1500) — TIA Portal V20 technology object documentation. The technology object exposes parameters such as the bit number of the LSB of the position value inside the SSI frame, the number of leading non-data bits, and the frame type (multiturn or singleturn). Use this documentation to set the LSB-offset parameter to the correct position inside the encoder word, and to enable the bit-strobe and mono-time parameters to match the encoder datasheet.
If the application is in early development and a parallel Gray-code encoder has not yet been procured, evaluate the following trade-off:
| Approach | Wiring | PLC scan load | Resolution ceiling | Cost |
|---|---|---|---|---|
| S7-226 + parallel Gray (this article) | 8+ conductors, pull-ups, shielded cable | ~200 µs of scan for 8-bit conversion | 8–16 bits practical | Lowest |
| S7-1200 + CM1241 + SSI encoder | 4 conductors (clock, data, supply, GND) | Handled by the CM/SM module | Up to 25 bits (multiturn) | Medium |
| S7-1500 + TM PosInput 2 + SSI | 4 conductors | Handled by the technology object | Up to 31 bits | Highest |
Troubleshooting Matrix
| Symptom | Likely cause | Action |
|---|---|---|
| BinaryByte reads 0 in all shaft positions | Pull-up missing, or encoder 0 V not bonded to PLC 0 V | Install 2.2 kΩ pull-ups on every output line; verify common 0 V at a single point |
| BinaryByte reads 255 (or N-1) constantly | Encoder supply out of range, or all inputs stuck high | Measure Vcc at the encoder terminals; check load on the NPN outputs |
| BinaryByte jumps by 2 or more between scans | HSC is still active on that input byte, or input filter is too slow | Disable HSC0–HSC3 in the System Block; set I0 input filter to 0.2 ms |
| Position drifts after power-cycle | Homing not executed, or origin offset not retained | Add homing routine; configure VD114 as retentive; copy program to EEPROM |
| Reading is stable but inverse (counts down when shaft turns CW) | Bit order reversed in the input byte | Swap I0.0 ↔ I0.7 wiring at the terminal strip, or XOR the result with 0xFF in software |
| Bit 7 stuck or noisy while others are clean | MSB cable routed next to a VFD output cable | Reroute with ≥ 100 mm segregation; use shielded cable with drain grounded at one end only |
| Position wraps unexpectedly at mid-revolution | Encoder resolution is 360 (or another non-power-of-two value) and the mask is wrong | Replace 255 with (N-1) in the wrap detection; apply modulo-N mask after conversion: B = B AND (N-1) |
| OB1 scan time increased by > 1 ms | Subroutine called inside a tight loop or cyclic interrupt | Call SBR0 once per scan from OB1 only; remove any redundant call sites |
| PosError flag raises immediately on power-up | V-memory not retentive; PrevPos initialised to 0 causes a false 0 → N-1 jump on first sample | Initialise PrevPos to 0 only on first scan (SM0.1); make VW103 retentive in System Block |
| Reading is correct at low RPM but skips bits at high RPM | Input filter set to 6.4 ms is slower than the bit-cell time | Reduce input filter to 0.2 ms for I0.0–I0.7 |
Field-Proven Caveats and Engineering Notes
- Source/sink trap. The most common commissioning failure on the S7-200 is treating the E6C2-AG5C as a sourcing output because the datasheet pin-out can look like a sourcing stage. It is NPN open-collector; without pull-ups the S7-200 input never sees a high level and BinaryByte stays at 0.
- Input filter setting. The S7-200 default input filter is 6.4 ms. For an 8-bit encoder at 360 rpm the bit-cell time is 21 ms, so the default is safe. For higher-resolution encoders at higher RPM (e.g. 1024 counts at 600 rpm, bit-cell ≈ 9 ms) reduce the filter to 0.2 ms in the System Block to avoid missed transitions.
- HSC conflict. The S7-226 shares I0.0–I0.5 with HSC0, HSC1, and HSC3. If any HSC is enabled in the project the firmware may rewrite the process image of those bytes on certain transitions, corrupting the Gray code. Always explicitly disable all four HSCs when using I0 as a parallel data port, even if no HSC instruction is in the program.
- Multi-turn counting. The E6C2-AG5C is a single-turn absolute encoder. To track total travel beyond one revolution, the user program must implement a wrap counter: detect the transition (N-1 → 0) and increment TurnCount; detect (0 → N-1) and decrement. This is the software equivalent of the coarse/fine resolver pattern used in long-travel machines.
- BCD versus binary. The Omron E6C2-AG*C outputs Gray code, not BCD. BCD conversion is only required if a downstream display expects a per-decade digit format. For distance calculation, keep the value in binary integer and scale to a REAL at the end of the calculation chain.
- STEP 7 Micro/WIN status chart refresh. The default chart refresh is 1 s. During manual rotation use "Continuous Poll" at 100 ms to see the binary position update live; otherwise the chart misses intermediate steps.
- First-scan initialisation. The wrap detection compares the current position to the previous position. On the first scan after power-up, PrevPos is undefined or zero, which can produce a spurious PosError or an erroneous TurnCount. Initialise PrevPos to 0 only on first scan (SM0.1 contact) and use the result of the first conversion as the baseline.
- Shielded cable routing. The encoder cable should enter the panel through a dedicated cable gland, run in its own trunking, and maintain ≥ 100 mm separation from any AC drive output cable, servo power cable, or welding lead. Ground the cable shield at the panel entry only; floating both ends creates a ground loop, grounding both ends defeats the shield.
Frequently Asked Questions
Can the S7-226 High-Speed Counters read an Omron E6C2-AG5C absolute encoder directly?
No. The HSC inputs on the S7-200 (HSC0–HSC3) are designed for incremental pulse trains — single, quadrature, or pulse+direction. An absolute encoder presents a parallel multi-bit code word on its output lines, not a pulse stream. The eight Gray-coded bits must be read as a standard digital input byte (I0.0–I0.7) and converted to binary in a ladder subroutine. HSC0–HSC3 must be disabled in the System Block to free I0.0–I0.5 for this purpose, otherwise the firmware may overwrite the process image of those bytes.
Does the E6C2-AG5C output Gray code or BCD?
The "A" in the suffix E6C2-AG5C denotes Gray code output, not BCD and not natural binary. Gray code guarantees that only one bit changes between adjacent shaft positions, eliminating the read ambiguity that binary or BCD would produce if the PLC sampled between bit transitions. BCD is only required if a downstream display needs a per-decade digit format; for distance calculation keep the converted value in binary and scale to engineering units.
Why do I need pull-up resistors on every encoder output line?
The Omron E6C2-AG5C is an NPN open-collector (sinking) device: each output transistor pulls the line to 0 V when active and otherwise leaves the line floating. The S7-200 digital inputs are PNP (sourcing) type and require a positive voltage to register an ON state. A pull-up resistor (2.2 kΩ to 4.7 kΩ to +24 V) on every output line converts the floating/NPN signal into a clean sourcing logic level. Without pull-ups the input reads as 0 V at every shaft position.
How do I track multiple revolutions if the E6C2-AG5C is single-turn?
Implement a software multi-turn counter in the user program. After the Gray-to-binary conversion, compare the new position to the previous position stored in VW103. If the new value is 0 and the previous was N-1, increment VD105 (turn counter). If the new value is N-1 and the previous was 0, decrement VD105. The total absolute position is then (turns × N) + current_position, scaled to engineering units. Configure VD105 and the origin offset as retentive so the count survives a power cycle.
What is the maximum scan-time impact of the Gray-to-binary subroutine on a CPU 226?
For an 8-bit encoder the shift-and-XOR cascade uses 6 SRB+XORB pairs, approximately 60–80 µs on a CPU 226. For a 16-bit encoder the pattern extends to 15 pairs, adding roughly 150–200 µs to OB1. Both figures are well within the S7-226's 0.8 ms typical scan budget for a small program. Place the SBR0 call once at the top of OB1, never inside a time-critical cyclic interrupt, and never gated behind a permissive that could stall the read.