1. 项目概述与背景
工业上位机开发一直是自动化领域的关键环节,而C#凭借其强大的Windows平台兼容性和丰富的类库支持,成为上位机开发的主流选择之一。这个项目以温湿度监控为切入点,带大家从零开始搭建完整的工业上位机系统。
我在2015年第一次接触工业上位机开发时,发现市面上大多数教程要么过于理论化,要么直接跳过了硬件连接等基础环节。这个教程将采用"硬件连接→通信协议→界面设计→数据处理"的递进式教学,确保每个环节都有可落地的实现方案。
2. 硬件准备与连接
2.1 硬件选型建议
对于工业级温湿度监控,推荐以下硬件配置:
- 传感器:SHT30数字温湿度传感器(I2C接口,±2%RH精度)
- 通信模块:USB转485转换器(推荐FTDI芯片方案)
- 工控机:任何支持Windows系统的设备(建议至少4GB内存)
注意:工业现场优先选择带隔离保护的485通信模块,防止地环路干扰
2.2 硬件连接示意图
plaintext复制[SHT30传感器] <-I2C-> [485转换器] <-USB-> [工控机]
具体接线方法:
- 将SHT30的VCC接5V电源
- SDA接转换器A端
- SCL接转换器B端
- 连接转换器USB到工控机
3. 开发环境搭建
3.1 软件安装清单
必须安装的组件:
- Visual Studio 2019/2022(社区版即可)
- .NET Framework 4.7.2+
- Modbus库(推荐NModbus4)
3.2 项目创建步骤
- 新建WPF应用项目
- 通过NuGet添加以下包:
- NModbus4
- LiveCharts.Wpf
- Newtonsoft.Json
4. 通信协议实现
4.1 Modbus RTU协议封装
csharp复制public class ModbusRTUClient
{
private IModbusSerialMaster master;
private SerialPort port;
public void Connect(string portName, int baudRate)
{
port = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
master = ModbusSerialMaster.CreateRtu(port);
port.Open();
}
public float ReadTemperature(byte slaveId)
{
ushort[] registers = master.ReadInputRegisters(slaveId, 0, 2);
return (registers[0] << 16 | registers[1]) / 100.0f;
}
}
4.2 数据采集线程设计
csharp复制private void StartMonitoring()
{
Thread monitorThread = new Thread(() =>
{
while (isRunning)
{
try {
float temp = client.ReadTemperature(0x01);
Dispatcher.Invoke(() => UpdateUI(temp));
Thread.Sleep(1000);
} catch {...}
}
}) { IsBackground = true };
monitorThread.Start();
}
5. 上位机界面开发
5.1 实时数据显示控件
使用LiveCharts实现动态曲线:
xml复制<lvc:CartesianChart Series="{Binding SeriesCollection}"
AnimationsSpeed="0:0:0.1">
<lvc:CartesianChart.AxisX>
<lvc:Axis LabelFormatter="{Binding DateTimeFormatter}"/>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
5.2 报警功能实现
csharp复制private void CheckAlarm(float value)
{
if (value > upperLimit)
{
PlaySound("alarm.wav");
LogAlarm("温度过高:" + value);
}
}
6. 数据存储方案
6.1 SQLite数据库设计
sql复制CREATE TABLE HistoryData (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
Temperature REAL NOT NULL,
Humidity REAL NOT NULL
);
6.2 使用EF Core操作数据库
csharp复制public class DataContext : DbContext
{
public DbSet<HistoryData> HistoryData { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=monitor.db");
}
7. 工业现场部署要点
7.1 安装包制作
使用Inno Setup制作安装程序时需包含:
- .NET Framework运行环境检测
- 串口驱动自动安装
- 开机自启动配置
7.2 现场调试技巧
- 使用串口调试助手验证硬件通信
- 修改注册表提高串口缓冲区大小:
reg复制[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Serial] "RxBuffer"=dword:00004000
8. 常见问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 读取数据为0 | 接线错误 | 检查A/B线是否接反 |
| 通信超时 | 波特率不匹配 | 确认设备与软件波特率一致 |
| 数据跳变 | 电源干扰 | 增加磁环或改用隔离电源 |
9. 性能优化建议
- 采用双缓冲队列处理数据:
csharp复制ConcurrentQueue<float> dataQueue = new ConcurrentQueue<float>();
- 使用Stopwatch精确控制采集间隔:
csharp复制Stopwatch sw = Stopwatch.StartNew();
while (true) {
if (sw.ElapsedMilliseconds >= interval) {
sw.Restart();
// 采集代码
}
}
10. 项目扩展方向
- 通过OPC UA实现与PLC通信
- 添加Web远程监控功能(SignalR)
- 集成机器学习预测算法(ML.NET)
我在实际项目中发现,工业现场的电磁干扰往往比预想的严重。建议在485通信线上加装磁环,并在软件中加入数据校验机制。一个简单的做法是对连续3次采集结果进行中值滤波,可以有效消除瞬时干扰。