Overview
Rapid SCADA 6 is an open-source industrial automation platform written in C# on .NET, distributed through the official repository at RapidScada/scada-v6 on GitHub. It is designed for building distributed automation systems that run on servers, embedded computers, and cloud instances. Writing outputs from the operator interface down to a Modbus device requires three coordinated configuration objects:
- An Output Channel registered in the configuration database.
- A Scheme Component bound to that channel number with its
Actionproperty pointing to a command. - A Command declared inside the Modbus device template that translates the channel write into the appropriate Modbus function code and register.
This article walks through each step with the XML structures, configuration table parameters, and verification checks required to push a value from a Rapid SCADA web scheme to a Modbus slave.
Prerequisites
- Rapid SCADA 6 Administrator utility (
ScadaAdmin) with read/write access to the configuration database. - Rapid SCADA 6 Server (
ScadaServer) and Agent (ScadaAgent) installed and running as Windows services or Linux daemons. - Modbus TCP or Modbus RTU driver configured in
ScadaComm; license-less trial mode is sufficient for development work. - Knowledge of the target Modbus device's data block, register address (zero-based or one-based depending on driver conventions), and required function codes.
- Web scheme editing access through
ScadaWebor the Scheme Editor shipped with the Administrator package.
Rapid SCADA 6 Architecture for Write Operations
Understanding how a command propagates from the operator's browser to the field device prevents mis-configuration. The flow is:
Configuration Database Objects
The configuration database is the single source of truth. Three tables are directly involved in write operations:
| Table | Role | Key Fields |
|---|---|---|
| Channel | Logical data point; identifies an input or output value | CnlNum, Name, DataType, CmdType, Formula, OutVal |
| Device | Physical or virtual slave | DevNum, Name, DevType, Address, CommLineNum |
| Template | XML file describing request/command structure | Name, FileName, CmdType, Commands[] |
For commands, additional lookup logic ties CnlNum to a CmdNum through the template's command table; the channel's CmdType must match the template's command type or the write will be rejected by the server.
Step 1 — Create the Output Channel
Open ScadaAdmin, connect to the configuration database, and navigate to Channels → New Channel. Configure the following parameters:
| Parameter | Recommended Setting | Notes |
|---|---|---|
| CnlNum | Next free number | Server-allocated; never reused |
| Active | True | Inactive channels are ignored by the server |
| Name | Descriptive, e.g. Pump1_RunCommand
|
Visible to operators |
| DataType | Double, Integer, or Boolean (matched to slave register width) | Defines interpretation of OutVal |
| CmdType | Standard (single-element) or Array (multi-element) | Must match the template's command element list |
| Formula | Default (no transform) or scaling expression | Applied before write |
| OutVal | Last acknowledged written value | Updated by command acknowledgement |
Save and publish the configuration. The channel is now known to ScadaServer but is not yet wired to a physical write.
Step 2 — Configure the Modbus Template Command
Templates are XML files inside the project's template directory. A Modbus command element is required for every output channel. The structure follows the schema defined in the Rapid SCADA 6 ScadaComm driver for Modbus.
<DeviceTemplate>
<Template>
<Name>ModbusTcp</Name>
<DevType>Modbus</DevType>
<Commands>
<Cmd cmdNum="1" name="SetCoil" cmdCode="05" dataBlock="0" address="0"/>
<Cmd cmdNum="2" name="SetRegister" cmdCode="06" dataBlock="1" address="0" readCmdCode="03"/>
<Cmd cmdNum="3" name="SetRegistersArray" cmdCode="16" dataBlock="1" address="0" cmdType="Array">
<CmdEl cnlNum="100" name="Setpoint1" dataType="Double" dataLen="2"/>
<CmdEl cnlNum="101" name="Setpoint2" dataType="Double" dataLen="2"/>
</Cmd>
</Commands>
</Template>
</DeviceTemplate>
Key attributes:
| Attribute | Meaning | Typical Values |
|---|---|---|
| cmdNum | Unique command number referenced from the scheme | 1 ... N |
| cmdCode | Modbus function code used to write | 05, 06, 15, 16, 22, 23 |
| dataBlock | Modbus data area | 0 = Coil, 1 = Holding Register, 2 = Discrete Input, 3 = Input Register |
| address | Starting register/coil (driver may translate zero/one-based) | 0 ... 65535 |
| readCmdCode | Optional read-back function code | 01, 02, 03, 04 |
| cmdType | Standard or Array | Array for multi-register writes |
Reload the configuration in ScadaAdmin so that ScadaServer recognizes the new template commands. The driver compiles the template and exposes cmdNum identifiers to the server's command dispatcher.
ScadaComm Modbus driver accepts addresses in the native protocol value; verify against the slave's manual before saving. A value of 40001 in vendor docs typically maps to holding register address 0 on the wire.Step 3 — Bind the Scheme Component to the Channel and Action
Open the Scheme Editor, select the button, dynamic text, or input control that will trigger the write, and configure the following properties:
| Property | Value | Purpose |
|---|---|---|
| CnlNum | Output channel number from Step 1 | Tells the server which channel value to write |
| Action | SendCommand |
Invokes a command instead of just displaying a value |
| ActionArgs / CmdNum | Template command number from Step 2 | Identifies which Modbus function to dispatch |
| CmdVal | Value to send (literal, bound channel, or operator input) | Sent to the channel's OutVal and then to the slave |
A common scheme-side binding looks like this in the scheme's XML:
<Component type="Button" cnlNum="100" action="SendCommand" cmdNum="2" cmdVal="1">
<Caption>Start Pump 1</Caption>
</Component>
On click, the browser posts a request to ScadaWeb, which hands it to ScadaServer. The server resolves the channel number to the linked device, looks up the command by cmdNum, packages the value according to the Modbus function code, and hands the request to the ScadaComm Modbus driver for transmission.
Modbus Function Codes Used for Writes
| Code | Name | Data Block | Use Case in Rapid SCADA |
|---|---|---|---|
| 05 | Write Single Coil | Coil (0x) | Boolean actuator (start/stop, enable) |
| 06 | Write Single Register | Holding Register (4x) | Single 16-bit setpoint |
| 15 (0x0F) | Write Multiple Coils | Coil (0x) | Bit-packed command arrays |
| 16 (0x10) | Write Multiple Registers | Holding Register (4x) | Array commands, multi-register setpoints |
| 22 (0x16) | Mask Write Register | Holding Register (4x) | Selective bit manipulation |
| 23 (0x17) | Read/Write Multiple Registers | Holding Register (4x) | Atomic read-modify-write for control loops |
Always confirm the target device supports the chosen function code; some inexpensive RTU slaves accept only 06 and 16.
Verification Procedure
- In ScadaAdmin, publish the configuration and confirm no validation errors are reported.
- Restart
ScadaServerandScadaCommservices if the template changed; channel-only edits typically do not require a restart. - Open the web scheme, sign in as an operator with command privileges, and trigger the bound component.
- Watch the server log (
ScadaServer.log) for aCommand processedentry containing theCnlNumandCmdNum. - Use a Modbus packet sniffer (Wireshark with the
mbtcpdissector, or a vendor diagnostic tool) to confirm the function code, address, and value on the wire. - Check the channel's
OutValin ScadaAdmin; it should reflect the acknowledged written value.
Troubleshooting Matrix
| Symptom | Likely Cause | Remediation |
|---|---|---|
| Scheme button does nothing on click | Action property not set, or user lacks command rights | Set Action to SendCommand; verify role permissions |
| Server logs "Unknown command" |
cmdNum not loaded — template not published |
Re-publish template, restart ScadaComm |
| Exception 02 ILLEGAL DATA ADDRESS | Register address out of range or wrong data block | Verify address and dataBlock against device manual |
| Exception 03 ILLEGAL DATA VALUE | Value outside the allowed range for that register | Apply scaling formula on channel; clamp at source |
| Exception 06 SLAVE DEVICE BUSY | Device servicing another request or locked | Reduce polling frequency; retry with backoff |
| No exception but no physical effect | Channel's Active is false or CmdType mismatch |
Activate channel; align CmdType with template |
| Value written is wrong by an order of magnitude | Byte/word order mismatch (Big-Endian vs Little-Endian) | Configure byte order in the Modbus driver options |
Security and Role Configuration
Writes must be restricted to authorized roles. In ScadaAdmin under Users → Roles, ensure the operator role has the SendCommand permission and that the role can act on the device or channel in question. Always enable audit logging on write operations; Rapid SCADA 6 records every command with the originating user, timestamp, channel, and value.
Performance and Timing Considerations
- Modbus TCP round-trip on a LAN is typically 5–20 ms; over WAN expect 50–200 ms.
- Avoid issuing more than one write per second to the same register to prevent Modbus exception 06 (busy) on slower slaves.
- For multi-register array commands, prefer function code 16 over multiple 06 transactions to reduce bus traffic.
- Large arrays (greater than 100 registers) may need to be split depending on the slave's PDU limit; classic Modbus caps a single 16 transaction at 123 registers.
Field-Proven Cautions
- Never bind a write action to an input channel; the server silently discards writes to read-only channels.
- If the Modbus driver restarts while a command is in flight, the request is lost — design HMI feedback (status indicator channel) for critical actuators.
- When upgrading between Rapid SCADA minor versions, re-validate templates: schema attributes occasionally gain or rename fields.
- Test with the
Modbus Simulatorshipped with Rapid SCADA examples before pointing at a live PLC.
FAQ
What three objects must be created to write from Rapid SCADA 6 to a Modbus device?
You need an output channel in the configuration database, a Modbus command inside the device template, and a scheme component whose Action property is set to SendCommand with the channel number and command number bound.
Which Modbus function code should I use for a single boolean start/stop command?
Use function code 05 (Write Single Coil) with dataBlock="0". If the actuator accepts a holding register representation, function code 06 also works.
Why does my scheme button trigger nothing even though configuration was published?
The most common causes are the scheme component missing the Action property set to SendCommand, the operator role lacking command permissions, or the Modbus template not being reloaded in ScadaComm. Check ScadaServer.log for "Unknown command" or "Permission denied" entries.
Do I need to restart services after editing an output channel?
Channel-only edits are picked up dynamically by ScadaServer, but template changes (new commands, attribute changes) require ScadaComm to reload and sometimes a restart to recompile the request graph.
Where is the official Rapid SCADA 6 source and documentation?
The official repository is RapidScada/scada-v6 on GitHub, which contains the server, agent, web, administrator, and communication driver source plus accompanying documentation.