Arduino Modbus 从机开发全攻略:基于 RS485 扩展板的分步实现指南
核心组件与物料清单
- Arduino UNO ×1 — 主控板
- 专业 RS422/RS485 扩展板 ×1 — 光隔离串口通信模块,兼容 Arduino UNO、Arduino 101、STM Nucleo 等
- USB 转 RS485 转换器 ×1 — PC 端 Modbus 主站接口
- 面包板 ×1
- LED(红) ×1
- 电阻 10 kΩ ×1、220 Ω ×1
- 跳线 若干
- 按键开关 12mm ×1
软件工具
- Arduino IDE
- ModbusTester(PC 端 Modbus 主站测试软件)
项目背景
Modbus 作为工业领域事实上的标准串行通信协议,广泛应用于工业电子设备互联。在 Modbus RTU/ASCII 模式下,RS485 是最常用的物理层。Arduino 可作为 Modbus 从机(在特定条件下也可作主机),但必须配备 RS485 接口。本项目采用的 RS422/RS485 扩展板提供全光隔离串口通信,是构建此类应用的理想选择。
本文旨在演示如何利用 Arduino UNO 搭建一个简易 Modbus 从机设备,并以 PC 运行 ModbusTester 作为主站进行测试。
硬件连接
RS485 总线接线
仅需将扩展板的 A、B 端子 与 Modbus 网络的 A、B 线对接;Y、Z 端子在本应用中不使用。长距离传输建议对 A、B 线采用双绞线。
扩展功能接线(可选)
为直观观察通信效果,可在面包板上接入一只 LED(通过 220 Ω 电阻限流)和一个按键(上拉 10 kΩ),分别连接到 Arduino 的数字引脚 12 和 7。此部分非必须,仅用于演示寄存器读写效果。
扩展板 DIP 开关配置
扩展板上有 3 组 DIP 开关,Modbus 模式下设置如下:
- SW1: 1-OFF, 2-ON, 3-ON, 4-OFF
- SW2: 1-OFF, 2-OFF, 3-ON, 4-ON
- SW3: 1-OFF/ON*, 2-OFF, 3-OFF, 4-OFF
* 仅当本模块位于总线末端时,将第 1 位拨至 ON 以接入终端电阻;其余情况均拨 OFF。
跳线帽设置
- JP1 电源电压选择: Arduino UNO 为 5V 逻辑,务必跳接至 5V 位置(3.3V 板卡如 Arduino 101 则跳 3.3V)。
- 通信端口跳线: 左上角跳线帽按丝印连接,将板载 UART(引脚 0/1)接至扩展板 RS485 收发器。
- RX/TX 控制跳线: 本例使用自动收发切换,无需接跳线。
PC 端 ModbusTester 配置
- 下载并解压 ModbusTester,启动软件。
- 先插入 USB-RS485 适配器,在软件中选择对应的 COM 口。
- 设置波特率 9600、从站 ID 1、数据位 8、无校验、停止位 1(9600,8,N,1)。
- 点击“Connect”建立连接。
Arduino 固件说明
固件基于 SimpleModbusSlave 库,实现 9 个保持寄存器:
| 寄存器索引 | 功能 | 地址 (4xxxx) |
|---|---|---|
| 0~5 | ADC 通道 0~5 读数 | 400001~400006 |
| 6 | LED 状态(主站写入控制) | 400007 |
| 7 | 按键状态(主站读取) | 400008 |
| 8 | 累计通信错误计数 | 400009 |
关键初始化参数:modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0); — 波特率 9600,从站 ID 1,收发使能引脚 6(扩展板默认),寄存器总数,低延迟模式关闭。
功能测试
- 在 ModbusTester 中点击 Read,读取 8 个寄存器(地址 400001~400008),可看到 ADC 数值与按键状态实时变化。
- 点击 Write,向地址 400007 写入 1 或 0,板载 LED 将随之点亮/熄灭,验证功能码 0x10(写多寄存器)生效。
完整代码
/* Arduino RS422/RS485 Shield Modbus 从机示例
* Version 1.0, Copyright (C) 2018 Hartmut Wendt, www.zihatec.de
* 基于 https://github.com/angeloc/simplemodbusng
* GPL v3 许可
*/
#include <SimpleModbusSlave.h>
#define ledPin 12 // 板载 LED
#define buttonPin 7 // 按键输入
enum { ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, LED_STATE, BUTTON_STATE, TOTAL_ERRORS, TOTAL_REGS_SIZE };
unsigned int holdingRegs[TOTAL_REGS_SIZE];
void setup() {
modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0);
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);
for (byte i = 0; i < 6; i++) {
holdingRegs[i] = analogRead(i);
delayMicroseconds(50);
}
holdingRegs[BUTTON_STATE] = digitalRead(buttonPin);
byte ledState = holdingRegs[LED_STATE];
if (ledState) digitalWrite(ledPin, HIGH);
else digitalWrite(ledPin, LOW);
}
原理图与实物接线图
详见项目附件中的原理图(schematics 部分),展示了扩展板、Arduino、按键、LED 及 RS485 总线的完整连接关系。
制造工艺
- Arduino Mega 按键 PWM 调光:三阶段渐变 LED 实战教程
- Arduino Nano 与 MPU-6050 构建实时陀螺仪游戏
- Unopad:基于 Arduino 的无缝 Ableton Live MIDI 控制器
- 自制简易红外避障传感器:IR LED + 光电二极管 + Arduino
- Find Me:基于 Arduino 与蓝牙的智能寻物器制作指南
- DIY Arduino 手柄方向盘 - 游戏竞速模拟器自制指南
- 热敏电阻测温轻松上手:Arduino 分步实战教程
- Arduino 合成乐音:从零实现 88 键钢琴全音域
- Arduino 连接 NMEA-0183 设备全攻略:从硬件接线到协议解析
- 基于 Arduino 和超声波传感器的自动门控制系统
- PhoneLocator:基于 Arduino Yun + Blynk 的手机防丢定位器
- 精通 C# Queue:Enqueue、Dequeue 与先进先出操作全解析