Skip to content

Modbus access cases ​

提示

Modbus devices can be connected through cloud polling or an edge gateway.

1. Cloud polling ​

Why cloud polling is needed ​

Common DTUs and communication modules usually provide only MQTT or TCP transparent transmission. If a device uses the Modbus protocol and no edge gateway is added, the device data is not actively reported with enough platform-side context.

In this mode, FastBee builds Modbus read commands according to the collection-point template of the product, sends the commands to the target device, and performs polling from the cloud.

Because a reported Modbus RTU frame does not include an explicit platform register marker, the platform needs to mark and match the request and response. The current implementation uses a Redis lock on the polling thread and waits for the device response.

Why cloud polling is needed

The overall implementation is shown below:

Why cloud polling is needed

Modbus protocol decoding and encoding ​

1. Platform code ​

In the FastBee backend, Modbus message decoding and encoding are implemented in the location shown below:

1. Platform code

2. Annotation-based decoding and encoding ​

FastBee provides a base package for annotation-based message decoding and encoding. It can be used to parse and generate many types of hardware messages, reducing repetitive backend development work.

2. Annotation-based decoding and encoding

The following example shows how the wrapped Modbus protocol is decoded and encoded with annotations.

First, check the field definition of the @Column annotation:

  1. length: specifies the field length.
  2. version: distinguishes downstream messages from upstream messages.
  3. totalUnit: specifies the preceding quantity unit of the field, which is used when parsing batch-read responses.
2. Annotation-based decoding and encoding

If you do not need to understand the frame parsing details, you can skip this section.

Key parsing rules:

  1. int: used here to represent a one-byte message length. In Java, int is four bytes, but this parser treats the field according to the configured message length.
  2. totalUnit: indicates the quantity field before the current field. For example, when totalUnit = 1, if the data length is n, the data list length is BYTE[2 * n].
  3. version: controls which command type a field participates in.
js
// When version is configured, the field is decoded or encoded only when the condition matches.
// When version is not configured, the field participates in all decoding and encoding.
//
// version = 0: parsed when the device reports data.
// version = 1: parsed when reading registers.
// version = 2: parsed when writing a single holding register.
2. Annotation-based decoding and encoding2. Annotation-based decoding and encoding

3. Backend cloud-polling implementation ​

The backend implements Modbus polling through scheduled tasks.

3. Backend cloud-polling implementation

The backend entry point for Modbus cloud polling is shown below:

3. Backend cloud-polling implementation

Processing flow:

  1. Filter online gateway devices.
  2. Read collection points from the product definition.
  3. Batch-generate and deliver Modbus read commands.
  4. Use a thread pool so that all commands for one sub-device are delivered in the same child thread.
  5. Use Redis as both the thread lock and the register marker.
  6. For each sub-device, the thread continues polling until the Redis cache expires or the device response is received, then sends the next command.

For implementation details, refer to the backend source code.

2. Edge gateway ​

提示

The edge gateway is used together with real-time cloud collection.

2.1 Solution overview ​

Because of the Modbus protocol characteristics, a raw Modbus frame reported to the cloud does not contain an address marker that the platform can directly use to identify the corresponding thing-model collection point.

To improve collection efficiency, real-time reporting, and general compatibility, this solution adds an MCU module as an edge gateway.

Hardware composition:

  1. The user's own device or MCU.
  2. A DTU or communication module in transparent transmission mode.
  3. An additional low-cost MCU that performs Modbus polling and reports changed values.

2.2 Message data ​

To solve the missing register-address marker in raw Modbus frames, the additional MCU wraps the Modbus protocol with an extra frame.

Device active reporting

text
FFAA              Wrapped frame header, used to ensure message integrity.
0D                Wrapped frame tail, used to ensure message integrity.
0001              Register address, used to identify the message.
010302030578B7    Raw Modbus frame.
2.2 Message data

Service delivery

2.2 Message data

Device acknowledgement for service delivery

After a Modbus device receives and executes a write command, it reports the write command back to the platform to indicate that the command was executed successfully.

2.2 Message data

2.3 Overall process ​

2.3 Overall process

2.4 Platform code ​

In the FastBee backend, decoding and encoding of the wrapped Modbus frame are implemented in the location shown below:

2.4 Platform code

Annotation-based decoding and encoding ​

FastBee uses the same annotation-based decoding and encoding package for this wrapped protocol.

image

The wrapped Modbus protocol can also be defined through @Column. The key fields are:

  1. length: specifies the field length.
  2. version: distinguishes downstream messages from upstream messages.
  3. totalUnit: specifies the preceding quantity unit of the field, which is used when parsing batch-read responses.

image

The message definition follows these rules:

  • Java primitive numeric types do not distinguish signed and unsigned values at the type level in this parser.
  • int can be used for a configured byte length. In the example, FFDD is two bytes and length = 2, so the field is parsed as two bytes.
  • short represents two bytes. Modbus data fields are composed of two-byte values, so short[] is used to support both single-value and batch-value parsing.
  • totalUnit indicates the quantity field before the current field. For example, when totalUnit = 1, if the data length is n, the data list length is BYTE[2 * n].

image

Annotation decoding and encoding test ​

The backend test class is PakModbusTest.

image

Example parsing results:

text
Single report parsing =
Read holding register (byte read/write mode)
slaveId=1, code=3, length=1, data=[773], address=1, writeData=0

Batch report parsing =
Read holding register (byte read/write mode)
slaveId=1, code=3, length=80,
data=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16384, 0, 0, 0, 3327, 924, 32, 0, -1, -1, 0, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, -55, 16, 25, 30, 16, 25, 25, 87, 7],
address=1, writeData=0

FastBee | fastbee.cn