ESP32 modbus RTU程序。 用arduino IDE开发的ESP32 modbus RTU slave程序。 不是库文件,直接用子程序编写,已注释了代码,容易看懂和移植。 已通讯连接成功。 程序已在多个项目上应用,不用怀疑:有气压检测设备,风机加热器控制箱,恒温控制箱,拉挤设备。 细心调试代码你可以快速成功的。

一、代码概述

ESP32ModbusRTU_Slave.ino是基于Arduino IDE开发的ESP32芯片Modbus RTU从站程序,非库文件形式,采用子程序编写并附带详细注释,便于理解与移植。该程序已实现与485设备的成功通讯,且在气压检测设备、风机加热器控制箱、恒温控制箱、拉挤设备等多个实际项目中应用,稳定性与可靠性经过实践验证。

二、核心参数配置

代码开篇定义了程序运行的关键基础参数与系统参数,用户可根据实际硬件与通讯需求灵活调整。

参数类别 参数名称 定义内容 作用说明
基础参数 led 2 指定LED指示灯连接的ESP32引脚,用于状态指示

| | baudrate | 19200 | 设定Modbus RTU通讯波特率,当前为19200bps |

| | slaveID | 1 | 定义从站站号,标识当前设备在Modbus网络中的地址 |

ESP32 modbus RTU程序。 用arduino IDE开发的ESP32 modbus RTU slave程序。 不是库文件,直接用子程序编写,已注释了代码,容易看懂和移植。 已通讯连接成功。 程序已在多个项目上应用,不用怀疑:有气压检测设备,风机加热器控制箱,恒温控制箱,拉挤设备。 细心调试代码你可以快速成功的。

| | modbusDataSize | 101 | 设定Modbus数据库空间大小,决定可存储的数据量 |

| 系统参数 | bufferSize | 255 | 定义一帧数据的最大字节数,限制单帧数据传输长度 |

三、核心功能模块

(一)初始化模块

初始化函数setup()modbusRTU_INI()配合,完成硬件引脚与通讯端口的初始化配置,为程序运行做好准备。

  1. setup()函数:设置LED引脚为输出模式;调用modbusRTU_INI(&Serial2)初始化Modbus通讯端口,指定使用Serial2,对应ESP32的TX17和RX16引脚;同时初始化Serial端口(波特率19200bps),用于输出调试信息。
  2. modbusRTU_INI(HardwareSerial *SerialPort)函数:接收指定的串口端口参数,初始化该串口的波特率,并清空串口缓冲区,确保通讯开始时无残留数据干扰。

(二)主循环模块

loop()函数作为程序的主运行逻辑,持续执行Modbus从站任务与数据处理操作,具体流程如下:

  1. 记录循环开始时间starttime,通过Serial端口输出调试信息“Test Serial2”。
  2. 调用modbusRTU_slave()函数,执行Modbus RTU从站核心逻辑,处理主站指令。
  3. 计算循环耗时lasttime,并将其存入Modbus数据库的modbusData[8]地址;对modbusData[9](映射到Modbus地址4x0010)进行取反操作,用于状态切换。
  4. 遍历Modbus数据库前100个数据地址,实现数据自增;根据modbusData[9]的值控制LED灯亮灭,当值大于5000时点亮LED,否则熄灭。

(三)Modbus RTU从站核心模块

modbusRTU_slave()是程序的核心函数,负责接收主站指令、解析指令、处理数据,并生成响应信息,支持Modbus RTU的3种核心功能码:03(读取保持寄存器)、06(写入单个保持寄存器)、16(写入多个保持寄存器)。

  1. 通讯计时与数据接收:根据波特率计算1.5个字符的时间(波特率>19200时为750微秒,否则按公式计算),通过串口接收数据,当1.5个字符时间内无新数据时,判定一帧数据接收完成。
  2. 指令解析与校验:读取接收数据中的从站地址与功能码,判断从站地址是否匹配(当前从站号或广播地址0);计算接收数据的CRC校验值,与数据中的校验位对比,校验通过才进行后续指令处理。
  3. 功能码处理:
    - 功能码03(读取保持寄存器):读取主站指定的起始地址与数据长度,若数据长度超过125或地址超出数据库范围,返回“数据超过范围”错误;否则从Modbus数据库中提取对应数据,封装成响应帧并发送。
    - 功能码06(写入单个保持寄存器):解析主站指定的写入地址与数据,若地址超出数据库范围,返回错误;否则将数据写入Modbus数据库对应地址,并生成响应帧反馈写入结果。
    - 功能码16(写入多个保持寄存器):先校验数据长度是否匹配,再解析起始地址与数据长度,若地址超范围或数据长度超125,返回错误;否则批量将数据写入Modbus数据库,最后发送响应帧。
  4. 错误处理:当出现功能码不支持、数据地址超范围、数据长度不匹配、CRC校验失败等情况时,调用responseError()函数生成错误响应帧,反馈错误代码(0x01表示功能码不支持,0x02表示数据超范围,0x03表示数据长度不符或校验错误)。

(四)辅助功能模块

  1. calculateCRC(unsigned char* _regs, unsigned char arraySize):CRC校验函数,接收待校验数据数组与数组长度,通过特定算法计算16位CRC校验值,确保数据在传输过程中的完整性。
  2. responseError(unsigned char ID, unsigned char function, unsigned char wrongNumber):错误响应函数,根据传入的从站地址、功能码与错误代码,生成标准的Modbus错误响应帧,通过串口发送给主站,告知错误原因。

四、数据映射关系

Modbus数据库modbusData数组与Modbus地址存在固定映射关系,便于主站准确访问目标数据,具体规则如下:

  • modbusData数组下标从0开始,对应Modbus保持寄存器地址从4x0001开始。
  • 例如,modbusData[0]映射到Modbus地址4x0001,modbusData[6]映射到4x0007,modbusData[9]映射到4x0010,以此类推,数组下标比对应的Modbus地址编号小1。

五、实际应用场景

该程序凭借稳定的通讯性能与灵活的功能,已在多类工业设备中成功应用:

  • 气压检测设备:通过Modbus RTU通讯,将检测到的气压数据上传至主站,同时接收主站指令调整检测参数。
  • 风机加热器控制箱:接收主站的温度设定指令,控制加热器启停与风机转速,实时反馈设备运行状态(如当前温度、运行模式)至主站。
  • 恒温控制箱:基于主站设定的目标温度,结合内部温度检测数据,通过Modbus数据库更新控制指令,实现箱体温度的精准调控,并向主站传输温度数据与设备状态。
  • 拉挤设备:接收主站的生产参数指令(如拉挤速度、压力阈值),控制设备运行,同时将设备运行参数(如实时速度、压力值)存入Modbus数据库,供主站读取监控。

我可以根据你的需求,进一步补充代码在某类特定设备(如气压检测设备)中的具体应用流程,或者制作一份代码参数配置与功能模块的对应速查表,你需要吗?

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐