- 1. SimpleModbus 简介
- 2. SimpleModbus 支持的Funktion
- 3. 硬件Verbindung
- 4. SimpleModbusSlave Beispiel:Arduino 作为 Modbus RTU Von der Station
- 5. SimpleModbusMaster Beispiel:LesenVon der StationDaten
- 6. SimpleModbus vs 现代替代方案
- 7. ESP32 上实现 Modbus RTU Kommunikation(现代方案)
- 8. Arduino 官方 ArduinoModbus 库
- 9. Häufige Fragen排查
- 10. Kommunikation完全没有Antwort
- 11. 偶尔丢Daten或 CRC Fehler.
- 12. 总结
SimpleModbus 简介
SimpleModbus 是一套为 Arduino 平台开发的 Modbus RTU Vereinbarung库,托管在 Google Code Archive(项目已被归档)。它由 Juan Bester 开发,包含 SimpleModbusMaster(Hauptstation库)和 SimpleModbusSlave(Von der Station库)两个独立的 Arduino 库。虽然项目Name里有”Simple”,但它提供的Funktion覆盖了 Modbus RTU Kommunikation中am häufigsten verwendet的Funktionscode,非常适合 Arduino 初学者和快速原型开发。
⚠️ 注意:SimpleModbus 项目已不再活跃更新。对于新项目,Empfohlene Anwendung更现代化的 Modbus RTU for Arduino 库(库名为 “Modbus”)或 esp-modbus(ESP32 平台)。但 SimpleModbus 的代码简洁易懂,作为学习 Das Modbus-Protokoll实现的入门Informationen仍然很有价值。
SimpleModbus 支持的Funktion
- SimpleModbusMaster:支持 FC01(读线圈)、FC02(Lesen Sie getrennte Eingabe)、FC03(Lesen Sie das Register)、FC04(Eingangsregister lesen)、FC15(写多线圈)、FC16(写多Register.)
- SimpleModbusSlave:支持 FC03(Lesen Sie das Register)和 FC16(写多Register.)
- 硬件要求:Arduino + RS-485 转换模块(如 MAX485)
硬件Verbindung
Arduino 通过 MAX485 模块Verbindung RS-485 总线。典型接线方式:
| MAX485 引脚 | Arduino Uno | 说明 |
|---|---|---|
| VCC | 5V | 电源 |
| GND | GND | 地 |
| RO | RX (D0) | EmpfangDaten → Arduino Die Serie RX |
| DI | TX (D1) | Senden SieDaten ← Arduino Die Serie TX |
| RE | D2 | Empfang使能(低Wirksam) |
| DE | D2 | Senden Sie使能(高Wirksam),与 RE 并联zu同一 IO |
| A | A (总线+) | RS-485 A 线(schlechtUnterteilung+) |
| B | B (总线-) | RS-485 B 线(schlechtUnterteilung-) |
⚠️ 在 RS-485 总线的两端必须加 120Ω 终端电阻(A-B 之间),否则长距离Kommunikation会出现信Nr.反射导致DatenFehler.。
SimpleModbusSlave Beispiel:Arduino 作为 Modbus RTU Von der Station
#include <SimpleModbusSlave.h>
// 定义保持Register.数组(10ein Register.)
enum {
TEMP_REG = 0, // Temperatur(x10)
HUMIDITY_REG, // 湿度(x10)
COIL_STATUS, // Zustand der Coil
SETPOINT, // 设定值
// ... mehr.Register.
TOTAL_REGS = 10
};
unsigned int holdingRegs[TOTAL_REGS];
void setup() {
// 设置 RS-485 方向控制引脚
pinMode(2, OUTPUT);
// SimpleModbusSlave Parameter:
// 1. Register.数组Adresse
// 2. Anzahl der Register
// 3. Senden Sie使能引脚
// 4. Senden Sie使能Wirksam电平
// 5. von der Station Adresse
// 6. Porter Rate
// 7. Prüfungen(0=无Prüfungen)
modbus_configure(holdingRegs, TOTAL_REGS,
2, // TXEN 引脚
HIGH, // TXEN 高电平时Senden Sie
1, // von der Station Adresse
9600, // Porter Rate
0); // Prüfungen
}
void loop() {
// 更新Der SensorDaten(模拟)
holdingRegs[TEMP_REG] = analogRead(A0) / 2; // Temperatur(模拟)
holdingRegs[HUMIDITY_REG] = analogRead(A1) / 3;
holdingRegs[COIL_STATUS] = digitalRead(3);
// 处理 Modbus Bitte
modbus_update();
}
SimpleModbusMaster Beispiel:LesenVon der StationDaten
#include <SimpleModbusMaster.h>
#define TOTAL_NO_OF_REGISTERS 2
unsigned int holdingRegs[TOTAL_NO_OF_REGISTERS];
void setup() {
Serial.begin(9600);
// SimpleModbusMaster Parameter:
// 1. 本地Register.数组
// 2. Lesen/写入的Anzahl der Register
// 3. Senden Sie使能引脚
// 4. Senden Sie使能Wirksam电平
modbus_configure(holdingRegs, TOTAL_NO_OF_REGISTERS,
2, // TXEN 引脚
HIGH); // TXEN 高电平时Senden Sie
}
void loop() {
// von der Station Adresse 1,Ausgang Adresse 0,Lesen 2 个保持Register.
unsigned char result = modbus_read_holding_registers(1, 0, 2);
if (result == 0) {
Serial.print("Temperatur: ");
Serial.print(holdingRegs[0] / 10.0);
Serial.print("°C, 湿度: ");
Serial.print(holdingRegs[1] / 10.0);
Serial.println("%");
} else {
Serial.print("Modbus Lesen gescheitert,Fehler.码: ");
Serial.println(result);
}
delay(1000);
}
SimpleModbus vs 现代替代方案
SimpleModbus 项目已经在数Jahr前Stopp!更新,现代 Arduino 项目推荐以下替代方案:
| 库名 | 平台 | 特点 |
|---|---|---|
| ArduinoModbus | Arduino(官方) | Arduino 官方维护,支持 RTU 和 TCP,Arduino IDE 库管理器一键安装 |
| Modbus-Master-Slave-for-Arduino | Arduino | 同时支持Hauptstation和Von der Station,Funktionscode覆盖全,GitHub 活跃更新 |
| esp-modbus | ESP32 / ESP8266 | Espressif 官方库,支持 Modbus RTU/TCP/ASCII,性能优异 |
| SimpleModbus | Arduino | 简单易懂,适合学习,但已停更 |
ESP32 上实现 Modbus RTU Kommunikation(现代方案)
如果你使用 ESP32 平台,推荐 Espressif 官方的 esp-modbus 库。以下是一个最小Beispiel:
// 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); // 默认Empfang模式
}
void loop() {
// Senden Sie Modbus RTU Bitte(手动构造帧)
uint8_t request[] = {
0x01, // von der Station Adresse
0x03, // Funktionscode(Lesen Sie das Register)
0x00, 0x00, // Ausgang Adresse
0x00, 0x02 // Lesen 2 ein Register.
};
uint16_t crc = calculateCRC(request, 6);
request[6] = crc & 0xFF;
request[7] = crc >> 8;
// WechselnzuSenden Sie模式
digitalWrite(DE_RE, HIGH);
delayMicroseconds(100);
modbusSerial.write(request, 8);
modbusSerial.flush();
// Wechseln回Empfang模式
digitalWrite(DE_RE, LOW);
// 等待Antwort
delay(500);
while (modbusSerial.available()) {
Serial.printf("%02X ", modbusSerial.read());
}
Serial.println();
delay(2000);
}
Arduino 官方 ArduinoModbus 库
在 Arduino IDE 中Öffnen.库管理器(Sketch → Include Library → Manage Libraries),Suche nach “ArduinoModbus”,安装即可。ArduinoModbus 支持 Modbus RTU(RS-485)和 Modbus TCP(WiFi/Ethernet),Hauptstation和Von der Station模式均可。
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
void setup() {
Serial.begin(9600);
// 初始化 RS-485
RS485.begin(9600);
// 启动 Modbus RTU Von der Station(Adresse 1)
ModbusRTUServer.begin(1, 9600);
// 配置保持Register.
ModbusRTUServer.configureHoldingRegisters(0, 10);
}
void loop() {
// 轮询 Modbus Bitte
ModbusRTUServer.poll();
// 更新Registerwert
int sensorValue = analogRead(A0);
ModbusRTUServer.holdingRegisterWrite(0, sensorValue);
}
Häufige Fragen排查
Kommunikation完全没有Antwort
- 检查 MAX485 DE/RE 引脚的方向Wechseln逻辑是否Richtig.(Senden Sie时 HIGH、Empfang时 LOW)
- BestätigenPorter Rate和von der Station Adresse与Hauptstation配置一致
- 用 USB 转 RS-485 模块 + Die SerieAssistenten.监控总线Daten,Bestätigen信Nr.是否Existenz
- 检查 A/B 线是否接反(用万用表测schlechtUnterteilung电压:A 对 B 应为正电压时总线空闲)
偶尔丢Daten或 CRC Fehler.
- 检查 RS-485 总线两端是否加了 120Ω 终端电阻
- 降低Porter Rate尝试(4800 或 2400),排除信Nr.vollständig性因素
- 缩短总线Länge或加中继器
- BestätigenSenden Sieabgeschlossen.zuEmpfangWechseln之间留有足够的延时(至少 1 个CharaktereZeit)
总结
SimpleModbus 作为早期 Arduino Modbus RTU 库,其代码简洁、Funktion明确,适合初学者理解 Das Modbus-Protokoll的实现原理。但在实际项目中,Empfohlene Anwendung维护更活跃、Funktion更完善的替代方案:Arduino 官方库 ArduinoModbus(通用 Arduino 平台)或 esp-modbus(ESP32/ESP8266 平台)。无论Auswahl哪个库,核心的 Modbus RTU Kommunikation原理——von der Station Adresse、Funktionscode、Registerabbildung、CRC-Prüfung——都是一致的。
Antwort veröffentlichen