How Captia Connect speaks Modbus
Connect behaves as the master: it is the side that asks. The plant equipment is the slave and only answers when interrogated, so the cadence of the history is not decided by the equipment, it is decided by the polling configuration of the Connect node. That is the practical difference against OPC UA or MQTT and it shapes everything else: there is no change notification and no semantic model here, there is a register map and a clock.
What Connect needs in order to start is not software on the controller, it is documentation: the register map of the equipment, which the manufacturer publishes in the communications manual. Without that document the integration turns into archaeology, and that is the first thing checked before committing to a commissioning date.
The data model: four tables and no semantics
A Modbus slave exposes four separate address spaces, and Connect reads them with different function codes because the protocol treats them as independent tables. Coils are read and write bits, typically digital output states. Discrete inputs are read only bits, typically digital inputs or alarm bits. Input registers are read only 16 bit words, where measurements usually live. Holding registers are read and write 16 bit words, where measurements, counters, configuration parameters and setpoints all sit together.
The operational consequence matters more than the taxonomy: the same quantity may appear in input registers on a meter and in holding registers on a drive, and no rule in the protocol guarantees otherwise. Connect infers nothing from the table a value sits in. Every signal is declared with its table, its address, its type and its scaling, taken from the manual, and that is what gets verified against the equipment display at commissioning.
Connect reads. Holding registers accept writes and so do coils, but the integration is framed as acquisition: control and setpoints remain with the plant automation system. Where the equipment allows it, the account or profile Connect uses is restricted to reading.
Addressing and the classic off by one
This is the error that forces a commissioning to be repeated more often than any other. The Modbus frame carries an address that starts at zero, but the traditional documentation of many manufacturers numbers registers from one and with a table prefix: the holding register documented as 40001 is address 0 on the wire, and 40108 is 107. Other manuals publish the wire address directly and add a footnote nobody reads.
Connect does not guess the convention. When a signal is declared, it is stated explicitly whether the address entered is the wire address or the manual address, and the check is always the same and always empirical: read a register with a known, stable value, a serial number, a firmware version or a phase voltage the equipment is showing on its own display, and compare. If it comes out shifted by one register, the convention was wrong. Doing that control reading at the start saves the off by one from surfacing weeks later disguised as nonsense data.
Types, word order and scaling
A Modbus register is 16 bits and nothing else. The protocol does not declare whether that is a signed integer, an unsigned integer, or half of a 32 bit value. This is where half of an integration falls over, which is why type declaration in Connect is explicit signal by signal.
When a quantity spans two registers, a 32 bit integer or a single precision float, word order appears. Within each register the byte order is fixed by the protocol, big endian, but the order in which the manufacturer places the high and low words of a 32 bit value is fixed by nobody. There are devices with the high word first and devices with the low word first, and both are legitimate. Connect declares that order per signal rather than per device, because some devices are not even consistent with themselves across blocks of the map.
The symptom of getting the type right and the word order wrong is recognisable: the reading does not come out slightly off, it comes out absurd, in the order of 10^38 or negative when it cannot be, and it jumps wildly with any small change in the real quantity. When that happens there is no point checking the sensor, the words need swapping and the reading repeating.
Then there is scaling. Most equipment does not send engineering units: it sends integers with an implicit factor documented in the manual, or an explicit factor held in another register. Power in tens of watts, temperature in tenths of a degree, energy with a multiplier that depends on the transformer ratio configured in the device itself. Connect applies factor and unit during normalisation, so the signal reaches the history already in kW, in degrees Celsius or in kWh. That is the step that avoids the classic chart multiplied by ten that nobody spots until somebody compares it against the utility bill.
| Slave table | What it holds in practice | How Connect treats it |
|---|---|---|
| Coils | Read and write bits: digital output states, run commands, permissives | Read as a boolean signal; writing stays outside the scope of acquisition |
| Discrete inputs | Read only bits: digital inputs, alarm and status bits | Read as booleans and used as context for the analogue measurements |
| Input registers | Read only 16 bit words: usually instantaneous measurements | Type, word order and scaling factor declared signal by signal |
| Holding registers | Read and write 16 bit words: measurements, counters, parameters and setpoints | Only the declared addresses are read, leaving configuration registers untouched |
Modbus TCP: Ethernet, port 502 and the unit id
Over Ethernet, Connect opens an outbound TCP connection to the IP address of the equipment on port 502, the port reserved by the standard, and keeps the session open between polls rather than reconnecting on every reading. The frame loses the serial mode checksum, which TCP already covers, and gains a header with a transaction identifier, which allows several requests in flight without confusing the replies.
The slave address field does not disappear: it survives as the unit id. On equipment with native Ethernet it is usually irrelevant and set to 1 or 255, but on a Modbus TCP to RTU gateway it is precisely what selects which device on the serial bus a request is aimed at. That detail is what turns a gateway into a twenty device integration behind a single IP address, and also what turns it into a bottleneck if polled without judgement, because behind that IP there is still a serial bus running at its real speed.
The connection is outbound from the Connect node towards the equipment and stays inside the plant network. Outwards, the node opens no inbound ports: the link to the platform is established by Tailscale as a secure outbound connection. This matters especially with Modbus, because the protocol carries no authentication and no encryption whatsoever. A port 502 published on the internet is a piece of plant equipment exposed to anyone. How that data is lifted without opening the network is what the guide on taking Modbus data to the cloud develops.
Modbus RTU over RS-485: bus, timing and physical layer
On serial, Connect is the single master of the bus. RS-485 is a multi-drop differential pair: every slave hangs off the same twisted pair in a daisy chain, each with its slave address from 1 to 247, and only one talks at a time. The RTU frame is binary and carries a 16 bit CRC; the end of frame is not a special character, it is a silence on the line equivalent to three and a half characters, which is why the bus is sensitive to anything that introduces latency between bytes.
Before mapping a single signal, four port parameters have to be fixed and matched exactly across every device on the bus and on the Connect node: baud rate, commonly 9600 or 19200 on installed equipment and 38400 or 115200 on recent devices; parity, with even parity and one stop bit as the most widespread combination and no parity with two stop bits as a frequent alternative; data bits, always 8 in RTU; and the slave address of each device, which must be unique on the bus. Two devices sharing an address produce overlapping replies and intermittent CRC errors that look like electrical noise and are not.
The physical layer decides the rest. The bus runs as a daisy chain, with no star branches, with 120 ohm termination at both ends and at no intermediate point, and with the cable screen earthed at a single point so as not to create a loop. Usable length depends on speed: at 9600 baud a well built bus comfortably reaches several hundred metres, and that distance shrinks as the speed goes up. The field rule is not to raise the baud rate for its own sake: if the polling cycle fits the available time at 9600, moving to 115200 only buys CRC errors in a workshop with drives switching near the cable tray.
Timing is the part that gets underestimated. Every reading consumes a full bus turn: request, slave response time and end of frame silence. With twenty devices on a bus at 9600 baud, the polling cycle is measured in seconds rather than milliseconds, and that is the real resolution of the signal no matter what the configuration asks for. Hence the two decisions Connect takes in configuration: group contiguous signals into block reads, because reading thirty consecutive registers in one request costs virtually the same as reading one, and assign different cadences per signal, with active power at the resolution the analysis demands and a cabinet temperature every few minutes.
When a slave does not answer, the master waits until the configured timeout expires, and that time comes out of the cycle of every other device. A single device switched off for maintenance degrades the cadence of the whole bus if the master insists with aggressive retries. The Connect behaviour is the one that avoids that effect: a bounded timeout, a limited number of retries and, once they fail, marking that slave as unavailable and lowering its retry rate rather than asking again on every pass. The absence is recorded as such in the history, which is not the same thing as a zero.
Different again is a slave that does answer but with an exception code. An illegal data address exception is not a communication fault, it is a badly declared map, usually the off by one or a block that this particular model in the range does not implement. It is fixed in the configuration, not by retrying.
| Parameter | What is decided | Starting criterion |
|---|---|---|
| Baud rate | A single rate across the whole bus, between 9600 and 115200 depending on the fleet | The lowest one that still closes the polling cycle within the required time |
| Parity and stop bits | Character format, identical on every device and on the Connect node | Whatever the least configurable device on the bus documents, and that one rules |
| Slave address | The 1 to 247 identifier of each device on the bus | Unique per device and recorded in the as built, not only in the memory of whoever fitted it |
| Termination and topology | 120 ohm resistors and the routing of the twisted pair | A daisy chain with no star branches, terminated at both ends and only at both ends |
| Polling cycle | Cadence per signal and grouping of contiguous registers into block reads | Blocks per device and a different cadence according to what each signal decides |
| Timeout and retries | What the master does when a slave fails to reply | Bounded waiting, limited retries and backing off a dead device so the bus keeps pace |
Which equipment speaks Modbus in a plant
Modbus has the largest installed base of any protocol on a Spanish plant floor, and it turns up in four families of equipment worth separating because the integration work differs in each.
Power analysers and energy meters are the most frequent case and the most rewarding. Almost all of them ship with RS-485 and Modbus RTU as standard, and mid range units add Ethernet with Modbus TCP. Their register map is well documented and stable across models in the same range, and they expose voltages, currents, active and reactive power, power factor and accumulated energy. The usual trap sits in accumulated energy, which arrives scaled by the current transformer ratio configured in the device itself, and in totaliser rollover.
Variable speed drives expose output frequency, current, estimated torque, heatsink temperature, running hours and status and fault words. Those last ones are bitmaps: a single register that has to be decomposed bit by bit before it means anything. They are the most direct source for watching the real condition of a pump or a fan without fitting additional instrumentation.
PLCs and controllers speak Modbus TCP almost always, either natively or through a configurable Modbus server over whichever memory area the programmer decides. Here the register map does not come from a manufacturer manual: it is defined by whoever programmed the controller, which makes it the one case where the commissioning conversation is with a person rather than with a PDF. When that same PLC also offers OPC UA, that route is usually preferred because the type travels declared.
Facility and process equipment closes the list: compressors, chillers, boilers, weighbridges, pumping sets, industrial grade instrumentation with an RS-485 output and capacitor banks. They usually expose a closed set of registers, which is what there is, and that is what you work with. The service that carries out that end to end data capture, including the bus and cabinet work, is PLC and plant equipment connectivity.
From Modbus register to time series
What a Modbus request returns is the bare minimum imaginable: a sequence of 16 bit words, with no type, no unit, no name and no time. Everything OPC UA carries declared has to be supplied here by the Connect configuration, which is why mapping is not a formality but the main body of work in the integration.
The identity of the signal is built entirely in Connect. Register 40108 on slave 7 tells nobody anything: it is declared as total active power of the line 2 distribution board, with its unit and a stable name, and tied to its asset, line or area. That is the step that makes the signal queryable by people who do not have the analyser manual in front of them, and the one described in general terms by the data acquisition system guide.
The timestamp is applied by Connect at the edge, at the instant of the reading, because the protocol does not carry one. It matters because of buffering: when connectivity to the platform drops, the node carries on polling the bus and persists the readings locally on its time series database. Once the network recovers, that delayed block synchronises at once, and if it were stamped by arrival time it would compress the series and misrepresent the dynamics. Stamped at the edge, every sample lands where it belongs.
Quality also has to be built. Modbus has no per value status code the way OPC UA does, but it does carry usable information: the reply arrived, arrived as an exception, did not arrive at all, or failed its CRC. Connect carries that distinction alongside the value instead of discarding it, so that in the history a communication gap reads as a gap and not as zero watts. The difference shows up the day an alert rule fires on a device that was simply disconnected.
Then there is the particular case of counters. An energy totaliser is monotonically increasing and rolls over on reaching the maximum of its type, and it also resets if somebody restarts the device or changes the transformer configuration. Treated as an ordinary measurement, that jump produces a huge negative consumption or an absurd spike in the monthly report. It is handled by declaring the signal as an accumulator, so that what gets queried afterwards is the increment between readings and a reset is identified rather than propagated into the report.
| What the register delivers | What Connect supplies | What it is good for later |
|---|---|---|
| A 16 bit word with no type | Type declared per signal and word order on 32 bit values | Removes the absurd value from swapped words and the misread sign |
| An integer with an implicit factor | Scaling factor and engineering unit applied during normalisation | The series arrives in kW, degrees or kWh, not in manufacturer counts |
| A table and register address | Signal identity, asset, line or area and a stable name | Makes the signal queryable by people without the register map to hand |
| No timestamp at all | A timestamp applied at the edge at the instant of the reading | The history keeps the real spacing between samples after a network outage |
| A reply, an exception, silence or a failed CRC | The condition of the reading is carried alongside the value | A communication gap reads as a gap rather than as a real zero |
| A monotonic totaliser that rolls over | The signal is declared as an accumulator with reset detection | Consumption per period does not break on rollover or on a device restart |
When Modbus is not the right route
Modbus solves more integrations than any other protocol on this platform, and precisely for that reason it is worth stating plainly where it stops being the right answer. There are five scenarios where insisting on it costs money.
When fast events have to be detected. Modbus is pure polling: whatever happens between two readings does not exist. An inrush current peak, a limit switch bounce or a process transient lasting tens of milliseconds will not be captured by raising the polling rate, because the bus has a ceiling and so does the slave. When the phenomenon is faster than the cycle, the route is equipment that records it locally and publishes it by event, and that is where OPC UA by subscription or MQTT by publication fit. Forcing Modbus to that resolution degrades the bus for every other signal and still misses the event.
When the equipment already exposes OPC UA. If the same PLC offers both routes, reading over Modbus means giving up the declared type, the readable name and the source timestamp only to reintroduce them by hand in the configuration. It is done when the OPC UA server is unlicensed or the manufacturer will not enable it, and then the decision is economic rather than technical, but it is not done out of habit.
When the device is autonomous or remote. A battery powered sensor, equipment in a building with no cable back to the node cabinet, or an installation spread across several sites do not fit a master/slave scheme that requires a master asking continuously. There the correct pattern is for the device to publish when it has something to say, and that is MQTT.
When the data is not on the plant floor. Production orders, product references, maintenance work orders or laboratory results live in an ERP, an MES or a cloud application, and there is no register to poll. The route is the standard integrations over REST API, webhooks or CSV.
When the installation is a building. Lighting, climate and tertiary automation have their own buses, and translating them into a register map adds a gateway and loses the semantics the building bus does have. For that part the route is OpenWebNet, and on fiscal utility meters it is IEC 870-5-102.
And there is one limit that belongs to security rather than architecture, and it deserves saying without hedging: Modbus has no authentication, no encryption and no access control. Anyone with access to the network or to the RS-485 pair can read the whole map and, on holding registers and coils, write to it. The protocol was designed for a closed fieldbus and cannot be hardened from the inside. What is done instead is containment: keep Modbus traffic inside the plant network, do not publish port 502 to the internet or expose a gateway through NAT, and lift the data to the platform over the secure outbound connection of the node. That is the real reason topology matters more here than on any other protocol in the list, and it is the subject of the Modbus to the cloud resource.
Coexistence with the rest of the installation
A normal plant does not speak one protocol, it speaks the ones it accumulated, and Modbus is almost always the substrate: it is in the analyser on the main board, in the drives on the line and in the compressor, however modern the rest may be. Connect acquires in parallel over every available route and lifts them into the same time series model, so that in the history a power reading from an analyser over Modbus RTU, a signal from a PLC over OPC UA and a consumption from a fiscal meter over IEC 870-5-102 all sit at the same level. Nobody needs to know which protocol a value came from in order to use it.
The two variants also coexist with each other, and the usual shape is mixed: equipment with Ethernet is read over TCP directly, while the serial fleet hangs off one or several gateways that the node interrogates over TCP, resolving each slave by its unit id. It is a convenient topology, and the error that comes with it is forgetting that behind the gateway there is still a slow bus: the cadence of that equipment is set by the RS-485, not by the Ethernet.
Migration, when it is raised, almost never consists of replacing Modbus. What happens is that new equipment arrives speaking OPC UA or publishing over MQTT while the Modbus fleet stays as it is for as long as it lasts, which tends to be decades. Hence the recommendation not to frame the integration as a protocol homogenisation project, which is expensive and which nobody asked for, but as an acquisition layer that accepts what is there. Once that layer exists, swapping an analyser or a drive stops being a data problem and becomes a change of map.
The platform modules already work on that base, the neutral definition of the protocol sits in the industrial glossary, and the engineering project that deploys the layer is OT and IT integration.