Yet another MODBUS library, supporting both TCP and RTU, providing gateway functionality.
- Usage
- Installation
- License
- MODBUS References
Modbuzz provides one consistent public API for:
- Connecting to real MODBUS devices over TCP or RTU.
- Running TCP/RTU clients and servers.
- Building TCP/RTU gateways by connecting a server to another data source.
If you are evaluating this library, start from Quick Start and verify one request end-to-end first.
This flow assumes a real MODBUS device is available:
- Start a TCP client or RTU client.
- Send one request to the device.
- Stop the client.
:ok = Modbuzz.start_tcp_client(:demo_tcp_client, {192, 168, 0, 10}, 502)
alias Modbuzz.PDU.WriteSingleCoil
req = %WriteSingleCoil.Req{output_address: 0, output_value: true}
{:ok, _res} = Modbuzz.request(:demo_tcp_client, req)
:ok = Modbuzz.stop_tcp_client(:demo_tcp_client)You can also use a data server as an in-memory value source behind TCP/RTU servers.
Modbuzz.start_tcp_client/3 starts a TCP client instance.
Modbuzz.request/2 or Modbuzz.request/3 requests synchronously. The 2nd argument, unit_id, can be omitted. If omitted, its value defaults to 0.
:ok = Modbuzz.start_tcp_client(:your_tcp_client, {192, 168, 0, 10}, 502)
alias Modbuzz.PDU.WriteSingleCoil
req = %WriteSingleCoil.Req{output_address: 0, output_value: true}
{:ok, _res} = Modbuzz.request(:your_tcp_client, req)Modbuzz.start_rtu_client/3 starts an RTU client instance.
Modbuzz.request/2 or Modbuzz.request/3 requests synchronously. The 2nd argument, unit_id, can be omitted. If omitted, its value defaults to 0.
:ok = Modbuzz.start_rtu_client(:your_rtu_client, "ttyUSB0", [speed: 9600])
alias Modbuzz.PDU.WriteSingleCoil
req = %WriteSingleCoil.Req{output_address: 0, output_value: true}
{:ok, _res} = Modbuzz.request(:your_rtu_client, 1, req)Modbuzz.start_data_server/1 starts a data server instance.
Data server lets you expose your own application data (for example, sensor values) as Modbus values through TCP/RTU servers.
:ok = Modbuzz.start_data_server(:your_data_server)
alias Modbuzz.PDU.WriteSingleCoil
req = %WriteSingleCoil.Req{output_address: 0, output_value: true}
res = %WriteSingleCoil.Res{output_address: 0, output_value: true}
:ok = Modbuzz.create_unit(:your_data_server, 1)
:ok = Modbuzz.upsert(:your_data_server, 1, req, res)
:ok = Modbuzz.start_tcp_server(:your_tcp_server, {192, 168, 1, 10}, 502, :your_data_server)In this setup, external Modbus clients can read/write values through your TCP/RTU server, backed by the data server mappings.
| Goal | API |
|---|---|
| Send a request and wait for result | Modbuzz.request/2, Modbuzz.request/3, Modbuzz.request/4 |
| Send a request and receive by message | Modbuzz.request_async/2, Modbuzz.request_async/3, Modbuzz.request_async/4, Modbuzz.request_async/5 |
| Start/stop data server | Modbuzz.start_data_server/1, Modbuzz.stop_data_server/1 |
| Manage data server content | Modbuzz.create_unit/1, Modbuzz.create_unit/2, Modbuzz.upsert/3, Modbuzz.upsert/4, Modbuzz.delete/2, Modbuzz.delete/3, Modbuzz.dump/1, Modbuzz.dump/2 |
| Start/stop TCP client | Modbuzz.start_tcp_client/3, Modbuzz.stop_tcp_client/1 |
| Start/stop RTU client | Modbuzz.start_rtu_client/3, Modbuzz.stop_rtu_client/1 |
| Start/stop TCP server | Modbuzz.start_tcp_server/4, Modbuzz.stop_tcp_server/1 |
| Start/stop RTU server | Modbuzz.start_rtu_server/4, Modbuzz.stop_rtu_server/1 |
For detailed external API behavior, see External API Guide.
Modbuzz.request/2, /3, and /4 are synchronous and return result directly.
Modbuzz.request_async/2, /3, /4, and /5 return :ok immediately and send result as a message:
{:modbuzz, name, unit_id, request, {:ok, response}}
{:modbuzz, name, unit_id, request, {:error, error_response_or_error_reason}}Use synchronous request for simple command flow. Use asynchronous request when you need non-blocking behavior or concurrent request orchestration.
Start functions return:
:ok{:error, :already_started}
Stop functions return:
:ok{:error, :not_started}
It is safe to call stop even when the process may already be down, as long as you handle {:error, :not_started}.
data_source for Modbuzz.start_tcp_server/4 and Modbuzz.start_rtu_server/4 can be:
- Data server name
- TCP client name
- RTU client name
TCP server example:
:ok = Modbuzz.start_tcp_server(:your_tcp_server, {192, 168, 1, 10}, 502, :your_data_source)RTU server example:
:ok = Modbuzz.start_rtu_server(:your_rtu_server, "ttyUSB1", [speed: 19200], :your_data_source)Use these recipes after you confirm Quick Start works.
TCP server receives a request and passes it through to RTU client.
:ok = Modbuzz.start_rtu_client(:your_rtu_client, "ttyUSB0", [speed: 9600])
:ok = Modbuzz.start_tcp_server(:your_tcp_server, {192, 168, 1, 10}, 502, :your_rtu_client)RTU server receives a request and passes it through to TCP client.
:ok = Modbuzz.start_tcp_client(:your_tcp_client, {192, 168, 0, 10}, 502)
:ok = Modbuzz.start_rtu_server(:your_rtu_server, "ttyUSB1", [speed: 19200], :your_tcp_client)TCP server receives a request and passes it through to TCP client.
:ok = Modbuzz.start_tcp_client(:your_tcp_client, {192, 168, 0, 10}, 502)
:ok = Modbuzz.start_tcp_server(:your_tcp_server, {192, 168, 1, 10}, 502, :your_tcp_client)RTU server receives a request and passes it through to RTU client.
:ok = Modbuzz.start_rtu_client(:your_rtu_client, "ttyUSB0", [speed: 9600])
:ok = Modbuzz.start_rtu_server(:your_rtu_server, "ttyUSB1", [speed: 19200], :your_rtu_client)- Timeout on request: Check that the client/server is started, the device is reachable, and the request matches the expected unit/address.
- No async result message:
request_asyncreturns:okeven if the target process is not running. Verify the client/server startup first. - Wrong or missing unit data:
If you are using a data server as backend source, ensure
create_unit/2was called with the sameunit_idused by the request.
If available in Hex, the package can be installed
by adding modbuzz to your list of dependencies in mix.exs:
def deps do
[
{:modbuzz, "~> 0.2.0"}
]
endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/modbuzz.
This project is licensed under the Apache-2.0 license.
And this project follows the REUSE compliance. For more details, see the REUSE SOFTWARE.
- WEB: https://modbus.org/