尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

VB通过MC协议TCP直连三菱Q系列PLC实战指南

VB通过MC协议TCP直连三菱Q系列PLC实战指南 简介本资源是一套面向工业自动化开发者的VB上位机与三菱Q系列PLC通信实战源码适用于初学者入门学习及工程师快速复用开发。聚焦串口通信场景完整实现数据读写、寄存器交互与基础错误处理解决VB与Q系列PLC建立稳定通讯链路的核心问题。压缩包共51个文件含6个VB源码文件含Form1.vb等主窗体逻辑、4个可执行exe含TcpClient.exe、6个DLL封装通信类库、3个XML配置与3个PDB调试符号文件辅以sln/vbproj工程结构和png界面资源总大小277KB结构清晰、开箱即用。已有204人学习下载读者可直接导入VS环境编译运行掌握串口参数配置波特率/校验位、MSComm或SerialPort调用、PLC寄存器地址映射及数据格式转换等关键实践细节并参考工程中My Project配置、App.config通信参数设定等真实项目规范。1. VB调用TCP/IP协议直连三菱Q系列PLC不是串口也不是MODBUS——这套源码走的是MC协议原生通道你打开这个TcpClient.sln项目第一眼会以为是串口通信毕竟“VBPLC”组合在老工程师记忆里几乎等于SerialPortMSComm RS485线。但实际解压后根本找不到SerialPort.Open()或MSComm1.PortOpen True这类代码App.config里明明白白写着add keyPLC_IP value192.168.3.10/Form1.vb中TcpClient.Connect()调用频次远高于任何串口操作。真相是这是一套基于三菱专有MC协议MELSEC Communication Protocol的TCP直连实现绕过OPC、不依赖GX Works ActiveX控件也不走MODBUS TCP封装层。它直接构造二进制帧——包括首部固定4字节0x50 0x00 0x00 0x00、目标模块IO编号、CPU监视标志、命令码如0x0000读D区0x0001写D区、起始地址BCD格式、数据长度字/双字单位再按Q系列PLC要求做CRC-16校验非标准Modbus CRC而是三菱自定义多项式0x8005。这种写法对新手极不友好但对产线实时性要求高的场景如每200ms刷新一次16个温度值8路开关状态却是刚需。适合两类人一是正在用VB维护老旧HMI系统、需快速对接新购Q03UDE PLC的现场工程师二是想吃透工业协议底层帧结构、为后续迁移到C#或Python做协议栈开发打基础的自动化开发者。2. 解析MC协议TCP帧结构与VB中的二进制构造逻辑2.1 为什么必须用MC协议而非MODBUS TCP三菱Q系列PLC的以太网模块如QJ71E71-100默认启用MC协议服务端监听端口5006非MODBUS的502。该协议原生支持Q系列特有的软元件寻址方式如D100、W10.0、B10、R1000且能直接访问过程映像区Process Image Memory和缓冲存储器Buffer Memory而MODBUS TCP仅能映射到有限的保持寄存器4xxxx区。更重要的是MC协议单次请求可读写最多960字1920字节而标准MODBUS TCP单次最多读125个寄存器250字节在需要高频批量采集传感器数据时MC协议减少70%以上网络往返次数。本源码中SendReadCommand()方法构造的请求帧长度为22字节其中关键字段如下表所示字段位置字节数VB代码示例Byte数组索引含义说明典型值十六进制帧头4frame(0) H50 : frame(1) H0固定标识MC协议特征码50 00 00 00网络号1frame(4) H0本地网络设000PLC号1frame(5) HFF广播地址或具体PLC号FF目标模块IO编号2BitConverter.GetBytes(CUInt(H3FF))Q系列CPU模块IO编号BCDFF 03CPU监视标志1frame(8) H00不监视1监视CPU状态00命令码2BitConverter.GetBytes(CUShort(H0))0x0000读软元件0x0001写00 00子命令码2BitConverter.GetBytes(CUShort(H0))0x0000默认0x0001带时间戳读00 00软元件类型1frame(13) H90D区0x90R区0x92X区0x9490起始地址低位4BitConverter.GetBytes(CUInt(H64))D100地址BCD编码0x0100 → 0x0001000064 00 00 00数据长度字2BitConverter.GetBytes(CUShort(10))读取10个D寄存器D100~D1090A 00提示Q系列PLC地址BCD编码规则是——将十进制地址转为BCD码后按小端序Little-Endian存入4字节。例如D100十进制100 → BCD码0x0100 → 小端序存为00 01 00 00但MC协议要求高位在前故最终为00 00 01 00。源码中ConvertToBCDAddress()函数正是执行此转换若此处填错PLC返回0x0003错误码地址异常。2.2 VB中TCP连接管理与超时控制的关键实现TcpClient类本身不提供工业级连接稳定性保障本源码通过三层机制规避常见断连问题连接预检在ConnectToPLC()方法中先调用Ping类检测IP可达性再用TcpClient.Client.Connected属性确认端口5006是否响应失败则抛出PLCConnectionException并记录事件日志发送超时硬约束NetworkStream.Write()不支持超时故改用AsyncCallback模式配合ManualResetEvent实现毫秒级超时默认300ms避免因PLC死机导致UI线程卡死接收缓冲区动态扩容ReadResponse()方法中先读取固定4字节头信息解析出实际数据长度位于帧偏移18~19字节再分配对应大小的Byte()数组接收完整响应防止Read()阻塞或截断。 Form1.vb 片段带超时的异步发送 Private Sub SendWithTimeout(ByVal data() As Byte, ByVal timeoutMs As Integer) Dim sendDone As New ManualResetEvent(False) Try _client.GetStream().BeginWrite(data, 0, data.Length, Sub(ar) _client.GetStream().EndWrite(ar) sendDone.Set() End Sub, Nothing) If Not sendDone.WaitOne(timeoutMs) Then Throw New TimeoutException(PLC发送超时 timeoutMs ms) End If Finally sendDone.Close() End Try End Sub该写法比简单Thread.Sleep()更精准且避免了TcpClient.SendTimeout属性在.NET Framework 4.0中被忽略的问题该属性仅对同步方法有效而异步方法需手动控制。2.3 数据解析从原始字节数组到VB数值类型的映射规则MC协议响应帧中读取D区数据部分为纯二进制每个D寄存器占2字节16位按小端序排列。例如读D100~D101返回01 00 02 00需转换为两个Int16BitConverter.ToInt16({H0, H1}, 0) 256BitConverter.ToInt16({H0, H2}, 0) 512。但源码中ParseDRegisterData()方法做了三重校验长度校验响应帧总长必须 ≥ 14 数据字节数否则视为帧损坏CRC校验提取帧末2字节用三菱专用CRC-16算法初始值0xFFFF多项式0x8005无反转重新计算并与响应帧CRC比对数据范围校验对D区数据强制转为UInteger后检查是否超出0~65535范围若超限则标记为InvalidData并触发报警。 Form1.vb 片段D区数据解析核心逻辑 Private Function ParseDRegisterData(ByVal rawData() As Byte, ByVal startIdx As Integer, ByVal count As Integer) As UInteger() Dim result(count - 1) As UInteger For i As Integer 0 To count - 1 Dim offset As Integer startIdx i * 2 If offset 1 rawData.Length Then Exit For 小端序转UInt16再转UInteger兼容负数场景 result(i) CUInt(BitConverter.ToUInt16(rawData, offset)) 范围过滤D区理论值域0~65535超出即异常 If result(i) 65535 Then result(i) 0xFFFFFFFFUI Next Return result End Function注意UInteger选择是为兼容PLC中D寄存器可能存储的无符号整数如计数器值若业务需处理有符号数如温度-200~800应改用Short并在BitConverter.ToInt16()后做符号扩展判断。3. PLC端配置要点与GX Works2中必须启用的服务3.1 Q系列PLC以太网模块参数设置以QJ71E71-100为例仅VB端正确无法通信PLC侧配置错误会导致连接被拒绝或返回0x0002命令异常错误码。在GX Works2中需完成以下三步网络参数设定在“工程”→“PLC参数”→“内置以太网”中设置IP地址如192.168.3.10、子网掩码255.255.255.0、默认网关192.168.3.1关键动作勾选“启用MC协议服务”端口号固定为5006不可修改访问权限配置进入“工具”→“选项”→“PLC系统设置”→“安全设置”将“远程RUN/STOP”和“远程I/O刷新”权限设为“允许”在“MC协议设置”页签中添加允许访问的IP段如192.168.3.0/24否则PLC会静默丢弃来自VB客户端的帧软元件锁保护解除若读取D100时返回0x0004访问禁止需检查“PLC参数”→“程序”→“软元件锁”是否启用了D区写保护在GX Works2中右键D区→“属性”→取消勾选“写入禁止”。注意Q系列PLC的MC协议默认禁用广播功能。源码中frame(5) HFF使用广播地址需在GX Works2的“MC协议设置”中显式启用“允许广播访问”否则PLC不响应。3.2 VB窗体中数据绑定与实时刷新机制设计Form1.vb采用Timer控件RefreshTimer驱动周期性读取但未使用BackgroundWorker或Task.Run存在UI线程阻塞风险。优化方案是将ReadDRegisters()方法重构为异步模式并用InvokeRequired安全更新控件 改写后的异步读取替换原Timer.Tick事件 Private Async Sub RefreshTimer_Tick(sender As Object, e As EventArgs) Handles RefreshTimer.Tick Try Dim values() As UInteger Await Task.Run(Function() ReadDRegisters(100, 10)) 安全更新UI If Me.InvokeRequired Then Me.Invoke(Sub() UpdateLabels(values)) Else UpdateLabels(values) End If Catch ex As Exception LogError(刷新失败: ex.Message) End Try End Sub Private Sub UpdateLabels(values() As UInteger) For i As Integer 0 To Math.Min(values.Length - 1, 9) Dim labelName As String $lblD{i 100} Dim lbl As Label Me.Controls.Find(labelName, True).FirstOrDefault() If lbl IsNot Nothing Then lbl.Text values(i).ToString() Next End Sub此改造将耗时的TCP通信移出UI线程避免窗体假死且UpdateLabels中的Controls.Find()比硬编码lblD100.Text更易维护。4. 常见通信故障定位与协议级排错技巧4.1 根据错误码快速定位问题根源MC协议响应帧的第16~17字节为错误码2字节大端序本源码在CheckResponseError()方法中解析并映射为可读提示。以下是生产环境中最常遇到的5类错误及处置方案错误码十六进制含义排查步骤VB端应对措施0000正常—继续解析数据0002命令异常检查VB发送帧中命令码offset 10~11、子命令码12~13是否为PLC支持值记录日志暂停刷新5秒后重试0003地址异常验证D区起始地址BCD编码是否正确如D100≠0x00000064弹窗提示“PLC地址配置错误”高亮配置项0004访问禁止GX Works2中检查D区软元件锁、MC协议访问权限列表显示“PLC权限不足请联系管理员”0005数据异常发送数据长度与PLC实际可写区域不符如向只读D区写入禁用写入按钮显示“目标寄存器为只读”提示使用Wireshark抓包时过滤条件设为tcp.port 5006 ip.addr 192.168.3.10可直观对比VB发送帧与PLC响应帧。若PLC无响应说明网络层不通若PLC返回帧但错误码非0000则问题在协议层。4.2 抓包验证与帧结构手工校验流程当Wireshark捕获到PLC返回帧50 00 00 00 00 00 00 00 FF 03 00 00 00 00 90 00 00 00 00 00 0A 00 00 00 01 00 02 00 00 00按以下步骤人工校验确认帧头前4字节50 00 00 00符合MC协议提取数据长度偏移18~19字节0A 00→ 十进制10 → 表示10个字20字节数据定位数据区从偏移22字节开始取20字节 →00 01 00 02 00 00 00 00 ...BCD地址反推偏移14~17字节00 00 00 00→ 地址0 → 对应D0但VB请求的是D100说明PLC端地址映射错误CRC校验取前28字节不含末2字节CRC用在线MC协议CRC计算器验证若不匹配则VB构造帧时字节序错误。此流程无需PLC编程知识仅凭网络包即可80%定位问题比反复重启GX Works2高效得多。4.3 高并发场景下的连接复用与资源泄漏防护源码中每次读写均新建TcpClient实例New TcpClient()在高频刷新如50ms周期下会导致Windows句柄耗尽。生产环境必须改为长连接连接池在Form1类级声明_sharedClient As TcpClient首次连接后复用添加Dispose()方法在窗体关闭时调用_sharedClient?.Close()和_sharedClient?.Dispose()增加心跳保活每30秒发送空帧00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00MC协议心跳码。 Form1.Designer.vb 中添加 Protected Overrides Sub Dispose(disposing As Boolean) If disposing AndAlso components IsNot Nothing Then components.Dispose() End If If _sharedClient IsNot Nothing Then Try _sharedClient.Close() Catch End Try _sharedClient.Dispose() End If MyBase.Dispose(disposing) End Sub此修改将单实例VB程序的稳定运行时间从数小时提升至数周避免因句柄泄漏导致的“连接被拒绝”错误。本文还有配套的精品资源点击获取
返回列表