samples: add Modbus RTU client sample
Add Modbus RTU client sample. Signed-off-by: Johann Fischer <j.fischer@phytec.de>
This commit is contained in:
parent
48d1b4b697
commit
fef70aa494
6 changed files with 202 additions and 0 deletions
8
samples/subsys/modbus/rtu_client/CMakeLists.txt
Normal file
8
samples/subsys/modbus/rtu_client/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(modbus-rtu-client)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
58
samples/subsys/modbus/rtu_client/README.rst
Normal file
58
samples/subsys/modbus/rtu_client/README.rst
Normal file
|
@ -0,0 +1,58 @@
|
|||
.. _modbus-rtu-client-sample:
|
||||
|
||||
Modbus RTU Client Sample
|
||||
########################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This is a simple application demonstrating a Modbus RTU client implementation
|
||||
in Zephyr RTOS.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
This sample has been tested with the nRF52840-DK and FRDM-K64F boards,
|
||||
but it should work with any board that has a free UART interface.
|
||||
|
||||
RTU client example is running on an evaluation board and communicates
|
||||
with another board that has been prepared according to the description
|
||||
`modbus-rtu-server-sample`.
|
||||
|
||||
In addition to the evaluation board, an USB to RS-485 bus adapter and
|
||||
a RS-485 shield are required. Shield converts the UART TX, RX signals to
|
||||
RS-485 and does not need a specific overlay, an Arduino header compatible
|
||||
shield like `joy-it RS-485 shield for Arduino`_ can be used.
|
||||
|
||||
The A+, B- lines of the RS-485 shield should be connected together.
|
||||
|
||||
Alternatively UART RX,TX signals of two boards can be connected crosswise.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This sample can be found under
|
||||
:zephyr_file:`samples/subsys/modbus/rtu_client` in the Zephyr tree.
|
||||
|
||||
The following commands build and flash RTU client sample.
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/subsys/modbus/rtu_client
|
||||
:board: frdm_k64f
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
The example communicates with the RTU server and lets the LEDs light up
|
||||
one after the other.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
*** Booting Zephyr OS build zephyr-v2.3.0-1993-g07e8d80ae028 ***
|
||||
[00:00:00.005,000] <inf> mb_rtu: RTU timeout 2005 us
|
||||
[00:00:00.050,000] <inf> mbc_sample: WR|RD holding register:
|
||||
48 00 65 00 6c 00 6c 00 6f 00 00 00 00 00 00 00 |H.e.l.l. o.......
|
||||
[00:00:00.062,000] <inf> mbc_sample: Coils state 0x00
|
||||
[00:00:00.864,000] <inf> mbc_sample: Coils state 0x07
|
||||
|
||||
|
||||
.. _`joy-it RS-485 shield for Arduino`: https://joy-it.net/en/products/ARD-RS485
|
15
samples/subsys/modbus/rtu_client/app.overlay
Normal file
15
samples/subsys/modbus/rtu_client/app.overlay
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Phytec Messtechnik GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&arduino_serial {
|
||||
status = "okay";
|
||||
|
||||
modbus0 {
|
||||
compatible = "zephyr,modbus-serial";
|
||||
label = "MODBUS";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
8
samples/subsys/modbus/rtu_client/prj.conf
Normal file
8
samples/subsys/modbus/rtu_client/prj.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
CONFIG_LOG=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||
CONFIG_UART_LINE_CTRL=n
|
||||
|
||||
CONFIG_MODBUS_RTU=y
|
||||
CONFIG_MODBUS_RTU_ROLE_CLIENT=y
|
6
samples/subsys/modbus/rtu_client/sample.yaml
Normal file
6
samples/subsys/modbus/rtu_client/sample.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
sample:
|
||||
name: Modbus RTU Client Sample
|
||||
tests:
|
||||
sample.modbus.rtu_client:
|
||||
tags: uart modbus
|
||||
depends_on: gpio, arduino_serial
|
107
samples/subsys/modbus/rtu_client/src/main.c
Normal file
107
samples/subsys/modbus/rtu_client/src/main.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2020 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <sys/util.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <modbus/modbus_rtu.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(mbc_sample, LOG_LEVEL_INF);
|
||||
|
||||
#define RTU_IFACE 0
|
||||
|
||||
static int init_modbus_client(void)
|
||||
{
|
||||
const uint32_t mb_rtu_br = 19200;
|
||||
const uint32_t rsp_timeout = 50000;
|
||||
|
||||
return mb_rtu_cfg_client(RTU_IFACE, mb_rtu_br, UART_CFG_PARITY_NONE,
|
||||
rsp_timeout, false);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uint16_t holding_reg[8] = {'H', 'e', 'l', 'l', 'o'};
|
||||
const uint8_t coil_qty = 3;
|
||||
uint8_t coil[1] = {0};
|
||||
const int32_t sleep = 250;
|
||||
static uint8_t node = 1;
|
||||
int err;
|
||||
|
||||
|
||||
if (init_modbus_client()) {
|
||||
LOG_ERR("Modbus RTU client initialization failed");
|
||||
return;
|
||||
}
|
||||
|
||||
err = mb_rtu_write_holding_regs(RTU_IFACE, node, 0, holding_reg,
|
||||
ARRAY_SIZE(holding_reg));
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC16 failed");
|
||||
return;
|
||||
}
|
||||
|
||||
err = mb_rtu_read_holding_regs(RTU_IFACE, node, 0, holding_reg,
|
||||
ARRAY_SIZE(holding_reg));
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC03 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_HEXDUMP_INF(holding_reg, sizeof(holding_reg),
|
||||
"WR|RD holding register:");
|
||||
|
||||
while (true) {
|
||||
uint16_t addr = 0;
|
||||
|
||||
err = mb_rtu_read_coils(RTU_IFACE, node, 0, coil, coil_qty);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC01 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("Coils state 0x%02x", coil[0]);
|
||||
|
||||
err = mb_rtu_write_coil(RTU_IFACE, node, addr++, true);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC05 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_msleep(sleep);
|
||||
err = mb_rtu_write_coil(RTU_IFACE, node, addr++, true);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC05 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_msleep(sleep);
|
||||
err = mb_rtu_write_coil(RTU_IFACE, node, addr++, true);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC05 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_msleep(sleep);
|
||||
err = mb_rtu_read_coils(RTU_IFACE, node, 0, coil, coil_qty);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC01 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("Coils state 0x%02x", coil[0]);
|
||||
|
||||
coil[0] = 0;
|
||||
err = mb_rtu_write_coils(RTU_IFACE, node, 0, coil, coil_qty);
|
||||
if (err != 0) {
|
||||
LOG_ERR("FC15 failed with %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_msleep(sleep);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue