CJ1M SCU41 Modbus RTU Master: PMCR Programming Guide

James Nishida15 min read
CJ/CP SeriesOmronTutorial / 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

Overview

The Omron CJ1M series PLC combined with a CJ1W-SCU41 Serial Communication Unit is a common platform for Modbus RTU field integration, particularly when the CJ1M-CPU11/CPU12/CPU13 base unit is paired with RS-485 transducer networks. Because the CPU's built-in RS-232C port interprets every byte through the host link / NT-Link ASCII frame handler, engineers cannot use plain TXD(236) / RXD(235) instructions to push raw Modbus RTU frames directly out of the CPU's peripheral port without configuring the port for Serial Gateway mode or Serial PLC Link sub-mode and then carefully pre-building binary buffers.

The reliable production path is the Protocol Macro mechanism executed by the PMCR(260) instruction on the SCU41. The macro lives in non-volatile memory on the SCU, is downloaded once, and is then triggered from ladder as a black-box function call. The article below documents all three implementation paths (Protocol Macro, CX-Protocol source, and direct RXD/TXD), pinout, CRC16 byte order, master/slave sequence addressing, and the typical commissioning traps including the well-documented CRC byte-order error in third-party documentation.

Hardware Prerequisites

Item Catalog / Spec Purpose
CPU CJ1M-CPU11 / CPU12 / CPU13 / CPU21 / CPU22 / CPU23 Main processor; CPU11/12/13 have 10 ksteps, CPU21/22/23 have 20 ksteps with 2 × 100 kHz pulse outputs
Serial Communication Unit CJ1W-SCU41 (2 × RS-232C, full modem) or CJ1W-SCU31 (1 × RS-232C + 1 × RS-422/485) Holds and executes protocol macros; the SCU41-V1 supports protocol macro 2.0 features
CX-Programmer CX-One or CX-Programmer ≥ 9.x Ladder / ST editing and PMCR configuration
CX-Protocol CX-Protocol ≥ 1.9 (part of CX-One) Authoring tool for protocol macro source (.psw) files; required to create new macros
Protocol Macro Transfer Utility Distributed with CX-Protocol Uploads/downloads compiled macros (.pmr) without a CX-Protocol license on every PC
RS-485 field devices Modbus RTU slaves (transducers, drives, instruments) Targets; typical address range 1–247

The CJ1M-CPU2@ datasheet confirms the CJ1M family supports 2 × 100 kHz pulse outputs and special-instruction based positioning, while reserving dedicated word allocations for the peripheral port and the optional SCU expansion.

Communication Architecture

The SCU41 occupies a slot on the CJ1M backplane and is allocated a logical port pair (Port 1 / Port 2) plus an I/O refresh word area starting at n = 1500 + (25 × unit_number). For unit number 0 (slot immediately to the right of the CPU), the SCU occupies CIO 1500–1524 and DM 30000–30099 by default.

For Modbus RTU master operation the SCU port must be configured:

  • Serial mode: Serial Gateway (default after macro download) or Protocol Macro
  • Data length: 8 bits (Modbus RTU is fixed 8N1 or 8E1)
  • Parity: None, Even, or Odd — must match the slave (transducers default to None / 2 stop bits (N,8,2) or Even (E,8,1))
  • Baud: 9600 / 19200 typical for transducer buses
  • Transmission protocol: Protocol Macro (not Host Link, not NT Link, not 1:N)
The SCU41 port used for protocol macros must not be set to Toolbus — Toolbus is reserved for CX-Programmer online editing on the peripheral port and on SCU port 2 if the PLC was originally configured for it.

Three Modbus RTU Implementation Paths

Engineers building a Modbus RTU master on a CJ1M + SCU41 typically choose between three approaches. Each has different tool, license, and engineering-cost tradeoffs.

Path Tooling Required License Cost Engineering Cost Best For
1. Protocol Macro (compiled .pmr) on the SCU CX-Protocol once for authoring, then only the Transfer Utility to deploy Single CX-Protocol seat; runtime is free Lowest — PMCR is a 3-operand instruction Production systems, re-used across many sites
2. CX-Protocol source (.psw) opened in CX-Programmer Not supported — .psw is a binary project file only CX-Protocol can open N/A N/A There is no path; do not attempt this
3. Direct TXD/RXD on the CPU peripheral port or SCU port in Serial Gateway mode CX-Programmer only None High — you build the Modbus ADU, CRC, and timing yourself in ladder Single-function demos, lab work, or when CX-Protocol is unavailable

Path 1 — Protocol Macro with PMCR(260)

The Protocol Macro is a compiled, time-deterministic sequence stored in the SCU's flash. The PLC side simply tells the SCU "run sequence N, with these parameters, store results at this address" via the PMCR(260) instruction.

PMCR operand layout

Standard PMCR call to a protocol macro sequence:

PMCR(260)
  C1  : #0000     ; Control word 1 — unit address (bits 8–15) + port (bits 0–7)
  C2  : #0004     ; Sequence number in HEX — e.g. 04h for "Read Holding Registers" master
  S   : D00200   ; Source word area: first parameter block
  D   : D00300   ; Destination word area: response storage

Operands in detail:

  • C1 = unit number in the high byte and port number in the low byte. For SCU41 in slot 0, port 2: C1 = #0102 (unit 01, port 02). For port 1: C1 = #0101.
  • C2 = sequence number, entered in hexadecimal. Sequence 0 is reserved ("no operation").
  • S = first source word; the macro reads parameter inputs (e.g. slave address, register number, register count) from consecutive words starting here.
  • D = first destination word; the macro writes the slave response (and status flags) into consecutive words starting here.

For a 4-channel Modbus master macro (read holding registers function 03 or input registers function 04) the parameter block layout is typically:

S offset Name Width Description
S+0 SlaveAddress 1 word Modbus slave ID 1–247 (1 = #0001)
S+1 FunctionCode 1 word 0x03 (holding) or 0x04 (input)
S+2 RegisterAddr 1 word Starting register (0-based; most transducers use 0-based, some use 1-based — subtract 1 if 1-based)
S+3 RegisterQty 1 word Number of 16-bit registers to read (1–125 per Modbus spec)
S+4.. Timeout / retry 2 words Communication timeout (×100 ms), retry count

Response block at D:

D offset Name Description
D+0 Status 0 = OK, non-zero = error (see SCU41 manual §7 for codes)
D+1 BytesReceived Number of payload bytes returned by the slave
D+2..D+n Register data 16-bit register values, one per word (note Modbus byte order: high byte first within each register)

Path 2 — CX-Protocol Source vs Compiled Macro

A common misconception is that the .psw project file can be opened in CX-Programmer. It cannot — .psw is a CX-Protocol project that compiles into a .pmr runtime object. The runtime object, plus the Protocol Macro Transfer Utility (bundled with CX-Protocol) is what allows deployment to the SCU without a CX-Protocol license at the receiving site.

  1. Author the macro in CX-Protocol on a licensed engineering PC.
  2. Compile to .pmr.
  3. Distribute the .pmr plus the Transfer Utility to the field PC.
  4. Use the Transfer Utility to download the .pmr to the SCU over the SCU's configuration port (CX-Protocol writes the macro into SCU flash via FINS commands over the CPU's peripheral port).
If you have only a compiled .pmr (no source), you can still deploy it, but you cannot edit it. Treat the .pmr as binary-only. If you need to modify timing, retry, or add a new function code, you must re-author in CX-Protocol.

Path 3 — Direct TXD(236) / RXD(235) on the CPU Serial Port

When CX-Protocol is unavailable, a workable but labour-intensive path is to build the Modbus ADU in the CPU and send it via the built-in RS-232C port (port 1 on CJ1M-CPU1x/CPU2x). The CPU port must be set to Serial Gateway (PLC Setup: Port 1 Serial Mode = Serial Gateway) and the port settings in the TXD(236) instruction must be 8N1 (or 8E1) at the slave's baud rate.

Frame format to read holding registers (function 03) from slave 1, register 0, qty 2:

[01]  [03]  [00 00]  [00 02]  [CRC_LO]  [CRC_HI]
Addr  Func  StartHi/Lo   Qty     16-bit CRC little-endian

Sample ladder extract using TXD(236):

; Build 6-byte Modbus request in DM area
; DM00000 = Slave address   =  #0001
; DM00001 = Function code   =  #0003  (holding registers)
; DM00002 = Start register  =  #0000
; DM00003 = Quantity        =  #0002
; DM00004 = CRC16 (LO/HI)   =  computed and stored as word
;
; TXD(236) sends N words from DM00000 as raw binary (no ASCII conversion)
; because the CPU port is in Serial Gateway mode (not Host Link).
TXD(236)
  C   : #0000   ; control: 0 = RS-232C, no start/end code, 8-bit data
  S   : D00000  ; source start word
  N   : #0006   ; number of words (12 bytes) to send
  C2  : #0000   ; not used for port 1 in serial gateway mode
;  ↑ ladder then issues RXD(235) to receive 9 bytes:
;  [01 03 04 xx xx xx xx CRC_LO CRC_HI]
RXD(235)
  C   : #0000
  D   : D00100  ; destination word area for received bytes
  N   : #0009   ; number of words (18 bytes) to read
  C2  : #0000

The reason naive TXD(236) attempts convert bytes to ASCII is that the CPU port defaults to Host Link mode, where the FINS protocol wraps every byte in STX/ETX and escapes control codes. Switch the port to Serial Gateway in the PLC Setup (peripheral port settings) and the data goes out raw.

CRC16 Byte Order — A Documented Trap

The Modicon Modbus specification defines the CRC16 to be appended low byte first, high byte second (CRC-Lo, CRC-Hi). The byte order is independent of the data byte order inside the PDU.

Modbus RTU frame (request example):
  [Addr][Func][StartHi][StartLo][QtyHi][QtyLo] [CRC_LO] [CRC_HI]
                                                   ^^^^^^^^  appended
                                                   little-endian

Several third-party macro documentation sheets reverse this order, stating "Hi, Lo". A SCU41 macro that appends CRC in the wrong order will pass the Modbus parameter check on the slave (function 03 or 04) and the slave will silently not respond, because the CRC fails and the frame is discarded. To confirm a SCU macro is correct:

  1. Capture the bytes the SCU transmits with a Modbus tap or RS-485 line monitor.
  2. Compute the CRC16 (poly 0xA001) over all bytes before the trailing two.
  3. Compare to the trailing two bytes — the last byte must equal the high byte of the computed CRC.

Standard CRC16 implementation (commonly used in macro parameter step "Send Attribute / Variable"):

CRC = 0xFFFF
for each byte b in {addr, func, data...}:
    CRC = CRC XOR b
    for 8 bits:
        if (CRC AND 0x0001):
            CRC = (CRC SHR 1) XOR 0xA001
        else:
            CRC = CRC SHR 1
append CRC as: [CRC AND 0xFF] , [CRC SHR 8]   ; little-endian

Master vs Slave Sequence Numbers

When both a master macro and a slave macro are loaded on the same SCU, the second operand of PMCR(260) selects which one runs. The sequence number is a single global namespace per SCU — the macro type (master/slave) is encoded into the macro itself, not the sequence number. Convention is to allocate:

  • Sequences 0x0100–0x01FF: master transmits then receives (modbus master)
  • Sequences 0x0200–0x02FF: slave receives then transmits (modbus slave)

A common compile-time convention is to use the Modbus function code as the low byte of the sequence number, so a master read-holding-registers macro lives at sequence 0x0103 and a slave read-holding-registers at 0x0203. Engineers can therefore tell at a glance which routine is being triggered by reading the hex constant in the second operand of PMCR(260) — and crucially, the SCU will not execute the wrong direction because master sequences expect a request from the CPU and produce a request to the bus, while slave sequences do the opposite.

RS-485 Wiring and SCU41 Pinout

The SCU41 ships with two RS-232C DB-9 ports. For RS-485 transducer buses you need either the CJ1W-SCU31 variant (port 2 is RS-422/485) or an external RS-232C-to-RS-485 converter on the SCU41. Wiring notes:

SCU Port Pin (DB-9) Signal RS-485 (SCU31 port 2)
2 2 RD n/a (RS-232C only on SCU41)
2 3 SD n/a
2 5 SG Signal ground — must connect to bus shield drain at one end only
2 (SCU31) 4 RDA / RDB RS-485 A+ / B- differential receive
2 (SCU31) 6 SDA / SDB RS-485 A+ / B- differential drive
1, 7, 8, 9 FG, +5V, RTS, CTS Tie FG to chassis at the PLC; +5V is fused 200 mA for converter power
Terminate the RS-485 bus with 120 Ω between A+ and B- at both ends. Biasing resistors (typically 680 Ω pull-up to 5V on A+, 680 Ω pull-down to GND on B-) are usually inside the SCU31 and are enabled by the PLC Setup switch "RS-485 Termination / Bias — Enabled". If you build a multi-drop transducer bus, do not enable bias on intermediate devices.

Implementing Function 04 (Read Input Registers)

Most transducer manufacturers implement function 04 (Read Input Registers), not 03. The Modbus PDU is identical, but the function code byte is 0x04. A working PMCR call for reading 4 input registers from slave 1, starting at register 30001 (1-based — subtract 1 to get 0-based start = 0):

; Parameter block in D00200–
D00200 = #0001   ; Slave address 1
D00201 = #0004   ; Function code 04 (Read Input Registers)
D00202 = #0000   ; Start register 0 (0-based)
D00203 = #0004   ; Quantity = 4 registers
D00204 = #0064   ; Timeout = 100 × 100 ms = 10 s
D00205 = #0003   ; Retries = 3

PMCR(260)
  C1  : #0102          ; SCU unit 01, port 02
  C2  : #0104          ; Sequence 0x0104 (master, function 04)
  S   : D00200
  D   : D00300
;
; After execution D00300 holds status; D00301 = bytes received;
; D00302..D00305 hold the 4 input register values in big-endian (Hi/Lo)

The slave response for function 04 is:

[01] [04] [08] [D0 D1 D2 D3 D4 D5 D6 D7] [CRC_LO] [CRC_HI]
 Addr  Func  ByteCnt      4 × 16-bit data        CRC

Each 16-bit value arrives in big-endian (Modbus byte order); when the SCU writes it to a CJ1M word the macro is responsible for swapping the bytes to the little-endian DM area convention. Check the macro's Receive Attribute / Variable "Swap" flag — it must be set to "Swap each word" for the data to land in DM as the integer the transducer means.

Verification Procedure

  1. Connect a Modbus RTU line monitor (or a second SCU31 running a slave emulator macro) on the bus.
  2. From CX-Programmer, force PMCR(260) to run with the parameter block above.
  3. Confirm on the line monitor: 8-byte request frame with the trailing CRC matching the CRC computed from the first 6 bytes.
  4. Confirm on the line monitor: slave response with byte count 08 and 4 register values.
  5. In CX-Programmer, observe D00300 = 0 (status OK) and D00302..D00305 populated with the expected values.
  6. Run a poll at 1 Hz for 10 minutes; verify zero Port communication error flags in the SCU (AR area bits in the SCU status).

Troubleshooting Matrix

Symptom Likely Root Cause Fix
SCU LEDs do not light at all SCU not seated, no power, wrong unit number Power-cycle, verify I/O assignment in CX-Programmer (CIO/DM area allocated for the unit number)
TXD LED flashes, RXD does not Bus termination, bias, or A/B swapped Verify 120 Ω terminators, swap RDA↔RDB if line monitor shows inverted polarity
RXD LED flashes, no DM data lands CRC16 byte order wrong in macro (high/low swapped) — slave discards the frame Capture line, recompute CRC, verify SCU appends LO then HI; if not, edit macro Send Attribute / Variable "CRC order" = Lo-Hi
Some slaves respond, others do not Parity / stop bits mismatch Match PLC Setup to each slave's datasheet; some transducers need E,8,1 and others N,8,2
First poll works, subsequent polls fail Inter-frame timing — Modbus requires 3.5 char silence; macro has no guard time Add 4-character delay between PMCR calls, or set the macro's End-of-frame time to 4 chars
PMCR returns status word 0x0001 immediately Sequence number not loaded on the SCU Use the Protocol Macro Transfer Utility to verify .pmr is resident on the SCU and that sequence 0x0104 exists
Status word 0x0002 (timeout) Baud rate or slave address mismatch, or wrong RS-485 direction control Reduce baud to 9600 to verify wiring, then re-test; if using RS-485 verify the SCU is in 2-wire half-duplex mode and that the converter has automatic direction control
Data is in DM but values look shifted by 8 bits Macro is not swapping Hi/Lo per Modbus big-endian → CJ1M little-endian Enable "Swap each word" on the receive Variable in the macro
Status word 0x0010 (FINS level error) CPU-side port number in C1 wrong, or unit number off by one Verify C1 high byte = SCU unit number, low byte = port number; remember the CJ1M peripheral port is port 1 on the CPU, not on the SCU

FAQ

Can I open a CX-Protocol .psw file in CX-Programmer?

No. The .psw is a CX-Protocol project file. The runtime artifact is the .pmr, which is uploaded to the SCU via the Protocol Macro Transfer Utility bundled with CX-Protocol. To re-author a macro you must have a licensed copy of CX-Protocol.

Why does TXD(236) convert my Modbus bytes to ASCII on the CJ1M built-in port?

The CPU's peripheral port defaults to Host Link (FINS) mode, which wraps every byte in STX/ETX. Switch the port to Serial Gateway in the PLC Setup (under Serial Communications — Peripheral Port Settings — Mode = Serial Gateway) and TXD/RXD will send and receive raw binary.

How do I tell the SCU which sequence is master vs slave when both are loaded?

Sequence numbers form a single global namespace per SCU. The convention is to reserve one block for master sequences and another for slave (for example, 0x01xx master and 0x02xx slave). The master sequence expects a request from the CPU and transmits it; the slave sequence waits for a request on the wire and writes a response. The function code (e.g. 0x04) becomes the low byte of the sequence number for clarity.

What is the correct CRC16 byte order in a Modbus RTU frame?

The Modicon specification requires the CRC to be appended low byte first, high byte second. If a SCU macro documentation sheet shows "Hi, Lo", that is a documentation error. Confirm by capturing the bus and recomputing CRC16 (poly 0xA001) over the bytes before the CRC — the last byte must equal the high byte of the computed CRC.

Can a CJ1M-CPU11 talk Modbus TCP without a serial SCU?

Yes, using a CJ1W-ETN21 Ethernet unit. The ETN21 supports FINS/UDP/TCP and, with the right ladder and DM configuration, can carry Modbus TCP by using SEND(090) / RECV(098) against an MBAP-header translator, or by routing through a Modbus/TCP-to-Modbus/RTU gateway. Pure Modbus TCP master on a CPU11 also requires the ETN21 to be at unit number 0 in the most common configuration, and the CPU's IP routing table to be set so the ETN21 owns the gateway address.

Back to blog