SimpleModbus Arduino库使用튜토리얼:让Arduino通过Modbus RTU통신

무료무료 기술 자료

이 글은 바로 읽을 수 있으며 기초 학습과 검색 유입에 적합합니다.

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

SimpleModbus 简介

SimpleModbus 是一套为 Arduino 平台개발的 Modbus RTU 프로토콜库,托管在 Google Code Archive(项目已被归档)。它由 Juan Bester 개발,包含 SimpleModbusMaster(마스터库)和 SimpleModbusSlave(슬레이브库)两个独立的 Arduino 库。虽然项目名称里有"Simple",但它提供的功能覆盖了 Modbus RTU 통신中最常用的기능 코드,非常适合 Arduino 初学者和快速原型개발。

⚠️ 注意:SimpleModbus 项目已不再活跃更新。对于新项目,推荐使用更现代化的 Modbus RTU for Arduino 库(库名为 "Modbus")或 esp-modbus(ESP32 平台)。但 SimpleModbus 的代码简洁易懂,作为학습 Modbus 프로토콜实现的入门자료仍然很有价值。

SimpleModbus 支持的功能

  • SimpleModbusMaster:支持 FC01(读코일)、FC02(读이산 입력)、FC03(读유지 레지스터)、FC04(读입력 레지스터)、FC15(写多코일)、FC16(写多레지스터)
  • SimpleModbusSlave:支持 FC03(读유지 레지스터)和 FC16(写多레지스터)
  • 硬件要求:Arduino + RS-485 转换模块(如 MAX485)

硬件연결

Arduino 通过 MAX485 模块연결 RS-485 总线。典型배선방식:

MAX485 引脚Arduino Uno설명
VCC5V电源
GNDGND
RORX (D0)수신데이터 → Arduino 시리얼 포트 RX
DITX (D1)보내기데이터 ← Arduino 시리얼 포트 TX
RED2수신使能(低有效)
DED2보내기使能(高有效),与 RE 并联到同一 IO
AA (总线+)RS-485 A 线(差分+)
BB (总线-)RS-485 B 线(差分-)

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

SimpleModbusSlave 예제:Arduino 作为 Modbus RTU 슬레이브

#include <SimpleModbusSlave.h>

// 定义유지 레지스터数组(10个레지스터)
enum {
    TEMP_REG = 0,      // 온도(x10)
    HUMIDITY_REG,       // 湿度(x10)
    COIL_STATUS,        // 코일 상태
    SETPOINT,           // 设定值
    // ... 更多레지스터
    TOTAL_REGS = 10
};

unsigned int holdingRegs[TOTAL_REGS];

void setup() {
    // 设置 RS-485 方向控制引脚
    pinMode(2, OUTPUT);
    
    // SimpleModbusSlave 매개변수:
    // 1. 레지스터数组주소
    // 2. 레지스터 수량
    // 3. 보내기使能引脚
    // 4. 보내기使能有效电平
    // 5. 슬레이브 주소
    // 6. 통신 속도
    // 7. 체크섬(0=패리티 없음)
    modbus_configure(holdingRegs, TOTAL_REGS,
                     2,                  // TXEN 引脚
                     HIGH,               // TXEN 高电平时보내기
                     1,                  // 슬레이브 주소
                     9600,               // 통신 속도
                     0);                 // 체크섬
}

void loop() {
    // 更新센서데이터(模拟)
    holdingRegs[TEMP_REG] = analogRead(A0) / 2; // 온도(模拟)
    holdingRegs[HUMIDITY_REG] = analogRead(A1) / 3;
    holdingRegs[COIL_STATUS] = digitalRead(3);
    
    // 处理 Modbus 请求
    modbus_update();
}

SimpleModbusMaster 예제:읽기슬레이브데이터

#include <SimpleModbusMaster.h>

#define TOTAL_NO_OF_REGISTERS 2
unsigned int holdingRegs[TOTAL_NO_OF_REGISTERS];

void setup() {
    Serial.begin(9600);
    
    // SimpleModbusMaster 매개변수:
    // 1. 本地레지스터数组
    // 2. 읽기/쓰기的레지스터 수량
    // 3. 보내기使能引脚
    // 4. 보내기使能有效电平
    modbus_configure(holdingRegs, TOTAL_NO_OF_REGISTERS,
                     2,      // TXEN 引脚
                     HIGH);  // TXEN 高电平时보내기
}

void loop() {
    // 슬레이브 주소 1,시작주소 0,읽기 2 个유지 레지스터
    unsigned char result = modbus_read_holding_registers(1, 0, 2);
    
    if (result == 0) {
        Serial.print("온도: ");
        Serial.print(holdingRegs[0] / 10.0);
        Serial.print("°C, 湿度: ");
        Serial.print(holdingRegs[1] / 10.0);
        Serial.println("%");
    } else {
        Serial.print("Modbus 읽기失败,错误码: ");
        Serial.println(result);
    }
    
    delay(1000);
}

SimpleModbus vs 现代替代方案

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

库名平台特点
ArduinoModbusArduino(官方)Arduino 官方维护,支持 RTU 和 TCP,Arduino IDE 库管理器一键安装
Modbus-Master-Slave-for-ArduinoArduino同时支持마스터和슬레이브,기능 코드覆盖全,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); // 默认수신모드
}

void loop() {
    // 보내기 Modbus RTU 请求(手动构造帧)
    uint8_t request[] = {
        0x01,        // 슬레이브 주소
        0x03,        // 기능 코드(读유지 레지스터)
        0x00, 0x00,  // 시작주소
        0x00, 0x02   // 읽기 2 个레지스터
    };
    uint16_t crc = calculateCRC(request, 6);
    request[6] = crc & 0xFF;
    request[7] = crc >> 8;
    
    // 전환到보내기모드
    digitalWrite(DE_RE, HIGH);
    delayMicroseconds(100);
    modbusSerial.write(request, 8);
    modbusSerial.flush();
    
    // 전환回수신모드
    digitalWrite(DE_RE, LOW);
    
    // 대기响应
    delay(500);
    while (modbusSerial.available()) {
        Serial.printf("%02X ", modbusSerial.read());
    }
    Serial.println();
    delay(2000);
}

Arduino 官方 ArduinoModbus 库

在 Arduino IDE 中열기库管理器(Sketch → Include Library → Manage Libraries),검색 "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 슬레이브(주소 1)
    ModbusRTUServer.begin(1, 9600);
    
    // 설정유지 레지스터
    ModbusRTUServer.configureHolding회원가입s(0, 10);
}

void loop() {
    // 轮询 Modbus 请求
    ModbusRTUServer.poll();
    
    // 更新레지스터 값
    int sensorValue = analogRead(A0);
    ModbusRTUServer.holding회원가입Write(0, sensorValue);
}

常见문제排查

통신完全没有响应

  • 检查 MAX485 DE/RE 引脚的方向전환逻辑是否正确(보내기时 HIGH、수신时 LOW)
  • 确认통신 속도和슬레이브 주소与마스터설정一致
  • 用 USB 转 RS-485 模块 + 시리얼 포트助手监控总线데이터,确认信号是否存在
  • 检查 A/B 线是否接反(用万用表测差分电压:A 对 B 应为正电压时总线空闲)

偶尔丢데이터或 CRC 错误

  • 检查 RS-485 总线两端是否加了 120Ω 终端电阻
  • 降低통신 속도尝试(4800 或 2400),排除信号完整性因素
  • 缩短总线길이或加中继器
  • 确认보내기完成到수신전환之间留有足够的延时(至少 1 个문자时间)

总结

SimpleModbus 作为早期 Arduino Modbus RTU 库,其代码简洁、功能明确,适合初学者理解 Modbus 프로토콜的实现원리。但在实际项目中,推荐使用维护更活跃、功能更完善的替代方案:Arduino 官方库 ArduinoModbus(通用 Arduino 平台)或 esp-modbus(ESP32/ESP8266 平台)。无论选择哪个库,核心的 Modbus RTU 통신원리——슬레이브 주소、기능 코드、레지스터 매핑、CRC 검증——都是一致的。

실제 프로젝트에 이 자료를 활용하시겠습니까?

도구 센터에서 프레임 분석, CRC 검증, 장비 디버깅을 진행하거나 요청을 제출하여 선정 및 연동 제안을 받아보세요.

엔지니어 회원

이 글을 실행 가능한 디버깅 자료로 활용하세요

가입하면 고급 프레임 분석, 자료 패키지 다운로드, 코드 예제, 엔지니어링 사례, 우선 기술 지원을 이용할 수 있어 실제 프로젝트 납품에 적합합니다.

고급 도구 무제한 이용
자료 패키지와 코드 패키지
완전한 엔지니어링 사례 라이브러리
우선 기술 지원 채널

답글 작성

이메일 주소는 공개되지 않습니다. 必填项已用 * 标注