资讯动态

工业网关设计:Modbus转MQTT协议转换实践

发布时间:2026/8/10 9:01:42 来源:尧图企业网站定制
工业现场的现实工厂车间里70%以上的设备用的是Modbus协议。PLC、变频器、温控仪、电表、网关——全是Modbus RTURS485或Modbus TCP。但云平台只认MQTT和HTTP。你在云端搭建了漂亮的物联网平台数据看板、告警规则、设备管理全准备好了。然后到了工厂现场发现设备根本接不上。中间缺一个东西协议转换网关。把Modbus数据读出来转成MQTT消息发到云端。这就是工业互联网落地的第一道坎。协议转换网关架构[PLC/传感器] --Modbus RTU(RS485)-- [网关] --MQTT-- [云平台] | [本地存储断点续传]网关的核心功能Modbus轮询按配置定时读取设备寄存器数据格式转换Modbus寄存器值 → JSONMQTT上报转成JSON通过4G/WiFi发到云端断点续传网络断了先存本地恢复后补传边缘计算简单规则引擎温度80度直接报警不等云端硬件方案我们虎王科技在工业项目中用的网关方案方案主控通信成本适用场景方案AESP32WiFi4G模组~80元小型设备20个测点方案BSTM32F44G模组~120元工业级-40~85度方案CLinux工控机以太网4G~500元复杂场景多协议方案B是最常用的。STM32F407 EC25 4G模组 RS485芯片工业级温度范围稳定可靠。Modbus RTU读取实践寄存器配置表假设我们有一个温湿度控制器Modbus寄存器表如下地址功能码数据类型描述0x000003uint16当前温度x100x000103uint16当前湿度x100x000203uint16设定温度0x000303uint16运行状态bit0运行, bit1告警0x001006uint16设定温度可写STM32读取Modbus的核心代码// modbus_rtu.c - Modbus RTU主站实现#defineMODBUS_ADDR0x01// 从站地址#defineMODBUS_FC_READ0x03// 功能码读保持寄存器#defineMODBUS_REG_TEMP0x0000// 温度寄存器地址#defineMODBUS_REG_HUMI0x0001// 湿度寄存器地址// 构建Modbus请求帧intbuild_read_request(uint8_t*buf,uint8_tslave,uint16_treg,uint16_tcount){buf[0]slave;// 从站地址buf[1]MODBUS_FC_READ;// 功能码buf[2](reg8)0xFF;// 寄存器地址高字节buf[3]reg0xFF;// 寄存器地址低字节buf[4](count8)0xFF;// 读取数量高字节buf[5]count0xFF;// 读取数量低字节// CRC16校验uint16_tcrccrc16(buf,6);buf[6]crc0xFF;// CRC低字节buf[7](crc8)0xFF;// CRC高字节return8;// 请求帧长度}// 解析Modbus响应帧intparse_read_response(uint8_t*buf,intlen,uint16_t*values,intmax_count){if(len5)return-1;if(buf[0]!MODBUS_ADDR)return-1;if(buf[1]!MODBUS_FC_READ)return-1;uint8_tbyte_countbuf[2];intreg_countbyte_count/2;if(reg_countmax_count)return-1;// CRC校验uint16_tcrc_calccrc16(buf,len-2);uint16_tcrc_recvbuf[len-2]|(buf[len-1]8);if(crc_calc!crc_recv)return-2;for(inti0;ireg_count;i){values[i](buf[3i*2]8)|buf[4i*2];}returnreg_count;}CRC16实现Modbus RTU的CRC16是标准CRC-16/MODBUS算法uint16_tcrc16(uint8_t*data,intlen){uint16_tcrc0xFFFF;for(inti0;ilen;i){crc^data[i];for(intj0;j8;j){if(crc0x0001)crc(crc1)^0xA001;elsecrc1;}}returncrc;}数据转换Modbus到MQTT读到的寄存器原始值需要转成有意义的JSON// 读取温湿度uint16_tregs[2];intretmodbus_read(MODBUS_ADDR,0x0000,2,regs);if(ret0){floattempregs[0]/10.0f;// 温度除以10floathumiregs[1]/10.0f;// 湿度除以10// 构建JSONcharjson[256];snprintf(json,sizeof(json),{\device_id\:\GW001\,\temp\:%.1f,\humi\:%.1f,\ts\:%ld},temp,humi,time(NULL));// 通过4G模组MQTT发布mqtt_publish(devices/GW001/telemetry,json);}最终云平台收到的消息{device_id:GW001,temp:25.3,humi:68.5,ts:1723113600}Modbus通信的几个坑坑1RS485总线冲突多个从站设备挂在同一条RS485总线上如果两个设备同时发送数据总线会冲突。解决Modbus是主从协议从站只在被问的时候才回答。确保你的代码不会并发查询多个从站。轮询一个等回答或超时再问下一个。坑2寄存器地址偏移有些设备的Modbus地址从0开始有些从1开始。文档上写地址40001实际读取时要用0x0000。建议拿到设备文档后先用手持Modbus调试器读几个地址验证。不要直接写代码否则调试时分不清是代码bug还是地址错误。坑34G模组MQTT断连4G网络在工厂车间信号不稳定MQTT连接偶尔断。如果不处理数据就丢了。解决本地SPI Flash缓存。网络断了把数据存Flash网络恢复后按时间戳补传。#defineMAX_CACHE100typedefstruct{uint32_ttimestamp;floattemp;floathumi;}cache_entry_t;cache_entry_tcache[MAX_CACHE];intcache_count0;// 断网时缓存voidcache_data(floattemp,floathumi){if(cache_countMAX_CACHE){cache[cache_count].timestamptime(NULL);cache[cache_count].temptemp;cache[cache_count].humihumi;cache_count;}// 满了就覆盖最旧的}// 恢复后补传voidflush_cache(){for(inti0;icache_count;i){charjson[256];snprintf(json,sizeof(json),{\device_id\:\GW001\,\temp\:%.1f,\humi\:%.1f,\ts\:%ld},cache[i].temp,cache[i].humi,cache[i].timestamp);mqtt_publish(devices/GW001/telemetry,json);}cache_count0;}批量配置方案工厂里50台网关一台台手动配置不现实。我们的方案配置文件通过MQTT下发云平台发配置消息网关收到后更新本地配置设备模板预置常见设备的Modbus寄存器表模板选模板即可自动发现网关上电后扫描RS485总线上的设备地址自动识别设备类型配置消息格式{config_id:factory_A_line1,devices:[{type:temp_controller,slave_addr:1,baudrate:9600,registers:[{addr:0,type:uint16,scale:0.1,name:temperature},{addr:1,type:uint16,scale:0.1,name:humidity}],interval:5}]}实际项目数据虎王科技在某个工厂的温湿度监控项目网关数量12台每台网关连接设备8台共96台温控器Modbus轮询间隔5秒MQTT上报频率30秒聚合5次轮询的数据一次上报月平均数据完整率99.2%4G月流量每台网关约50MB总结工业物联网落地的核心环节就是协议转换。Modbus到MQTT看似简单但实际部署中RS485总线、4G网络稳定性、寄存器地址映射等细节问题很多。关键经验Modbus轮询要可靠4G断网要补传批量配置要自动化。这三件事做对了工业网关方案就能落地。沧州虎王科技专注物联网软硬件开发、通信设备、嵌入式系统与设备管理平台。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价