串口通讯

  • 前言
  • 通讯协议
  • 代码部分
    • 引用文件的准备
    • 数据类型的声明
      • 写接收数据函数DataReceiveFunction()
      • 写打开串口函数OpenPort()
      • 关闭串口ClosePort()
      • 发送数据WriteData(byte[] bys)
    • 对于PLC端参考自由口协议向上方式即可,未来遇到什么古怪问题会持续更新。

前言

U3D和plc或者是单片机等其他软件的串口通讯脚本就是需要在上位机写一个串口服务程序,可以实现开启串口、关闭串口、接收、发送这四块基本内容即可,对于有数据处理的朋友可以再开一个线程专门用来数据处理。

这篇文章在稍微影响数据流的准确性下,将C#中Read()函数接收一次信息却分两次到多次读取的的问题解决了一点。

为了方便大家直接移植,以下代码均不带函数名称,将代码片直接复制至函数下即可。

2023年4月28日更新:
1.之前有发现当物理的硬件线路受到干扰时会出现断链或线程(协程)卡死的情况,之后发现极大可能是出现在外部干扰导致串行通讯出现乱码,该乱码导致接收线程中的序号错乱。本次主要更新接收线程中的接收模块校验问题。
2.同时如果出现读取不完全的情况很有可能是 软件读的速度>>串口接受数据的速度,解决方法是再接收事件函数的开始位置延迟一段时间,根据数据长度的不同可以适当改变延迟的时间,我这边延时了300ms

通讯协议

U3D为串口通讯协议,PLC为自由口协议。

代码部分

引用文件的准备

在U3D端需要使用

using System.IO.Ports;

这个引用中关于端口号、波特率、数据位、停止位、奇偶位五个参数的定义。

数据类型的声明

    private string portName;   //端口号private int baudRate;         //波特率private Parity parity;          //奇偶位private int dataBits;          //数据位private StopBits stopBits;//停止位

五个参数定义好后,开始写四个基本的函数块,其中最有特点的即为接收数据函数,希望大家可以看看有没有更好的方法,我就在这抛砖引玉了。

写接收数据函数DataReceiveFunction()

int index = 0;       //用于记录此时的数据次序int ReadToBytes = 0;//记录长度byte[] readBuffer = new byte[20];int startIndex = -1;while (true){if (sp != null && sp.IsOpen){try{Thread.Sleep(300);int n = sp.BytesToRead;if (n > 0)//此处是发现接收缓存区出现内容则进行读取{readBuffer = new byte[sp.BytesToRead + 1];ReadToBytes = sp.Read(readBuffer, 0, n);//Debug.Log(n + "   "  + sp.ReadBufferSize);//if ((n == 10))  //用来判断是否符合接收长度,不符合则继续接收,因为Read()是分多次从缓冲区读取。//就可能出现一次读一位一次读12位的情况。//{//    index = 0;//    for (int i = 0; i < n; i++)//    {//        if (index >= n) index = n - 1;//        data[index] = readBuffer[i];                               //将数据存入data中//        index++;//    }//}//上面注释的部分为之前的弱校验,只是对接收缓存区内容大小做了一次判断//下面为多次校验版本,通过查找“发送报文”的帧头“0xF4”来进行拷贝//建议可以再这里多做几次校验。通过更改报文来确定收到的数据可靠//CRC、长度、和等各种校验方式,这里仅对校验帧头帧尾举例。for (int i = 0; i < readBuffer.Length; i++){if (readBuffer[i] == 0xF4){// 检查后面第10位是否为0xEFif (i + 10 < readBuffer.Length && readBuffer[i + 10] == 0xEF){startIndex = i;break;}}}//当startIndex不为-1的时候表示找到,并将从此开始的整个报文拷贝到这里if (startIndex != -1){Array.Copy(readBuffer, startIndex, data, 0, 10);}//打印输入string str = "";for (int i = 0; i < index; i++){str += Convert.ToString(data[i]) + " ";}Debug.Log(str + "   " + n + "   " + index + "   " + sp.ReadBufferSize);str = "";DataProcessingFunction(data);//数据处理函数,这个是根据自己需要怎么处理来写的,在这我就不献丑了。}}catch (Exception ex){Debug.Log(ex);}}Thread.Sleep(100);}

写打开串口函数OpenPort()

给五个参数赋上初值

    SerialPort sp = null;//串口控制Thread dataReceiveThread;//定义一个线程//给五个参数赋上初值portName = COM1;baudRate = 9600;parity = Parity.None;dataBits = 8;stopBits = StopBits.None;//将参数传给spsp = new SerialPort(portName, baudRate, parity, dataBits, stopBits);sp.ReadTimeout = 400;//使用try...catch...结构可以捕捉中途是否出现中断以及导致中断的原因。try{sp.Open();}catch (Exception ex){Debug.Log(ex.Message);}//当串口打开后会报告一下打开串口信息,这个可以之后引入操作界面以供观察。if (sp.IsOpen){Debug.Log("打开串口" + portName + " " + baudRate + " " + parity + " " + dataBits + " " + stopBits);//同时单独打开一个数据接收线程为dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction));//数据接收线程dataReceiveThread.Start();}

关闭串口ClosePort()

//同打开串口一样也使用try...catch...try{sp.Close();}catch (Exception ex){Debug.Log(ex.Message);}

发送数据WriteData(byte[] bys)

    if (sp.IsOpen){sp.Write(bys, 0, bys.Length);}

对于PLC端参考自由口协议向上方式即可,未来遇到什么古怪问题会持续更新。

西门子PLC与Unity3D通讯丨串口通讯相关推荐

  1. labview+PLC程序+OPC完整项目程序Labview和西门子PLC smart200 OPC通讯仪器串口通讯

    labview+PLC程序+OPC完整项目程序Labview和西门子PLC smart200 OPC通讯仪器串口通讯 全套项目资料,包括Labview 程序,研华工控机,西门子Smart 200程序, ...

  2. Labview和西门子PLC smart200 OPC通讯仪器串口通讯

    Labview和西门子PLC smart200 OPC通讯仪器串口通讯 全套项目资料,包括Labview 程序,研华工控机,西门子Smart 200程序,电气原理图,元器件清单,详细注释 Labvie ...

  3. C# 机器视觉工控通讯------西门子PLC之S7协议上位机通讯

    C# 机器视觉工控通讯------西门子PLC之S7协议上位机通讯 使用步骤 1.引入库 项目添加应用HslCommunication.dll和代码代码如下(示例): dll官方支持网站> us ...

  4. 西门子PLC 1200和V20变频器USS通讯 5台西门子变频器V20和1200PLC USS通讯

    西门子PLC 1200和V20变频器USS通讯 5台西门子变频器V20和1200PLC USS通讯,西门子触摸屏,总线通讯,实际项目程序,提供,CAD电气图纸 变频器设置说明 详细注释和项目文件 YI ...

  5. 西门子PLC与Unity3D通讯丨PROFINET通讯

    Unity3D 与西门子PLC通讯 前言 通讯协议 通讯建立的细节 期间遇到的两个主要问题 总结 前言 想做这样的通讯太久了,从21年二月份陆陆续续到十一月份才正式做好,最开始想西门子1200系列与u ...

  6. 西门子PLC的MODBUS RTU和modbusTCP通讯

    1.西门子PLC的通讯扩展 西门子通讯桥接器分为基本版和专业版,型号分别为NET30-MPI和NET30-MPI Pro,专业版不仅包含了基本版所有的功能,而且增加了扩展口X2的MODBUS主从站功能 ...

  7. 西门子PLC(S7-1200、1500)通讯程序报16#80C8错误的解决方法

    最近在用S7-1200做通讯实验,里面配置了1个TCP通讯.2个UDP通讯.1个MODBUS TCP SERVER. 开始时,只配置有一个通讯的时候,都能正常工作.后来,把这几个集成在一个程序里时,却 ...

  8. serialport通过usb通讯_IOT串口通讯-RS232/RS485

    串口 串口是串行接口(serial port)的简称,也称为串行通信接口或COM接口.串口通信是指采用串行通信协议(serial communication)在一条信号线上将数据一个比特一个比特地逐位 ...

  9. android串口通讯奇偶校验,串口通讯奇偶数校验及CRC校验如何使用详解

    我们以前在学校使用串口基本都不用奇偶数校验都是采用硬件CRC(循环冗余校验码)校验的.但有时候为了数据传输的更加严谨和差错的处理会采用奇偶校验.这里简单说下软件上CRC校验是如何计算的. 所谓CRC是 ...

最新文章

  1. GTX 1080Ti + cuda8.0 + cuDNN6.0 安装及测试
  2. 扫描的图片怎么转换成word
  3. PHPStorm IDE 快捷键
  4. 对Spring创建对象的思考
  5. 阶段3 3.SpringMVC·_04.SpringMVC返回值类型及响应数据类型_2 响应之返回值是String类型...
  6. 数据类型 --生成器
  7. Linux文件夹设置共享
  8. 华为3500光端机基本介绍_OptixOSN3500光端机产品描述
  9. 迅为6818/4418开发板Yocto开发指南
  10. 【深度学习基础1】深度学习发展历史
  11. 游戏开发入门——Lua(1)
  12. Immersionbar学习笔记
  13. java计算机毕业设计华北地区阔叶林木叶部病虫害图像管理系统源码+mysql数据库+系统+lw文档+部署
  14. Vue, App与我(二)
  15. C语言如何给随机数赋变量,C语言产生随机数序列的方法
  16. 迅雷资源优化去广告补丁
  17. 安卓手机怎么录屏幕 如何录制视频
  18. 什么是Azkaban - 流式调度框架
  19. Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(六)
  20. 黄历php源码下载,黄历查询示例代码

热门文章

  1. Simulink的S函数的离散仿真
  2. 【学习mysql】ubuntu20.04下彻底删除mysql8.0
  3. Sentinel-2(哨兵-2)L1C数据辐亮度(辐射定标)和TOA反射率的获取说明
  4. 如何彻底卸载Oracle数据库
  5. 我们该如何度过自己的大学四年?
  6. 计算机等级考试培训课件,全国计算机等级考试培训课件.ppt
  7. 【202106小白训练营】day03-java数据结构
  8. awk命令详解(大全)
  9. STM32C8T6 流水灯的实现(库函数版)
  10. DeepNet :Scaling Transformers to 1000 Layer