一个Modbus-TCP传感器数据传输方案

需求
lora接收最多200个节点的传感器数据,每个传感器数据16位。通过modbus-tcp上传至服务器

基于需求:提供详细的Modbus-TCP协议方案:

1. 数据包大小分析

总数据量计算:

  • 采集时间:4字节 (int32)
  • 200个传感器 × (1字节ID + 2字节数据) = 600字节
  • 总计:604字节

Modbus-TCP限制:

  • Modbus PDU最大长度:253字节
  • 功能码03/04单次最大读取寄存器数:125个寄存器(250字节数据)
  • 604字节数据必须分包传输

2. 寄存器映射方案

2.1 寄存器分配

地址范围 内容 长度 说明
40001-40002 采集时间戳 2寄存器 Unix时间戳
40003-40004 数据包信息 2寄存器 包序号、总包数等
40005-400132 传感器数据块1 128寄存器 第1包数据
40101-40128 传感器数据块2 128寄存器 第2包数据
40201-40228 传感器数据块3 128寄存器 第3包数据
40301-40328 传感器数据块4 128寄存器 第4包数据
40401-40420 传感器数据块5 20寄存器 第5包数据

2.2 数据包分包方案

共分5包传输:

  • 每包:128个寄存器(256字节数据)
  • 前4包:各128寄存器
  • 第5包:20寄存器

3. 寄存器详细定义

3.1 基本信息寄存器 (40001-40004)

地址 内容 数据类型 说明
40001 时间戳高16位 uint16 采集时间的高位
40002 时间戳低16位 uint16 采集时间的低位
40003 包控制信息 uint16 比特位定义见下表
40004 传感器总数 uint16 实际传感器数量(1-200)

包控制信息(40003)比特位定义:

复制代码
比特15-8: 保留
比特7-4: 总包数 (固定为5)
比特3-0: 当前包序号 (0-4)

3.2 数据包寄存器结构

每包数据格式:

复制代码
寄存器N+0: [传感器ID1][数据1高8位]
寄存器N+1: [数据1低8位][传感器ID2]  
寄存器N+2: [数据2高8位][数据2低8位]
寄存器N+3: [传感器ID3][数据3高8位]
...

数据打包示例:

cpp 复制代码
// 每2个寄存器存储3个传感器数据
寄存器布局:
[ID1][Data1_H]  [Data1_L][ID2]  [Data2_H][Data2_L]  [ID3][Data3_H] ...

4. Modbus-TCP通信协议

4.1 Master请求命令定义

读取基本信息:

复制代码
事务标识符: 0x0001
协议标识符: 0x0000
长度: 0x0006
单元标识符: 0x01
功能码: 0x03 (读保持寄存器)
起始地址: 0x0000 (40001)
寄存器数量: 0x0004 (4个寄存器)

读取数据包n:

复制代码
事务标识符: 0x0002
协议标识符: 0x0000  
长度: 0x0006
单元标识符: 0x01
功能码: 0x03
起始地址: 0x0004 + (n-1)*128 (对应40005,40101...)
寄存器数量: 0x0080 (128寄存器) 或 0x0014 (20寄存器)

4.2 Slave响应数据定义

基本信息响应:

复制代码
事务标识符: 0x0001
协议标识符: 0x0000
长度: 0x000B
单元标识符: 0x01
功能码: 0x03
字节数: 0x08
数据: [时间戳高][时间戳低][控制字][传感器数]

数据包响应:

复制代码
事务标识符: 0x0002
协议标识符: 0x0000
长度: 0x0107 (对于128寄存器)
单元标识符: 0x01  
功能码: 0x03
字节数: 0x0100 (256字节)
数据: [传感器数据块...]

5. 通信流程说明

5.1 完整数据读取流程

复制代码
Master端流程:
1. 建立TCP连接
2. 发送读取基本信息请求(40001-40004)
3. 解析响应,获取时间戳和传感器总数
4. 循环发送5个数据包读取请求
5. 重组并解析所有传感器数据
6. 关闭TCP连接

Slave端流程:
1. 监听TCP连接
2. 接收Master请求
3. 根据地址映射返回对应数据
4. 维持连接直到所有数据传送完成

5.2 具体实现示例

Master请求序列:

python 复制代码
# 1. 读取基本信息
request1 = "01 03 00 00 00 04"  # 40001-40004

# 2. 读取5个数据包  
request2 = "01 03 00 04 00 80"  # 40005-40132 (包1)
request3 = "01 03 01 00 00 80"  # 40101-40228 (包2) 
request4 = "01 03 02 00 00 80"  # 40201-40328 (包3)
request5 = "01 03 03 00 00 80"  # 40301-40428 (包4)
request6 = "01 03 04 00 00 14"  # 40401-40420 (包5)

6. 数据解析算法

cpp 复制代码
// 数据重组伪代码
struct SensorData {
    uint8_t id;
    int16_t value;
};

vector<SensorData> parseSensorData(const vector<uint16_t>& allRegisters) {
    vector<SensorData> result;
    
    // 跳过基本信息寄存器(前4个)
    int regIndex = 4;
    
    for(int i = 0; i < 200; i += 3) {
        // 每3个传感器占用4个寄存器
        if(regIndex + 3 >= allRegisters.size()) break;
        
        // 解析第1个传感器
        uint8_t id1 = allRegisters[regIndex] >> 8;
        int16_t value1 = (allRegisters[regIndex] & 0xFF) << 8 | 
                        (allRegisters[regIndex+1] >> 8);
        result.push_back({id1, value1});
        
        // 解析第2个传感器  
        uint8_t id2 = allRegisters[regIndex+1] & 0xFF;
        int16_t value2 = allRegisters[regIndex+2];
        result.push_back({id2, value2});
        
        // 解析第3个传感器
        uint8_t id3 = allRegisters[regIndex+3] >> 8;
        int16_t value3 = (allRegisters[regIndex+3] & 0xFF) << 8 |
                        (allRegisters[regIndex+4] >> 8);
        result.push_back({id3, value3});
        
        regIndex += 4;
    }
    
    return result;
}

7. 注意事项

  1. 超时处理: 建议设置合理的读写超时(如30秒)
  2. 错误重试: 实现重试机制,单包失败可重试该包
  3. 数据一致性: 使用时间戳确保多包数据属于同一采集周期
  4. 连接管理: 长时间连接建议实现心跳机制
  5. 性能优化: 可根据网络状况调整包大小和并发请求数

这个方案确保了在Modbus-TCP协议限制内高效可靠地传输所有传感器数据。

相关推荐
深度学习实战训练营6 小时前
MemNet:一种用于图像恢复的持久性存储网络
网络·人工智能
TiAmo8086 小时前
ip生产区
服务器·网络·tcp/ip
文火冰糖的硅基工坊8 小时前
[嵌入式系统-146]:五次工业革命对应的机器人形态的演进、主要功能的演进以及操作系统的演进
前端·网络·人工智能·嵌入式硬件·机器人
2301_793167998 小时前
网络基础总结
运维·网络·hcia
西***63478 小时前
从信号处理到智能协同:高清混合矩阵全链路技术拆解,分布式系统十大趋势抢先看
网络·分布式·矩阵
小鹏linux8 小时前
用wireshark进行手机app抓包教程-2025最新
网络·测试工具·wireshark
alex1008 小时前
API安全漏洞详解:Broken Function Level Authorization (BFLA) 的威胁与防御
网络·安全
夜白宋9 小时前
【网络代理相关知识】
网络
bkspiderx10 小时前
Linux网络与路由配置完全指南
linux·运维·网络·c++