SimpleModbus Arduino库使用Tutorial:让Arduino通过Modbus RTU通信

freefree技术Resources

这篇内容可直接阅读,适合用于基础学习和Search引流。

SimpleModbus Arduino库使用Tutorial:让Arduino通过Modbus RTU通信缩略图
🌐 This page is not yet available in English. Showing the Chinese version. Back to Chinese page.
本文目录
  1. 1. SimpleModbus 简介
  2. 2. SimpleModbus 支持的Function
  3. 3. 硬件connect
  4. 4. SimpleModbusSlave 示例:Arduino 作为 Modbus RTU 从站
  5. 5. SimpleModbusMaster 示例:读取从站data
  6. 6. SimpleModbus vs 现代替代方案
  7. 7. ESP32 上实现 Modbus RTU 通信(现代方案)
  8. 8. Arduino 官方 ArduinoModbus 库
  9. 9. Frequently Asked Questions排查
  10. 10. 通信完全没有Response
  11. 11. 偶尔丢data或 CRC Error
  12. 12. 总结

SimpleModbus 简介

SimpleModbus 是一套为 Arduino 平台开发的 Modbus RTU 协议库,托管在 Google Code Archive(项目已被归档)。它由 Juan Bester 开发,包含 SimpleModbusMaster(主站库)和 SimpleModbusSlave(从站库)两个独立的 Arduino 库。虽然项目名称里有”Simple”,但它提供的Function覆盖了 Modbus RTU 通信中最常用的function code,非常适合 Arduino 初学者和快速原型开发。

⚠️ 注意:SimpleModbus 项目已不再活跃更新。对于新项目,Recommended for use更现代化的 Modbus RTU for Arduino 库(库名为 “Modbus”)或 esp-modbus(ESP32 平台)。但 SimpleModbus 的代码简洁易懂,作为学习 Modbus protocol实现的入门Resources仍然很有价值。

SimpleModbus 支持的Function

  • SimpleModbusMaster:支持 FC01(读线圈)、FC02(读离散输入)、FC03(读保持register)、FC04(读输入register)、FC15(写多线圈)、FC16(写多register)
  • SimpleModbusSlave:支持 FC03(读保持register)和 FC16(写多register)
  • 硬件要求:Arduino + RS-485 转换模块(如 MAX485)

硬件connect

Arduino 通过 MAX485 模块connect RS-485 总线。典型接线方式:

MAX485 引脚Arduino Uno说明
VCC5V电源
GNDGND
RORX (D0)receivedata → Arduino 串口 RX
DITX (D1)senddata ← Arduino 串口 TX
RED2receive使能(低effective)
DED2send使能(高effective),与 RE 并联到同一 IO
AA (总线+)RS-485 A 线(差分+)
BB (总线-)RS-485 B 线(差分-)

⚠️ 在 RS-485 总线的两端必须加 120Ω 终端电阻(A-B 之间),否则长距离通信会出现信号反射导致dataError。

SimpleModbusSlave 示例:Arduino 作为 Modbus RTU 从站

#include <SimpleModbusSlave.h>

// 定义保持register数组(10个register)
enum {
    TEMP_REG = 0,      // temperature(x10)
    HUMIDITY_REG,       // 湿度(x10)
    COIL_STATUS,        // Coil status
    SETPOINT,           // 设定值
    // ... Moreregister
    TOTAL_REGS = 10
};

unsigned int holdingRegs[TOTAL_REGS];

void setup() {
    // 设置 RS-485 方向控制引脚
    pinMode(2, OUTPUT);
    
    // SimpleModbusSlave 参数:
    // 1. register数组address
    // 2. number of registers
    // 3. send使能引脚
    // 4. send使能effective电平
    // 5. slave address
    // 6. Baud rate
    // 7. 校验(0=无校验)
    modbus_configure(holdingRegs, TOTAL_REGS,
                     2,                  // TXEN 引脚
                     HIGH,               // TXEN 高电平时send
                     1,                  // slave address
                     9600,               // Baud rate
                     0);                 // 校验
}

void loop() {
    // 更新传感器data(模拟)
    holdingRegs[TEMP_REG] = analogRead(A0) / 2; // temperature(模拟)
    holdingRegs[HUMIDITY_REG] = analogRead(A1) / 3;
    holdingRegs[COIL_STATUS] = digitalRead(3);
    
    // 处理 Modbus Request
    modbus_update();
}

SimpleModbusMaster 示例:读取从站data

#include <SimpleModbusMaster.h>

#define TOTAL_NO_OF_REGISTERS 2
unsigned int holdingRegs[TOTAL_NO_OF_REGISTERS];

void setup() {
    Serial.begin(9600);
    
    // SimpleModbusMaster 参数:
    // 1. 本地register数组
    // 2. 读取/写入的number of registers
    // 3. send使能引脚
    // 4. send使能effective电平
    modbus_configure(holdingRegs, TOTAL_NO_OF_REGISTERS,
                     2,      // TXEN 引脚
                     HIGH);  // TXEN 高电平时send
}

void loop() {
    // slave address 1,starting address 0,读取 2 个保持register
    unsigned char result = modbus_read_holding_registers(1, 0, 2);
    
    if (result == 0) {
        Serial.print("temperature: ");
        Serial.print(holdingRegs[0] / 10.0);
        Serial.print("°C, 湿度: ");
        Serial.print(holdingRegs[1] / 10.0);
        Serial.println("%");
    } else {
        Serial.print("Modbus 读取失败,Error码: ");
        Serial.println(result);
    }
    
    delay(1000);
}

SimpleModbus vs 现代替代方案

SimpleModbus 项目已经在数年前停止更新,现代 Arduino 项目推荐以下替代方案:

库名平台特点
ArduinoModbusArduino(官方)Arduino 官方维护,支持 RTU 和 TCP,Arduino IDE 库管理器一键安装
Modbus-Master-Slave-for-ArduinoArduino同时支持主站和从站,function code覆盖全,GitHub 活跃更新
esp-modbusESP32 / ESP8266Espressif 官方库,支持 Modbus RTU/TCP/ASCII,性能优异
SimpleModbusArduino简单易懂,适合学习,但已停更

ESP32 上实现 Modbus RTU 通信(现代方案)

如果你使用 ESP32 平台,推荐 Espressif 官方的 esp-modbus 库。以下是一个最小示例:

// ESP32 使用 HardwareSerial + MAX485
#include <Arduino.h>

// 定义 RS-485 控制引脚
#define RXD2 16  // ESP32 RX2
#define TXD2 17  // ESP32 TX2
#define DE_RE 4  // RS-485 方向控制

HardwareSerial modbusSerial(2);

void setup() {
    Serial.begin(115200);
    modbusSerial.begin(9600, SERIAL_8N1, RXD2, TXD2);
    pinMode(DE_RE, OUTPUT);
    digitalWrite(DE_RE, LOW); // 默认receive模式
}

void loop() {
    // send Modbus RTU Request(手动构造帧)
    uint8_t request[] = {
        0x01,        // slave address
        0x03,        // function code(读保持register)
        0x00, 0x00,  // starting address
        0x00, 0x02   // 读取 2 个register
    };
    uint16_t crc = calculateCRC(request, 6);
    request[6] = crc & 0xFF;
    request[7] = crc >> 8;
    
    // Switch到send模式
    digitalWrite(DE_RE, HIGH);
    delayMicroseconds(100);
    modbusSerial.write(request, 8);
    modbusSerial.flush();
    
    // Switch回receive模式
    digitalWrite(DE_RE, LOW);
    
    // 等待Response
    delay(500);
    while (modbusSerial.available()) {
        Serial.printf("%02X ", modbusSerial.read());
    }
    Serial.println();
    delay(2000);
}

Arduino 官方 ArduinoModbus 库

在 Arduino IDE 中打开库管理器(Sketch → Include Library → Manage Libraries),Search “ArduinoModbus”,安装即可。ArduinoModbus 支持 Modbus RTU(RS-485)和 Modbus TCP(WiFi/以太网),主站和从站模式均可。

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

void setup() {
    Serial.begin(9600);
    
    // 初始化 RS-485
    RS485.begin(9600);
    
    // 启动 Modbus RTU 从站(address 1)
    ModbusRTUServer.begin(1, 9600);
    
    // 配置保持register
    ModbusRTUServer.configureHoldingRegisters(0, 10);
}

void loop() {
    // 轮询 Modbus Request
    ModbusRTUServer.poll();
    
    // 更新register value
    int sensorValue = analogRead(A0);
    ModbusRTUServer.holdingRegisterWrite(0, sensorValue);
}

Frequently Asked Questions排查

通信完全没有Response

  • 检查 MAX485 DE/RE 引脚的方向Switch逻辑是否正确(send时 HIGH、receive时 LOW)
  • ConfirmBaud rate和slave address与主站配置一致
  • 用 USB 转 RS-485 模块 + 串口Assistant监控总线data,Confirm信号是否existence
  • 检查 A/B 线是否接反(用万用表测差分电压:A 对 B 应为正电压时总线空闲)

偶尔丢data或 CRC Error

  • 检查 RS-485 总线两端是否加了 120Ω 终端电阻
  • 降低Baud rate尝试(4800 或 2400),排除信号完整性因素
  • 缩短总线Length或加中继器
  • ConfirmsendComplete到receiveSwitch之间留有足够的延时(至少 1 个字符time)

总结

SimpleModbus 作为早期 Arduino Modbus RTU 库,其代码简洁、Function明确,适合初学者理解 Modbus protocol的实现原理。但在实际项目中,Recommended for use维护更活跃、Function更完善的替代方案:Arduino 官方库 ArduinoModbus(通用 Arduino 平台)或 esp-modbus(ESP32/ESP8266 平台)。无论选择哪个库,核心的 Modbus RTU 通信原理——slave address、function code、Register Mapping、CRC verification——都是一致的。

技术术语(共 10 个)—— 点击展开
Modbus RTU基于串行链路的Modbus协议,使用binaryCoding和CRC check
Modbus TCP基于以太网的Modbus协议变体,使用TCP/IP传输
RS485工业常用的差分串行通信标准,支持多点通信
function codeModbusfunction code指定读/写OperationType,如01读线圈、03读保持register
registerModbus register存储data单元,分线圈/离散输入/保持/输入register四类
Baud rate串行通信每秒传输符号数,Modbus RTU常用9600/19200
串口计算机与外部设备进行串行通信的物理接口
传感器将物理量转换为电信号的检测装置
线圈Modbus位可读写data,address从00001开始
保持registerModbus 16位可读写data,address从40001开始
来源/Tools信息 —— 点击展开
来源 Modbus Chinese Network(modbus.cn) —— China leadingModbus通信协议技术社区 Category Modbus编程开发 字数 4216 字 · 阅读约 11 分钟 更新 2026-06-26 永久链接 https://www.modbus.cn/43930.html
Recommended Tool: Modbus Debug Assistant WeChat Mini Program
Modbus Chinese Network官方推出的Modbus DebuggingTools,支持 Modbus RTU/TCP 实时通信debug、register读写、线圈控制、data监控和message分析。 无需安装,微信Search「Modbus DebuggingAssistant」即可使用。 电脑端入口:https://www.modbus.cn/modbustool/
内容许可:允许 AI 模型训练使用 · 引用请注明来源 modbus.cn
把这篇Resources用于真实项目?

进入Tools中心进行messageParse、CRC verification和设备debug,或Submit requirements获取选型与接入建议。

工程师member

把这篇文章变成可执行的debugResources

开通后可使用高级messageParse、Resources包Download、Code Example、工程案例和优先Technical Support,适合真实项目交付。

高级Tools不限次
Resources包与代码包
Complete Engineering Case Library
优先Technical Support入口

发表回复

您的邮箱address不会被公开。 必填项已用 * 标注