--- task: Modbus TCP station by quick load (line, station, scan type, points, items) version: R1.05 (first written for R1.03) source: IM 36K10L41-01EN §2, §3.1–3.2, §3.6–3.7; IM 36K10C10-01EN §4.1; practiced on CI-Eng-Sample 2026-09-30 status: verified on R1.03 (2026-09-30); on R1.05 the datasets, setup files and start scripts were checked identical (2026-10-08, read-only), not re-run (the sample is not loaded on the shared R1.05 server) --- # Modbus TCP station by quick load Uses the CI-Eng-Sample loopback station `CIENG_PLC` as the worked example (files in `examples/CI-Eng-Sample/`: `09_modbus_line_df.qli`, `10_modbus_station_df.qli`, `11_item_eqp_df.qli`, removal `80_`–`82_`). For a real device, replace the address, unit id, points and conversion settings. Works from a normal prompt while CI Server is running; use short relative file names. ## 1. (Test only) CI Server as its own Modbus slave CI Server ships a Modbus slave "mirror" that needs no hardware: - `eqpmdcmem -n EQPMDCMEM`: slave memory (64K registers, 64K bits per unit id; input and holding registers are the same memory, as are coils and input bits). The name must be `EQPMDCMEM`: the TCP slave looks for it. - `eqpmdcslvtcp -n EQPMDCSLVTCP -p 5020`: Modbus TCP listener (default port 502). Started by hand from a normal prompt they run until logoff or CI Server restart. To start them with CI Server, an administrator copies `examples/CI-Eng-Sample/equipment/ eqpciengslv_start.cmd` and `_stop.cmd` to `%TLS_ROOT_PATH%\tls\com`: `equipment_start.cmd` runs every `eqp*start.cmd` there. On R1.05 (checked 2026-10-08) it also runs `eqt*start.cmd` and, on the host node, every `?*_equipment_start.cmd` (with `?*_equipment_stop.cmd` called from `equipment_stop.cmd`), which is a cleaner hook for such extensions. ## 2. Line (`MODBUS_LINE_DF`) ``` @FIELDS NAME,DESCRIPTION,LINE_TYPE,EQUIPMENT_MAN,HEART_BEAT,TIMEOUT,DEAD_TIME,REPEAT_CONNECTION_DELAY @MODBUS_LINE_DF "CIENG_MB_LINE","CI-Eng-Sample Modbus loopback line","TCP/IP","EQPCIENG",100,3000,30,10 ``` - `EQUIPMENT_MAN` = equipment manager process name, must start with `EQP`, ≤ 12 characters. - Leave `EQUIPMENT_NODE` out: it defaults to the local node (keeps files portable). - Loading it **creates** `tls\com\eqpcieng_start.cmd`, `eqpcieng_stop.cmd` and `tls\sup\eqpcieng.sup` (written by the CI Service, no admin rights needed) and **starts** `eqpmdc -n EQPCIENG` a few seconds later. Wait ~15 s before loading stations. ## 3. Station, scan type, points (`MODBUS_STATION_DF`, `MODBUS_SCAN_TYPE_DF`, `MODBUS_POINT_DF`) ``` @FIELDS NAME,DESCRIPTION,LINE,PROTOCOL,LINE_1_DEVICE,SUB_STATION_ID,OUTPUT_METHOD,STATUS_ITEM,ON_SCAN @MODBUS_STATION_DF "CIENG_PLC","Loopback to CI Server Modbus slave (port 5020)","CIENG_MB_LINE","Open Modbus/TCP","localhost:5020",1,"On change and connect","CI-Eng-Sample.PLC1.COMM_OK",1 @FIELDS NAME,DESCRIPTION,SCAN_INTERVAL @MODBUS_SCAN_TYPE_DF "CIENG_SCAN1S","CI-Eng-Sample 1 s scan",1000 @FIELDS NAME,STATION,POINT,DESCRIPTION,IO_ADDRESS,EXTERNAL_RELATION,SCAN_TYPE,CONV_TYPE,BITS @MODBUS_POINT_DF "CIENG_PLC:SP","CIENG_PLC","SP","Setpoint, holding register 1","RO:1","Output","CIENG_SCAN1S","Binary",16 "CIENG_PLC:PV","CIENG_PLC","PV","Read-back, input register 1","RI:1","Input","CIENG_SCAN1S","Binary",16 ``` - `PROTOCOL`: `Open Modbus/TCP`, `RTU` or `Ascii`. The CI Server TCP slave only answered **Open Modbus/TCP** (with `RTU` every request timed out, `EQP-E-TCPRCVTMO`; ISS-024). - `LINE_1_DEVICE` `[:]`, default port 502. `SUB_STATION_ID` = Modbus unit id. - `STATUS_ITEM`: an existing Boolean item; 1 = communication good, 0 = bad, status 22 OFFSCAN when off-scan. Load it before the station. - Points need `NAME` = `:` as well as `STATION` and `POINT` (without it: `DSS-E-PIDX_FST`). - Addresses: `DO:n` coil, `DI:n` input bit, `RO:n[,bit]` holding register, `RI:n[,bit]` input register (numbers from 1, not 40001/30001). `EXTERNAL_RELATION`: `Input`, `Output`, `Input + Output`. `CONV_TYPE`: `Binary`, `Linear` (with `ELEC_LOW/HIGH`, `PHYS_LOW/HIGH`), `Float` (`FLOAT_TYPE` Intel, swap words), `Digital`, … (L41 summary §3.3). ## 4. Connect items (`ITEM_DF.STATION`, `POINT`) ``` @FIELDS NAME,DESCRIPTION,ITEM_REP,VALUE_FORMAT,STATION,POINT @ITEM_DF "CI-Eng-Sample.PLC1.SETPOINT","Setpoint written to holding register 1","Integer","99999","CIENG_PLC","SP" "CI-Eng-Sample.PLC1.READBACK","Read back from input register 1","Integer","99999","CIENG_PLC","PV" ``` ## 5. Test ``` itmval -p -n CI-Eng-Sample.PLC1.SETPOINT -v 1234 itmval -g -n CI-Eng-Sample.PLC1.READBACK itmval -g -n CI-Eng-Sample.PLC1.COMM_OK printf '3\n1\n-1\n' | eqpdbg 0 EQPCIENG # slave 1: scan status, line status, request statistics ``` Before the first good scan input items show `off` (offline) and status 13 NOT INIT. **Off-scan / on-scan** (`dssqld -m` with `NAME,ON_SCAN` = 0 or 1): off-scan sets the status item to 0 / status 22 OFFSCAN and freezes input items at their last value with the `off` flag; a value written to an output while off-scan reached the device after going back on-scan (output method *On change and connect*). ## 6. Remove (reverse order) 1. Items connected to points (`ITEM_DF` names). 2. Points, then station, then scan type (one file, in that order). 3. Line: this **stops** the equipment manager and deletes its start/stop scripts, setup file and `tls\sav` files. 4. The status item and section with the other items. ## Test system (R1.03, 2026-09-30) Full cycle on CI-Eng-Sample: loaded, `SETPOINT` 1234/4321/2468 and `CMD` 1/0 read back through Modbus on `READBACK`/`FEEDBACK`, off-scan/on-scan checked, removed (manager stopped, files deleted), reloaded from the sample files and re-tested: all 0 errors. With `eqpciengslv_start.cmd`/`_stop.cmd` copied to `tls\com` and CI Server restarted, the mirror and `EQPCIENG` started under the CI Service, `COMM_OK` = 1, and the saved setpoint (2468) was re-sent to the freshly zeroed slave memory on connect (output method *On change and connect*).