铁路列车车辆监控系统设计方案(双串口PC机实现)
一、系统概述
1.1 系统定位
铁路列车车辆监控系统是基于PC机的双串口通信平台,用于实时采集列车车辆运行状态数据、与地面监控中心交互,并实现异常状态报警与控制。系统通过两个独立串口分别连接车载数据采集模块和地面监控终端,满足铁路环境下多源数据融合与远程监控需求。
1.2 核心需求
- 双串口独立通信:PC机需同时支持两个串行端口(COM1/COM2),分别处理不同通信任务
- 实时数据采集:通过COM1接收车载传感器数据(速度、位置、温度、压力等)
- 远程监控交互:通过COM2与地面站通信,接收控制指令并发送报警信息
- 可靠数据传输:抗电磁干扰、断线重连、数据校验(CRC16)
- 直观监控界面:实时数据显示、历史曲线、报警记录、设备状态指示
二、系统架构设计
2.1 硬件组成
| 设备/模块 | 功能描述 | 通信接口 | 关键参数 |
|---|---|---|---|
| PC机 | 监控中心,运行监控软件,处理双串口数据 | 2×RS232/USB转串口 | 波特率:9600~115200bps,8N1 |
| 车载数据采集模块 | 集成STM32/Arduino,连接车辆传感器(速度、位置、温度、压力、振动等) | 串口(COM1) | 自定义协议,帧周期100ms~1s |
| 地面监控终端 | 地面站PC或工控机,发送控制指令(如紧急制动、参数设置),接收报警信息 | 串口(COM2) | Modbus RTU协议或自定义协议 |
| 传感器组 | 速度传感器(光电/霍尔)、GPS定位模块、温度传感器(PT100)、压力传感器 | 模拟/数字接口 | 精度:速度±0.1km/h,温度±0.5℃ |
| 报警装置 | 声光报警器、短信模块(可选) | 数字I/O | 支持异常状态分级报警(预警/紧急) |
2.2 软件架构
graph TD
A[PC监控软件] --> B[串口1通信模块]
A --> C[串口2通信模块]
A --> D[数据处理中心]
A --> E[监控显示界面]
A --> F[数据存储模块]
A --> G[报警处理模块]
B -->|接收| H[车载数据采集模块]
C -->|通信| I[地面监控终端]
D -->|解析/校验| B
D -->|协议转换| C
E -->|显示| D
F -->|存储| D
G -->|触发| E
G -->|控制| B
三、双串口通信实现
3.1 串口分配与协议设计
| 串口 | 连接对象 | 通信方向 | 协议类型 | 数据内容 | 波特率 | 周期 |
|---|---|---|---|---|---|---|
| COM1 | 车载数据采集模块 | PC←车载(接收) | 自定义帧协议 | 帧头(0xAA55)+设备ID(1B)+数据长度(1B)+数据(速度2B+位置4B+温度2B+压力2B+振动2B)+CRC16(2B)+帧尾(0x0D0A) | 19200bps | 500ms |
| COM2 | 地面监控终端 | PC↔地面(双向) | Modbus RTU | 读保持寄存器(0x03):车辆状态、故障代码;写单个寄存器(0x06):控制指令(如0x01=紧急制动) | 9600bps | 按需交互 |
3.2 自定义帧协议(COM1)
帧结构(共16字节)
| 字段 | 字节数 | 说明 |
|---|---|---|
| 帧头 | 2 | 固定0xAA55(大端模式) |
| 设备ID | 1 | 车载模块编号(0x01~0xFF) |
| 数据长度 | 1 | 数据区字节数(固定0x0A=10B) |
| 速度 | 2 | 单位0.1km/h,范围01000(0x00000x03E8) |
| 位置 | 4 | GPS经纬度(经度2B+纬度2B,单位0.0001°,范围-180~180) |
| 温度 | 2 | 单位0.1℃,范围-400850(0xFE700x0352) |
| 压力 | 2 | 单位kPa,范围01000(0x00000x03E8) |
| 振动 | 2 | 单位m/s²,范围0200(0x00000x00C8) |
| CRC16 | 2 | 校验范围:设备ID~振动(多项式0x8005,初始值0xFFFF) |
| 帧尾 | 2 | 固定0x0D0A(回车换行) |
3.3 Modbus RTU协议(COM2)
关键功能码
| 功能码 | 名称 | 用途 | 数据格式 |
|---|---|---|---|
| 0x03 | 读保持寄存器 | 地面站读取车辆状态(如速度、故障代码) | 请求:从机地址(1B)+0x03+起始地址(2B)+寄存器数(2B);响应:数据(n×2B) |
| 0x06 | 写单个寄存器 | 地面站发送控制指令(如紧急制动) | 请求:从机地址(1B)+0x06+寄存器地址(2B)+数据(2B) |
| 0x10 | 写多个寄存器 | 地面站批量设置参数(如报警阈值) | 请求:从机地址(1B)+0x10+起始地址(2B)+寄存器数(2B)+字节数(1B)+数据(n×2B) |
四、PC监控软件实现(C#示例)
4.1 开发环境
- 语言:C#(.NET Framework 4.8)
- 开发工具:Visual Studio 2022
- 核心库:
System.IO.Ports(串口通信)、LiveCharts(实时曲线)、Sqlite(数据存储)
4.2 关键代码模块
4.2.1 双串口初始化
using System.IO.Ports;
public class SerialPortManager
{
public SerialPort Com1 { get; set; } // 连接车载模块
public SerialPort Com2 { get; set; } // 连接地面终端
public void InitPorts()
{
// COM1配置(车载数据采集)
Com1 = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);
Com1.DataReceived += Com1_DataReceived; // 数据接收事件
Com1.Open();
// COM2配置(地面通信)
Com2 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
Com2.DataReceived += Com2_DataReceived;
Com2.Open();
}
// COM1数据接收(车载数据)
private void Com1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[Com1.BytesToRead];
Com1.Read(buffer, 0, buffer.Length);
ProcessCarData(buffer); // 解析车载数据
}
// COM2数据接收(地面指令)
private void Com2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[Com2.BytesToRead];
Com2.Read(buffer, 0, buffer.Length);
ProcessGroundCommand(buffer); // 解析地面指令
}
}
4.2.2 车载数据解析(自定义协议)
public class CarDataParser
{
public struct CarData
{
public byte DeviceId;
public float Speed; // km/h
public float Longitude; // °
public float Latitude; // °
public float Temperature; // ℃
public float Pressure; // kPa
public float Vibration; // m/s²
}
public static CarData Parse(byte[] frame)
{
if (frame.Length != 16 || frame[0] != 0xAA || frame[1] != 0x55)
throw new Exception("无效帧头");
// 校验CRC16
ushort crcCalculated = CalculateCRC(frame, 2, 12); // 校验设备ID~振动(12字节)
ushort crcReceived = (ushort)((frame[14] << 8) | frame[15]);
if (crcCalculated != crcReceived)
throw new Exception("CRC校验失败");
CarData data = new CarData();
data.DeviceId = frame[2];
data.Speed = BitConverter.ToUInt16(frame, 4) / 10.0f; // 2字节速度
data.Longitude = (BitConverter.ToInt16(frame, 6) / 10000.0f); // 4字节经度(2B+2B)
data.Latitude = (BitConverter.ToInt16(frame, 8) / 10000.0f); // 4字节纬度
data.Temperature = BitConverter.ToInt16(frame, 10) / 10.0f; // 2字节温度
data.Pressure = BitConverter.ToUInt16(frame, 12) / 10.0f; // 2字节压力
data.Vibration = BitConverter.ToUInt16(frame, 14) / 10.0f; // 2字节振动(注:原帧结构需调整,此处为示例)
return data;
}
// CRC16计算(多项式0x8005)
private static ushort CalculateCRC(byte[] data, int offset, int length)
{
ushort crc = 0xFFFF;
for (int i = 0; i < length; i++)
{
crc ^= (ushort)(data[offset + i] << 8);
for (int j = 0; j < 8; j++)
{
if ((crc & 0x8000) != 0)
crc = (ushort)((crc << 1) ^ 0x8005);
else
crc <<= 1;
}
}
return crc;
}
}
4.2.3 地面指令处理(Modbus RTU)
public class ModbusProcessor
{
private SerialPort Com2; // 地面通信串口
public ModbusProcessor(SerialPort com2) => Com2 = com2;
// 发送控制指令(如紧急制动:寄存器0x0001=0x0001)
public void SendEmergencyStop()
{
byte[] command = {
0x01, // 从机地址(地面站)
0x06, // 功能码(写单个寄存器)
0x00, 0x01, // 寄存器地址0x0001
0x00, 0x01, // 数据0x0001(紧急制动)
0x00, 0x00 // CRC16占位(需计算)
};
ushort crc = CalculateModbusCRC(command, 0, 6);
command[6] = (byte)(crc & 0xFF);
command[7] = (byte)(crc >> 8);
Com2.Write(command, 0, 8);
}
// 解析地面读指令(0x03)
public void ProcessReadCommand(byte[] request)
{
if (request[1] != 0x03) return;
byte slaveAddr = request[0];
ushort startAddr = (ushort)((request[2] << 8) | request[3]);
ushort regCount = (ushort)((request[4] << 8) | request[5]);
// 构造响应(示例:返回速度、温度)
byte[] response = new byte[3 + 2 * regCount];
response[0] = slaveAddr;
response[1] = 0x03;
response[2] = (byte)(2 * regCount);
// 填充数据(速度0x0001=123.4km/h → 0x04D2,温度0x0002=25.5℃ → 0x00FF)
response[3] = 0xD2; response[4] = 0x04; // 速度
response[5] = 0xFF; response[6] = 0x00; // 温度
// 计算CRC
ushort crc = CalculateModbusCRC(response, 0, 7);
response[7] = (byte)(crc & 0xFF);
response[8] = (byte)(crc >> 8);
Com2.Write(response, 0, 9);
}
// Modbus CRC16计算
private ushort CalculateModbusCRC(byte[] data, int offset, int length)
{
ushort crc = 0xFFFF;
for (int i = 0; i < length; i++)
{
crc ^= data[offset + i];
for (int j = 0; j < 8; j++)
{
if ((crc & 0x0001) != 0)
crc = (ushort)((crc >> 1) ^ 0xA001);
else
crc >>= 1;
}
}
return crc;
}
}
参考代码 铁路列车车辆监控系统本系统要求PC机有两个串行通讯串口 www.youwenfan.com/contentcnt/124055.html
五、系统功能实现
5.1 实时监控界面(C# WinForms)
- 数据显示区:实时显示速度、位置、温度、压力、振动等参数(数字+仪表盘)
- 地图显示区:基于GPS数据在百度/高德地图上显示列车位置(需API支持)
- 历史曲线区:用LiveCharts绘制速度、温度变化趋势(支持时间范围选择)
- 报警列表:显示异常状态(如温度超限、压力异常),支持声光报警(调用
System.Media播放警报音) - 控制按钮:手动发送控制指令(如紧急制动、参数复位)
5.2 数据存储与查询
- 存储格式:SQLite数据库(表结构:
TimeDATETIME,DeviceIdINT,SpeedREAL,LongitudeREAL,LatitudeREAL,TemperatureREAL,PressureREAL,VibrationREAL,AlarmFlagBOOL) - 存储策略:每500ms存储一次COM1数据,异常数据(如报警)实时存储
- 查询功能:按时间范围、设备ID、参数类型查询历史数据,支持导出Excel
5.3 报警与故障诊断
-
报警规则:
- 速度超限:>120km/h(预警),>160km/h(紧急)
- 温度超限:>80℃(预警),>100℃(紧急)
- 压力异常:<50kPa或>1000kPa(紧急)
-
故障诊断:根据多参数关联分析(如速度突降+振动增大→轮对故障)
六、系统测试与优化
6.1 测试方案
| 测试项 | 方法 | 预期结果 |
|---|---|---|
| 串口通信稳定性 | 连续24小时收发数据,记录丢包率、错包率 | 丢包率<0.1%,错包率<0.01% |
| 数据解析正确性 | 用模拟器发送自定义帧,验证解析后数值与发送值一致 | 解析误差<0.1% |
| 报警响应时间 | 模拟异常数据(如温度=101℃),记录从数据接收到报警弹出的时间 | 响应时间<500ms |
| 断线重连 | 拔插串口线,验证软件自动检测并重新连接 | 重连时间<3s,无数据丢失 |
6.2 优化措施
- 抗干扰设计:串口线使用屏蔽双绞线,PC机接地,波特率降为9600bps(强干扰环境)
- 数据压缩:对历史数据采用差分存储(仅存变化量),减少存储空间
- 多线程处理:COM1/COM2数据接收、界面刷新、数据存储分别用独立线程,避免卡顿
- 断线缓存:串口断开时,车载数据暂存于内存环形缓冲区(容量10MB),重连后补发
七、系统部署与维护
7.1 硬件部署
- PC机:工业级工控机(防尘、宽温-20~60℃),配置双串口(如研华UNO-2170)
- 车载模块:防水外壳,安装在车辆电气柜内,通过CAN总线连接传感器
- 线缆:RS232串口线(长度<15m)或光纤(长距离),避免与动力线并行
7.2 软件维护
- 固件升级:通过COM1远程更新车载模块固件(需设计Bootloader)
- 日志管理:记录系统运行日志(串口状态、错误代码),支持按日期查询
- 参数配置:提供界面配置串口参数、报警阈值、存储周期等
八、总结
本系统通过PC机双串口实现了铁路列车车辆的实时监控,具备以下特点:
- 双串口独立通信:COM1专注车载数据采集,COM2负责地面交互,分工明确
- 可靠数据传输:自定义协议+CRC校验、Modbus RTU标准协议,确保数据正确性
- 直观监控界面:实时数据显示、地图定位、历史曲线、分级报警,满足运维需求
- 扩展性强:支持传感器扩展(如振动、电压)、协议扩展(如TCP/IP网关)