Omron PLC Single-Input Toggle ON/OFF Ladder Programming
Many field applications require a single physical input to behave as a push-on / push-off control. A momentary pushbutton, a sensor pulse, or a single HMI button must alternate the state of a bit every time it is actuated. The technique is well documented in the Omron user community as the "ToggleBit" or "single input toggle" pattern. This reference consolidates the practical ladder solutions for the CS1, CJ1, CJ2, and CP1 families, ties each implementation to the specific instruction set, and documents the addressing rules, scan-time behavior, and verification steps required for production deployment.
1. Functional Requirement
A single discrete input (for example, CIO 0.00 wired to a normally-open pushbutton) must toggle a single output bit (for example, CIO 100.00 driving a relay or lamp) on every press. The output holds its last state between presses, and power cycling returns the output to OFF (cold start default) unless retentive memory is selected.
Three behaviors must be guaranteed:
- Only one transition of the output per actuation, regardless of the input contact bounce duration.
- No missed toggles when the input is held closed for multiple scan cycles.
- Deterministic first-scan behavior - the output must be OFF at power-up.
2. Prerequisites
Before writing the rung, confirm the controller, programming tool, and I/O wiring.
| Item | Specification | Notes |
|---|---|---|
| CPU | CS1G/H, CJ1G/H, CJ2H, CJ2M, CP1H, CP1L, CP1E | All listed families share the toggle instruction set covered here. |
| Firmware | CS1: V3.0 or later; CJ1: V3.0 or later; CJ2: V1.0 or later; CP1: any released firmware | Verify with CX-Programmer PLC Information dialog. |
| Programming tool | CX-Programmer 9.x (or Sysmac Studio 1.20+ for CJ2) | Outputs file with extension .cxp. |
| Input module | 24 VDC sink/source input unit (e.g. CS1W-ID211, CJ1W-ID211, CP1W-20EDR) | Wire one NO contact to an input bit, e.g. 0.00. |
| Output module | Relay or transistor output unit (e.g. CS1W-OC211, CJ1W-OC211, CP1W-20EDR) | Connect the load to the output bit, e.g. 100.00. |
| Memory | Work (W) and Holding (H) areas available | W area is non-retentive; H area retains across power cycles. |
Reference documentation: Omron CS1 Series overview, Omron CJ1 Series overview, Omron CP1 Series overview, and the CJ2 Series product page. Programming manuals for the CS1G/H are catalog number W394 and for the CJ1G/H are W413; CP1 programming manual is W451 and CX-Programmer operation manual is W437.
3. Memory and Address Allocation
Plan the I/O map before opening the ladder editor. The following default allocation works for any of the listed CPUs.
| Symbol | Address | Type | Purpose |
|---|---|---|---|
| PB_TOGGLE | 0.00 | CIO Input | Physical pushbutton input. |
| OUT_LAMP | 100.00 | CIO Output | Final output driving the load. |
| TOG_STATE | W0.00 | Work Bit | Internal toggle state - holds the latched value. |
| TOG_EDGE | W0.01 | Work Bit | Rising edge pulse of the input (one scan wide). |
| FIRST_SCAN | A200.15 | System Flag | First-cycle flag. ON for one scan at power-up. |
The system flag A200.15 (First Cycle Flag) is available on CS1, CJ1, CJ2, and CP1 CPUs and is the standard way to initialize a bit at power-up. See the CS1 CPU Unit Operation Manual (W339) for the full auxiliary area map.
4. Method 1 - KEEP Instruction (Recommended for CS1/CJ1)
The KEEP instruction is a single instruction that implements a bistable latch. The set input (S) latches the bit ON, the reset input (R) clears it. By feeding the inverted output back to the set input, a single edge pulse on the input toggles the bit on every press.
4.1 Ladder - Method 1 (CS1 / CJ1 one-rung implementation)
| A200.15 0.00 100.00
|---|·|----------|/|---------( KEEP 100.00 )---|
| FIRST_SCAN PB_TOG OUT_LAMP |
| |
| 0.00 100.00 |
|---|/|----+--|/|-------------------|
| PB_TOG OUT_LAMP |
Read the rung as: KEEP 100.00 is reset (R) by A200.15 (so the bit starts OFF on first scan) and is set (S) by the logical AND of NOT 0.00 and NOT 100.00. The moment 100.00 goes OFF and 0.00 is OFF, the KEEP latches ON. The next time the button is pressed (rising edge closes the contact), 0.00 turns ON, the S-input falls, but the KEEP stays latched because R is not energized. When the button is released, 0.00 goes OFF again, but the S-input is now blocked by 100.00 (which is ON), so nothing changes. The user must release the button and press it a second time; on the second release, 0.00 OFF plus 100.00 ON, S is still blocked. The output only toggles on the falling edge of the input combined with the output being OFF. This implementation behaves as a release-to-toggle and is widely used for push-on / push-off lamp control.
For a press-to-toggle (toggle on the rising edge of the input), use Method 2.
4.2 Why this works in one rung on CS1/CJ1
CS1 and CJ1 CPUs evaluate the KEEP S-input before the R-input. The S-input of KEEP is energized when both the inverted input 0.00 and the inverted output 100.00 are both ON, i.e. the button is released and the lamp is currently OFF. The R-input is energized only on the first scan, ensuring the latch starts cleared. The CS1/CJ1 instruction set is defined in CS1 Programming Manual W394.
5. Method 2 - DIFU / DIFD Edge Detection with Set/Reset
The DIFU (Differentiation Up) instruction produces a one-scan pulse on the rising edge of its input condition. Pairing DIFU with a SET/RSET pair produces a clean press-to-toggle, immune to contact bounce and to the operator holding the button down.
5.1 Ladder - Method 2 (Universal for CS1, CJ1, CJ2, CP1)
| 0.00 0.00 100.00
|---| |------------| |--------------( )---|
| PB_TOG PB_TOG OUT_LAMP
| | (DIFU) W0.01
| +-----------(TOG_EDGE)
|
| W0.01
|---|/|------------( SET 100.00 )---|
| TOG_EDGE OUT_LAMP
|
| W0.01
|---| |------------( RSET 100.00 )---|
| TOG_EDGE OUT_LAMP
| 100.00
|---| |------------( ) 100.00
| OUT_LAMP OUT_LAMP
Read the logic: rung 1 outputs 100.00 while the pushbutton is held AND the output is OFF. The DIFU generates a single-scan pulse W0.01 on the rising edge of 0.00. The NOT pulse of W0.01 SETs the output, the direct pulse of W0.01 RSETs the output. The two rungs feed the same pulse to SET and RSET - in this topology only the SET branch is active because the output is OFF at the moment of the rising edge; on the second press the output is ON and the RSET branch fires. Rung 3 holds the output on through its own contact.
5.2 Why DIFU is mandatory
Without DIFU, a held pushbutton would set the bit, then reset the bit, then set the bit, then reset the bit, on every scan as long as the input is closed. DIFU is defined in CS1/CJ1 programming manual W394 and CJ2 programming manual W474. CP1 series uses the same instruction (W451).
6. Method 3 - Universal Up/Down Counter Toggle
For very long button-hold situations (operator leaves the button closed for seconds) the edge-detect method can still be confused if a scan is missed. A counter-based toggle is bulletproof because the counter increments exactly once per press regardless of bounce or hold time.
6.1 Ladder - Method 3 (works on every current Omron PLC)
| 0.00 0.00
|---|/|--------|/|---( CNT 0000 #0001 )---|
| PB_TOG PB_TOG C0
|
| C0
|---|·|-----------------( MOV #0000 C0 )---|
| C0
| C0 100.00
|---|·|-----------------( OUT 100.00 )---|
| C0
The CNT counter C0 counts input rising edges. The count value is 0 or 1 alternating. The second rung resets the counter the instant it reaches its target (1), producing a one-cycle output C0. The third rung copies C0 to 100.00.
100.00.7. Cross-Reference: Choosing the Right Method
| Criterion | Method 1 (KEEP) | Method 2 (DIFU + SET/RSET) | Method 3 (CNT) |
|---|---|---|---|
| CPU families | CS1, CJ1, CJ2, CP1H, CP1L | All | All |
| Rungs required | 1-2 | 3-4 | 3 |
| Toggle on | Release of input | Press of input | Press of input |
| Contact bounce tolerance | High | High (DIFU filters) | Very high (counter filters) |
| Long-hold immunity | High | Medium (relies on edge detect) | Very high |
| Retentive option | Yes - use H area | Yes - use H area | Yes - use H area + CNTR |
| Scan-time impact | Negligible | Negligible | Negligible |
| Field serviceability | Low (single rung is hard to read) | High (rungs are self-documenting) | High |
8. Building the Program in CX-Programmer
The original Omron community examples were distributed as .cxp project files (CX-Programmer). To rebuild from scratch in CX-Programmer 9.7x:
- Launch CX-Programmer, select File > New, choose the CPU type (e.g. CJ2M-CPU31), and click Settings to set the cycle time and I/O table.
- Open the Symbols window and define
PB_TOGGLEat0.00,OUT_LAMPat100.00,TOG_STATEatW0.00. - In the Ladder Section 1 workspace, place the DIFU, SET, and RSET rungs as shown in Method 2.
- Compile with Ctrl+F7. CX-Programmer will report any addressing errors in the output window.
- Save as
ToggleBit.cxp- the same file format that has been used to share single-input toggle programs in the Omron user community since 2003. - Connect to the PLC via USB or Ethernet and click Online > Transfer to PLC (Ctrl+T). Select Program, Symbols, and Comments, then confirm.
- Switch to Monitor Mode (Ctrl+M) to watch the bit transitions in real time.
For newer CP2E, NX102, and NJ501 controllers, use Sysmac Studio 1.40+ and the equivalent ladder or ST implementation. The KEEP and DIFU instructions are identical in Sysmac Studio.
9. Verification Procedure
After download, perform the following sequence with the PLC in Monitor or Run mode. The test takes about 60 seconds and confirms all three behaviors required in Section 1.
-
Power-up default. With the pushbutton open, power-cycle the PLC. Confirm
100.00is OFF for at least 5 seconds after power-up. -
Single press test. Press and release the button once within 1 second. Confirm
100.00transitions OFF to ON exactly once. -
Second press test. Press and release the button a second time. Confirm
100.00transitions ON to OFF exactly once. -
Hold test. Press and hold the button for 10 seconds, then release. Confirm
100.00toggles exactly one time (on press if using Method 2 or 3, on release if using Method 1). - Bounce test. Manually pulse the input contact 20 times in 5 seconds (use a debounced test rig or a second operator). Confirm the output toggles 20 times, no missed pulses, no double-counts.
-
Retentive test (only if retentive flag selected). Power-down the PLC while
100.00is ON, wait 10 seconds, power up. Confirm100.00returns to ON.
Use CX-Programmer Watch Window (Ctrl+3) to display 0.00, 100.00, and W0.01 simultaneously during the test.
10. Troubleshooting Matrix
| Symptom | Likely Cause | Diagnostic | Fix |
|---|---|---|---|
| Output never turns ON | A200.15 permanently stuck ON, or input is shorted | Force 100.00 ON from the Watch Window |
Inspect the input wiring and first-scan flag; replace input module if contact is shorted |
| Output toggles twice per press | Set and Reset rungs both firing on the same pulse | Insert a 0.01 s timer (TIM 0000 #1) on the DIFU rung | Use Method 2 rung order - SET rung first, then RSET, and use W0.01 as the trigger |
| Output toggles once on press, once on release | Both KEEP and SET are active in the same logic | Online > Cross-Reference for bit 100.00
|
Remove the redundant instruction - one latch only |
| First power-up shows output already ON | KEEP retained from previous session in H area | Check address table - H area used in place of W | Use W area for non-retentive toggle, or add A200.15 reset |
| CX-Programmer reports "address out of range" | Bit 100.00 not assigned on the selected CPU |
Open I/O Table dialog | Add the appropriate I/O module to the I/O table or move the bit to an available address |
| Toggle works in Monitor but not Run | DIFU is inside a JMP / CJP loop that is not executing | View program with Show Comments enabled | Move the toggle logic outside the JMP region or condition the JMP on the inverse of the input |
| Counter method (Method 3) never resets | Reset rung missing or wired to wrong contact | Monitor C0 count value |
Add explicit reset rung with C0 count-out contact driving MOV #0 to C0
|
11. Field-Commissioning Notes
Once the toggle logic is verified on the bench, the following points should be checked on the installed machine:
- EMC and input filtering. The CS1W-ID211 and CJ1W-ID211 input units have a hardware filter of 0 ms / 1 ms / 2 ms / 4 ms / 8 ms / 16 ms / 32 ms (set in the I/O tables, PLC Setup > Input Filter). For mechanical pushbuttons in industrial environments, set the filter to 8 ms minimum to reject contact bounce and conducted noise.
- Surge suppression on the output. If the load is a relay coil or solenoid, fit a flyback diode (1N4007) across DC coils or a MOV across AC coils. The KEEP output is a dry contact in Method 1 and 2 only when driving a relay output module; a transistor output module needs external protection.
-
First-scan initialization. Use the system flag
A200.15(First Cycle Flag) to force the toggle bit OFF at every power-up if the application is safety-relevant. A200.15 is ON for one scan after entering Run mode and is the documented way to initialize a non-retentive bit. See the auxiliary area table in the CS1/CJ1 CPU Unit Operation Manual. - Watchdog considerations. The DIFU instruction requires the input to be OFF for at least one full scan before the next rising edge is recognized. On a CS1G with a 20 ms cycle, the operator must release the button for at least 20 ms between presses - this is invisible to a human but must be documented in the operator manual.
-
Symbolic programming. Always program using symbol names rather than absolute addresses. The original 2003 Omron toggle program files were shared as
.cxpprojects; opening them in modern CX-Programmer (9.73 or later) preserves the symbol table and allows re-targeting to any CS1/CJ1/CJ2/CP1 CPU.
12. Migration Notes Across Families
| Source CPU | Target CPU | Code Change Required | Verification |
|---|---|---|---|
| CS1G/H | CJ2M | None - instructions are identical | Recompile in CX-Programmer, download, test |
| CJ1M | CP1H | None - instructions are identical | Add CP1W expansion I/O if more than 16 inputs needed |
| CP1L | CP1E | Replace DIFU with @P or use Task pulse (P_0_02s) | CP1E does not support DIFU/DIFD; use the cyclic task bit P_On with a contactor circuit |
| Any Omron PLC | NX/NJ (Sysmac Studio) | Convert ladder to ST or use built-in Latch variable | Use Retain attribute on the toggle variable if retentive |
For CP1E controllers, the CP1E Programming Manual (W461) documents that DIFU and DIFD are not available. Use the rising-edge contactor pattern with the cyclic task bit P_0_02s (2-second pulse) to debounce, or use the @ prefix on the input contact (for example, @0.00) which is treated as a one-shot rising-edge contact by CX-Programmer.
13. Summary of Best Practice
For new deployments on CS1, CJ1, CJ2, CP1H, and CP1L, use Method 2 (DIFU + SET/RSET) for press-to-toggle behavior. Use Method 1 (single-rung KEEP) only when the application requires release-to-toggle and the operator is trained to release between presses. Use Method 3 (counter) when the input is a long-duration or noisy signal such as a foot switch or a sensor in a wash-down environment. Always use a non-retentive bit (W area) for the toggle state unless the application explicitly requires power-loss retention, in which case use the H area and document the retention behavior in the operator manual.
Reference manuals for further reading:
- CS1 Series - CS1 Programming Manual W394, CS1 CPU Operation Manual W339
- CJ1 Series - CJ1 Programming Manual W413, CJ1 CPU Operation Manual W393
- CJ2 Series - CJ2 CPU Unit Software User's Manual W473
- CP1 Series - CP1H/CP1L Programming Manual W451, CP1E Programming Manual W461
- CX-Programmer Operation Manual W437 - covers project (.cxp) file handling, online editing, and Watch Window
Which Omron PLC instruction is best for a single-input toggle on CS1 or CJ1?
Use the DIFU (Differentiation Up) instruction to generate a one-scan rising-edge pulse, then drive a SET and RSET pair on consecutive rungs. The output bit must be referenced on its own contact to latch. This is the universal pattern that works on CS1, CJ1, CJ2, CP1H, and CP1L CPUs and is documented in the CS1 Programming Manual (W394) and CJ1 Programming Manual (W413).
Why does my CS1 KEEP-based toggle output never turn OFF?
If the KEEP set input is wired as NOT(0.00) AND NOT(100.00), the output is set when the button is released and the output is OFF. The KEEP R-input should only be energized on the first scan via the system flag A200.15. Verify the rung with CX-Programmer online monitor and check that A200.15 is wired to the R-input of KEEP, not the S-input.
Can the toggle state survive a power cycle on CJ2M?
Yes. Use an H area bit (H0.00) in place of W0.00 as the toggle state and the KEEP will retain the value across power cycles. To force the toggle OFF on next power-up, add an A200.15 (First Cycle Flag) reset rung that clears H0.00 one scan after Run mode is entered. A200.15 is defined in the CJ2M CPU Unit Software User's Manual (W473).
Does the CP1E support DIFU and DIFD for toggle logic?
No. The CP1E does not execute the DIFU or DIFD instructions. Use the @ (rising-edge) prefix on the input contact, e.g. @0.00, to obtain a one-scan pulse, or use the built-in cyclic task bit P_0_02s in a contactor circuit. The CP1E Programming Manual (W461) lists the supported instruction set.
What file extension does CX-Programmer use to share a toggle program?
CX-Programmer saves complete projects with the extension .cxp. The file contains the program sections, symbol table, I/O table, and PLC settings. A single-input toggle program is typically a one-section project. CX-Programmer 9.73 or later is recommended to read legacy .cxp files generated by earlier versions.
How do I migrate a CS1 toggle program to a CJ2M without rewriting it?
Open the .cxp file in CX-Programmer, select the new CPU type (CJ2M-CPU31) in the Change PLC dialog, recompile with Ctrl+F7, and download. The CS1 and CJ2 instruction sets for KEEP, DIFU, DIFD, SET, RSET, and CNT are identical, so the rungs require no edits. Verify with the Watch Window after download.