Arduino开发板作为Modbus主设备可以读取或改写其他Modbus从设备的数据可作为釆集数据的中转站或显示设备用仅提供软件代码和用Arduino当Modbus主站说白了就是让这块小开发板当数据指挥官——把温湿度传感器、智能电表、PLC这些从站设备的数据捞过来要么自己接个LCD显示要么转发给上位机当中转站甚至还能反过来给从站发指令改参数玩法直接拉满。Arduino开发板作为Modbus主设备可以读取或改写其他Modbus从设备的数据可作为釆集数据的中转站或显示设备用仅提供软件代码和先上核心代码后面碎碎念关键细节#include ModbusRTU.h // 定义Modbus主站用的串口这里用Serial2避免占用调试用的Serial0 ModbusRTU modbusClient; // 从站配置根据你的实际设备改 #define SLAVE_ADDR 1 // 从站地址别和其他设备撞了 #define TEMP_REG 0 // 温度值存在从站的0号保持寄存器 #define HUMI_REG 1 // 湿度值存在1号保持寄存器 #define CONTROL_REG 10 // 用来控制从站继电器的寄存器 void setup() { // 调试串口打开方便看数据 Serial.begin(115200); // Modbus主站串口初始化波特率96008N1标准格式必须和从站一致 modbusClient.begin(9600, SERIAL_8N1, Serial2); delay(100); Serial.println(Arduino Modbus 主站已上线); } void loop() { // 第一步读取从站的温湿度寄存器2个寄存器0和1 uint8_t readStatus modbusClient.readHoldingRegisters(SLAVE_ADDR, TEMP_REG, 2); if (readStatus modbusClient.ku8MBSuccess) { // 从返回的数据包里抠出寄存器值 float temperature modbusClient.getResponseBuffer(0) / 10.0; // 假设从站存的是放大10倍的整数 float humidity modbusClient.getResponseBuffer(1) / 10.0; Serial.print(读取成功 | 温度: ); Serial.print(temperature); Serial.print(℃ | 湿度: ); Serial.print(humidity); Serial.println(%); } else { Serial.print(读取失败错误码: ); Serial.println(readStatus); } // 第二步每隔5秒给从站写一次控制指令比如切换继电器状态 static unsigned long lastWriteTime 0; if (millis() - lastWriteTime 5000) { lastWriteTime millis(); // 生成一个0/1的切换值模拟开关控制 static uint16_t ctrlValue 0; ctrlValue !ctrlValue; uint8_t writeStatus modbusClient.writeSingleRegister(SLAVE_ADDR, CONTROL_REG, ctrlValue); if (writeStatus modbusClient.ku8MBSuccess) { Serial.print(写入成功控制寄存器设为: ); Serial.println(ctrlValue); } else { Serial.print(写入失败错误码: ); Serial.println(writeStatus); } } delay(1000); // 每秒读一次数据别太急 }碎碎念时间串口选择为什么用Serial2而不是默认的Serial因为Serial0要留给电脑调试打印用啊不然你一边发Modbus指令一边打调试信息串口数据就乱成粥了。要是你用的是Nano这种只有一组硬件串口的板子那只能把调试信息关了或者用软件串口库模拟一个。指令踩坑点- 从站地址必须和设备一致比如你买的温湿度模块地址设的是2这里SLAVE_ADDR就得改成2不然主站喊破喉咙也没人理。- 波特率、数据位、停止位必须和从站严丝合缝Modbus RTU默认8N18数据位、无校验、1停止位波特率常用9600/19200瞎改的话就是鸡同鸭讲。数据解析modbusClient.getResponseBuffer(0)这句话就是从返回的数据包里把第一个寄存器的值抠出来。为啥要除以10因为很多传感器会把小数放大10倍存成整数比如25.3℃存成253防止浮点传输出问题读回来再缩回去就行灵活调整。写入逻辑这里写的是单个保持寄存器要是想写多个用writeMultipleRegisters就行。比如给PLC批量写参数一次传好几个值效率更高。实际玩法拓展数据中转站把读取到的温湿度值通过WiFi模块比如ESP8266上传到阿里云/腾讯云Arduino就成了现场设备和云端的桥梁。本地显示接个I2C OLED屏把temperature和humidity丢到屏幕上不用连电脑也能看数据。联动控制比如读到温度超过30℃就给控制寄存器写1触发从站的继电器开风扇完美实现闭环控制。最后提一嘴要是调试的时候一直读不到数据先把主站和从站用USB转TTL接电脑用串口助手发指令试试排除是硬件还是代码的问题——毕竟有时候不是代码错了是杜邦线插反了啊喂