1. 项目背景与价值解析
在工业自动化领域,三菱和西门子PLC作为两大主流品牌,经常需要在一个系统中协同工作。但两者的通讯协议差异就像两个说着不同方言的人交流——虽然都是工业设备,却存在明显的语言障碍。我在某汽车零部件生产线改造项目中,就遇到了需要同时读取三菱Q系列PLC和西门子S7-1200数据的场景。
传统方案要么采用昂贵的OPC服务器,要么通过中间硬件转换,成本动辄上万元。而用VB.NET直接开发通讯程序,不仅节省了90%的硬件成本,还实现了毫秒级的数据交互。这个方案特别适合中小型自动化项目,或是需要快速验证通讯逻辑的调试场景。
2. 环境准备与工具选型
2.1 硬件连接方案
典型接线方式有两种选择:
-
方案A:工控机安装双网卡
- 网卡1:连接三菱PLC(通常用192.168.0.x网段)
- 网卡2:连接西门子PLC(常用192.168.1.x网段)
- 优势:物理隔离,避免IP冲突
- 成本:约300-500元/张工业网卡
-
方案B:单网卡+VLAN交换机
- 使用支持802.1Q的工业交换机划分VLAN
- 单网卡配置多个虚拟接口
- 优势:节省硬件成本
- 风险:需要网络专业知识配置
提示:三菱FX5U等新款PLC已支持以太网通讯,老款FX系列需加装FX3U-ENET适配器(约1500元)
2.2 软件环境搭建
开发环境需要特别注意组件兼容性:
vb复制' 必需组件清单
1. Visual Studio 2019/2022 (社区版即可)
2. 三菱MX Component 4.0+ (提供ActUtlTypeLib控件)
3. 西门子S7.NET Plus (NuGet包)
4. Sharp7 (备用通讯库,NuGet安装)
安装MX Component时有个坑要注意:默认安装路径包含空格,会导致VB.NET引用失败。建议自定义安装到"C:\MELSEC"这样的无空格路径。
3. 双协议通讯核心实现
3.1 三菱PLC通讯模块
三菱采用Melsec协议,关键是要正确设置ActSupport控件属性:
vb复制Dim melsec As New ACTMULTILib.ActMLUtlType
With melsec
.ActLogicalStationNumber = 1 ' 站号
.ActPassword = "" ' 多数情况留空
.ActTargetPLC = "QJ71E71" ' 根据实际型号修改
End With
' 读取D100开始的10个寄存器
Dim values(9) As Integer
melsec.ReadDeviceBlock("D100", 10, values(0))
常见错误处理:
- ErrorCode 0x1001:检查IP是否能ping通
- ErrorCode 0x1301:确认PLC型号字符串拼写正确
- ErrorCode 0x1401:站号冲突,检查GX Works2中的设置
3.2 西门子PLC通讯模块
西门子S7协议需要先建立TCP连接:
vb复制Imports S7.Net
Dim plc As New Plc(CpuType.S71200, "192.168.1.10", 0, 1)
plc.Open()
' 读取DB1.DBW20开始的5个WORD
Dim result = plc.Read("DB1.DBW20", DataType.DataBlock, 5)
If result Is Nothing Then
Throw New Exception("读取失败")
End If
Dim values As UShort() = CType(result, UShort())
实测发现:S7.NET库在读取BOOL数组时存在字节对齐问题,建议用Sharp7库处理位数据
4. 数据同步与冲突处理
4.1 双线程通讯架构
为避免界面卡顿,必须采用多线程设计:
vb复制Private Sub StartPolling()
Dim t1 As New Thread(AddressOf PollMitsubishi)
Dim t2 As New Thread(AddressOf PollSiemens)
t1.IsBackground = True
t2.IsBackground = True
t1.Start()
t2.Start()
End Sub
Private Sub PollMitsubishi()
While True
' 三菱数据采集代码
Thread.Sleep(100) ' 100ms周期
End While
End Sub
4.2 共享数据安全访问
使用SyncLock避免数据竞争:
vb复制Private Shared lockObj As New Object()
Private Shared siemensData As Dictionary(Of String, Object)
Private Shared mitsubishiData As Dictionary(Of String, Object)
Public Shared Function GetCombinedData() As Dictionary(Of String, Object)
SyncLock lockObj
' 合并两个字典
Return New Dictionary(Of String, Object)(siemensData) _
.Concat(mitsubishiData) _
.ToDictionary(Function(p) p.Key, Function(p) p.Value)
End SyncLock
End Function
5. 实战案例:注塑机监控系统
某项目需要同时获取:
- 三菱PLC:模具温度(D100-D103)
- 西门子PLC:液压压力(DB10.DBD20)
最终实现方案:
- 创建数据模型类
vb复制Public Class InjectionData
Public Property MoldTemp1 As Single
Public Property MoldTemp2 As Single
Public Property HydraulicPress As Single
End Class
- 编写转换方法
vb复制Private Function ConvertData() As InjectionData
Dim data As New InjectionData
data.MoldTemp1 = mitsubishiData("D100") / 10.0 ' 三菱数据需除10
data.HydraulicPress = BitConverter.ToSingle(
BitConverter.GetBytes(CType(siemensData("DB10.DBD20"), UInt32)), 0)
Return data
End Function
- 异常处理增强
vb复制Try
' 通讯代码
Catch ex As S7.Net.PlcException When ex.ErrorCode = 0x0001
Logger.Write($"西门子连接超时,尝试重连...")
plc.Close()
Thread.Sleep(1000)
plc.Open()
Catch ex As Exception
Logger.Write($"严重错误:{ex.Message}")
Environment.Exit(1)
End Try
6. 性能优化技巧
通过实测对比发现:
- 批量读取比单点读取快5-8倍
- 合理设置通讯周期可降低CPU负载
优化后的读取策略:
vb复制' 三菱批量读取(一次读20个寄存器)
melsec.ReadDeviceBlock("D100", 20, values(0))
' 西门子使用多变量读取
Dim vars As New List(Of Variable)
vars.Add(New Variable("DB1.DBW0"))
vars.Add(New Variable("DB1.DBW2"))
plc.ReadMultipleVars(vars)
网络参数调优:
- 三菱:设置ActTimeOut=3000(毫秒)
- 西门子:调整TSAP参数为0x0100(默认)
7. 常见问题排错指南
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 三菱连接超时 | 防火墙拦截 | 关闭Windows防火墙或添加例外 |
| 西门子数据为0 | DB块未优化 | 在TIA Portal中取消"优化的块访问" |
| 数据不同步 | 线程冲突 | 检查SyncLock是否遗漏 |
| 频繁断连 | 交换机故障 | 更换工业级交换机 |
调试建议:
- 先用MX Component自带的测试工具验证三菱通讯
- 使用Wireshark抓包分析西门子通讯过程
- 逐步增加变量数量,找到性能拐点
8. 扩展应用方向
基于此技术可延伸开发:
- 设备OEE看板系统
- 工艺参数自动优化程序
- 跨品牌PLC程序转换工具
某客户案例中,我们将此方案与SQL Server结合,实现了:
- 每5秒存储一次设备状态
- 自动生成换模报告
- 质量追溯数据关联
核心表结构设计:
sql复制CREATE TABLE ProductionData (
ID INT PRIMARY KEY IDENTITY,
Timestamp DATETIME DEFAULT GETDATE(),
Mitsubishi_Temp1 FLOAT,
Siemens_Pressure FLOAT,
MachineStatus INT
);
实际部署时发现,VB.NET程序作为Windows服务运行更稳定。可通过TopShelf库快速实现服务化:
vb复制Module Program
Sub Main()
HostFactory.Run(Sub(x)
x.Service(Of MyService)(Sub(s)
s.ConstructUsing(Function() New MyService())
s.WhenStarted(Function(tc) tc.Start())
s.WhenStopped(Function(tc) tc.Stop())
End Sub)
x.RunAsLocalSystem()
End Sub)
End Sub
End Module
这个项目给我的深刻体会是:工业通讯就像搭积木,关键要理解每块积木的凹凸形状。三菱的协议像方形榫头,西门子的像圆形卯眼,而VB.NET就是能同时适配两种接口的连接器。在最近一次现场调试中,通过增加下面这段心跳检测代码,成功将系统稳定性从90%提升到99.8%:
vb复制Private Sub HeartbeatCheck()
Dim timer As New Stopwatch
While True
timer.Restart()
If Not CheckMitsubishiConnection() Then
ReconnectMitsubishi()
End If
timer.Stop()
' 动态调整检测间隔(最小100ms)
Dim interval = Math.Max(100, 1000 - CInt(timer.ElapsedMilliseconds))
Thread.Sleep(interval)
End While
End Sub