示例程序
本章说明如何下载、配置并运行 C、Python、STM32 和 Arduino 示例,通过 Modbus RTU 使用 Modbus RTU Module (A) 的继电器输出、数字量输入、模拟量输入和模拟电流输出。
本产品为成品功能模块,不属于二次开发模块,不提供模块内部固件源码及工程文件。
本页提供的 C、Python、STM32 和 Arduino 程序仅用于演示外部主控如何通过 Modbus RTU 操作模块,并非模块源码。
主控板适配、硬件故障排查以及用户自行修改的 GPIO、UART 初始化代码不属于示例程序支持范围。
下载示例程序
Ubuntu 用户安装下载和解压工具,然后下载示例压缩包。发布前请将 DOWNLOAD_URL 替换为实际下载链接。
sudo apt install -y wget unzip
wget https://files.waveshare.com/wiki/Modbus-RTU-Module-A/Modbus_RTU_Module_A_Demo.zip
unzip Modbus_RTU_Module_A_Demo.zip
cd Modbus_RTU_Module_A_Demo
解压后的目录结构如下:
Modbus_RTU_Module_A_Demo/
├── c/
├── python/
├── STM32/
└── Arduino/
Windows 用户可以使用浏览器下载示例程序并解压,后续进入对应平台目录即可。
开发协议请参考 Modbus RTU Module (A) 开发协议。
功能概览
设备具有 2 路继电器输出、2 路数字量输入、2 路模拟电流输出和 2 路模拟量输入,各功能组的通道编号均为 1~2。示例库提供以下功能:
| 功能 | C、STM32 | Python | Arduino | Modbus 指令 |
|---|---|---|---|---|
| 读取或控制单路继电器 | read_relay、write_relay | read_relay()、write_relay() | readRelay()、writeRelay() | 读 0x01,写 0x05 |
| 读取或控制两路继电器 | read_relays、write_all_relays、write_relays | read_relays()、write_all_relays()、write_relays() | readRelays()、writeAllRelays()、writeRelays() | 读 0x01,写 0x05 或 0x0F |
| 继电器闪开或闪闭 | pulse_relay | pulse_relay() | pulseRelay() | 写 0x05 |
| 读取单路或两路数字量输入 | read_digital_input、read_digital_inputs | read_digital_input()、read_digital_inputs() | readDigitalInput()、readDigitalInputs() | 读 0x02 |
| 读写单路继电器控制模式 | read_control_mode、write_control_mode | read_control_mode()、write_control_mode() | readControlMode()、writeControlMode() | 读 0x03,写 0x06 |
| 读写两路继电器控制模式 | read_control_modes、write_control_modes | read_control_modes()、write_control_modes() | readControlModes()、writeControlModes() | 读 0x03,写 0x10 |
| 读写单路模拟电流输出 | read_analog_output、write_analog_output | read_analog_output()、write_analog_output() | readAnalogOutput()、writeAnalogOutput() | 读 0x03,写 0x06 |
| 读写两路模拟电流输出 | read_analog_outputs、write_analog_outputs | read_analog_outputs()、write_analog_outputs() | readAnalogOutputs()、writeAnalogOutputs() | 读 0x03,写 0x10 |
| 读取单路或两路模拟量输入 | read_analog_input、read_analog_inputs | read_analog_input()、read_analog_inputs() | readAnalogInput()、readAnalogInputs() | 读 0x04 |
| 读写单路模拟输入类型 | read_analog_input_type、write_analog_input_type | read_analog_input_type()、write_analog_input_type() | readAnalogInputType()、writeAnalogInputType() | 读 0x03,写 0x06 |
| 读写两路模拟输入类型 | read_analog_input_types、write_analog_input_types | read_analog_input_types()、write_analog_input_types() | readAnalogInputTypes()、writeAnalogInputTypes() | 读 0x03,写 0x10 |
| 读取或设置串口参数 | read_serial_param、write_serial_param | read_serial_parameters()、write_serial_parameters() | readSerialParameters()、writeSerialParameters() | 读 0x03,写 0x06 |
| 读取或设置设备地址 | read_address、write_address | read_device_address()、write_device_address() | readDeviceAddress()、writeDeviceAddress() | 读 0x03,写 0x06 |
| 读取软件版本 | read_version | read_software_version() | readSoftwareVersion() | 读 0x03 |
完整示例只查询串口参数和设备地址,不修改通信配置。其它设备函数均会运行一次;涉及保持寄存器或线圈写入时,程序会先查询原状态,写入演示值,再次查询实际状态。
Python 示例
测试环境:Ubuntu 22.04,USB‑TO‑RS485(B)转换器
Python 示例位于 python/ 目录,使用 pymodbus 完成 Modbus RTU 通信。建议在虚拟环境中安装依赖:
sudo apt install -y python3 python3-venv python3-pip
cd python
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
打开 main_module_a.py,根据实际连接修改串口、波特率、超时和设备地址。示例默认串口为 /dev/ttyUSB0:
SERIAL_PORT = "/dev/ttyUSB0"
SERIAL_BAUDRATE = 9600
SERIAL_TIMEOUT_SECONDS = 0.3
DEVICE_ID = 1
PRINT_FRAMES = True
示例中的主要操作如下:
# 串口总线和 Module A 设备分别初始化,同一条总线可连接多个设备。
client = ModbusSerialClient(
port=SERIAL_PORT,
baudrate=SERIAL_BAUDRATE,
bytesize=8,
parity="N",
stopbits=1,
timeout=SERIAL_TIMEOUT_SECONDS,
)
bus = ModbusRtuBus(client)
bus.connect()
device = ModbusRtuModuleA(device_id=1)
# 查询 DO1,设置为关闭,再查询实际状态。
before = device.read_relay(bus, 1)
device.write_relay(bus, 1, RELAY_OFF)
after = device.read_relay(bus, 1)
# 读取两路数字量输入和两路模拟量输入。
digital_inputs = device.read_digital_inputs(bus)
analog_inputs = device.read_analog_inputs(bus)
完整示例依次演示功能概览中的全部查询和控制函数。每一步都会打印操作名称、TX、RX 和执行结果;读取结果保存在 ModbusRtuModuleA 对象中。所有步骤仅执行一次,完成后关闭串口并退出程序。
运行完整示例:
python main_module_a.py
实例如下所示:

C 示例
测试环境:Ubuntu 22.04,USB‑TO‑RS485(B)转换器
C 示例位于 c/ 目录:
module_a.h:数据结构、错误码和对外接口声明。module_a.c:串口通信、Modbus RTU 帧组装、CRC 校验、响应检查和设备操作实现。main_module_a.c:完整调用示例,并打印每次通信的 TX、RX 数据帧。Makefile:编译、运行和清理命令。
运行前请在 main_module_a.c 中修改 MODULE_A_DEMO_PORT。Linux 可填写 /dev/ttyUSB0 或 /dev/ttyACM0,Windows 可填写 COM6 等实际端口名称。示例不接收命令行参数,修改后需要重新执行 make。
#define MODULE_A_DEMO_PORT "/dev/ttyUSB0"
#define MODULE_A_DEMO_BAUDRATE 9600u
#define MODULE_A_DEMO_TIMEOUT_MS 300u
#define MODULE_A_DEMO_ADDRESS 1u
示例中的主要操作如下:
ModbusRtuBus bus;
ModbusRtuModuleA device;
module_a_bus_open(&bus, MODULE_A_DEMO_PORT, MODULE_A_DEMO_BAUDRATE);
module_a_init(&device, MODULE_A_DEMO_ADDRESS);
/* 查询 DO1,设置为关闭,再查询实际状态。 */
device.read_relay(&device, &bus, 1u);
device.write_relay(&device, &bus, 1u, MODULE_A_RELAY_OFF);
device.read_relay(&device, &bus, 1u);
module_a_bus_close(&bus);
完整示例依次演示功能概览中的全部查询和控制函数。每一步都会打印操作名称、TX、RX 和执行结果;读取结果保存在 ModbusRtuModuleA 结构体中。所有步骤仅执行一次,完成后关闭串口并退出程序。
Linux 编译和运行:
sudo apt install -y build-essential
cd c
make
./module_a_demo
Windows 使用 MSYS2/MinGW 时执行:
cd c
mingw32-make
.\module_a_demo.exe
实例如下所示:

STM32 示例
示例使用的硬件:NUCLEO-F103RB 和 RS485 CAN Shield。
板子的 GPIO 引脚请勿直接连接 RS485 接口。直连有烧坏板子 GPIO 的风险,须经过 RS485 电平转换模块接入总线。
STM32 示例工程的 RS485 和调试串口引脚如下:
| 通道 | STM32 引脚 | 连接或用途 |
|---|---|---|
| RS485 发送 | PA9 / USART1_TX | 连接 RS485 收发器 DI |
| RS485 接收 | PA10 / USART1_RX | 连接 RS485 收发器 RO |
| RS485 方向使能 | PA8 / GPIO Output | 高电平发送,低电平接收 |
| 调试串口发送 | PA2 / USART2_TX | 连接串口工具 RX,输出 TX、RX 报文和运行结果 |
| 调试串口接收 | PA3 / USART2_RX | 示例已初始化,当前演示命令 |
设备函数调用示例:
ModbusRtuBus bus;
ModbusRtuModuleA device;
ModbusRtuBusInit(&bus, &huart1, RS485_DE_GPIO_Port, RS485_DE_Pin, GPIO_PIN_SET, 300u);
ModuleA_Init(&device, 1u);
/* 查询 AO1,设置为 1000 μA,再查询实际值。 */
device.read_analog_output(&device, &bus, 1u);
device.write_analog_output(&device, &bus, 1u, 1000u);
device.read_analog_output(&device, &bus, 1u);
开发板复位后,完整示例会依次演示功能概览中的全部查询和控制函数。每一步都会通过 USART2 打印操作名称、TX、RX 和执行结果;读取结果保存在 ModbusRtuModuleA 结构体中。所有步骤仅执行一次,完成后主程序进入空闲循环,不再向模块发送控制指令。
使用 Keil MDK 编译和烧录:
- 双击打开
STM32/MDK-ARM/Modbus RTU Module A.uvprojx。 - 在 Keil 中选择目标
Modbus RTU Module A,按Rebuild重新编译工程。 - 连接下载器并按下
Download烧录程序。
- 使用串口调试工具打开 USART2 调试串口,参数为
115200, 8N1。 - 复位开发板,查看设备操作、TX、RX 和运行结果。
实例如下所示:

Arduino 示例
示例使用的硬件:UNO PLUS 和 RS485 CAN Shield。
板子的 GPIO 引脚请勿直接连接 RS485 接口。直连有烧坏板子 GPIO 的风险,须经过 RS485 电平转换模块接入总线。
示例使用的串口和引脚如下:
| 功能 | 主控引脚 |
|---|---|
| RS485 RX | D2 |
| RS485 TX | D8 |
| RS485 DE 和 /RE | D7 |
| 串口监视器 | 115200 |
设备函数调用示例:
SoftwareSerial rs485(2, 8); // RX, TX
ModbusRtuBus bus(rs485, 7); // 串口和 RS485 方向控制
ModbusRtuModuleA device(1); // Module A 设备地址
/* 查询 DO1,设置为关闭,再查询实际状态。 */
device.readRelay(bus, 1u);
device.writeRelay(bus, 1u, MODULE_A_RELAY_OFF);
device.readRelay(bus, 1u);
开发板启动后,完整示例会依次演示功能概览中的全部查询和控制函数。每一步都会通过 Arduino IDE 串口监视器打印操作名称、TX、RX 和执行结果;读取结果保存在 ModbusRtuModuleA 对象中。所有步骤仅执行一次,loop() 保持为空,不会重复控制设备。
使用 Arduino IDE 编译和上传:
- 打开
Arduino/Modbus_RTU_Module_A/Modbus_RTU_Module_A.ino。 - 在 Arduino IDE 中选择
Arduino Uno或实际使用的兼容开发板,并选择对应串口。 - 单击“验证”,编译示例程序。
- 单击“上传”,将程序上传到开发板。
- 上传完成后打开“串口监视器”,将波特率设置为
115200。 - 复位开发板,查看设备操作、TX、RX 和运行结果。
实例如下所示:

注意事项
- 模块默认通信参数为
9600, N, 8, 1,默认设备地址为1。 - 完整示例只查询串口参数和设备地址,不会修改模块通信配置。
- 通信失败时,依次检查供电、RS485 A/B 接线、串口权限、设备地址和波特率。