西门子PLC与Unity3D通讯丨串口通讯

前言

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

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

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

通讯协议

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];
        
	   while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    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++;
                            }

                        }

                        //打印输入
                        string str = "";
                        for (int i = 0; i < index; i++)
                        {
                            str += Convert.ToString(data[i]) + " ";
                        }
                        Debug.Log(str + "   " + n + "   " + index + "   " + sp.ReadBufferSize);
                        str = "";

                        DataProcessingFunction(index, 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;
	
	//将参数传给sp
	sp = 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端参考自由口协议向上方式即可,未来遇到什么古怪问题会持续更新。

版权声明:本文为CSDN博主「辰似五味」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44879321/article/details/122244118

前言

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

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

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

通讯协议

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];
        
	   while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    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++;
                            }

                        }

                        //打印输入
                        string str = "";
                        for (int i = 0; i < index; i++)
                        {
                            str += Convert.ToString(data[i]) + " ";
                        }
                        Debug.Log(str + "   " + n + "   " + index + "   " + sp.ReadBufferSize);
                        str = "";

                        DataProcessingFunction(index, 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;
	
	//将参数传给sp
	sp = 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端参考自由口协议向上方式即可,未来遇到什么古怪问题会持续更新。

版权声明:本文为CSDN博主「辰似五味」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44879321/article/details/122244118

生成海报
点赞 0

辰似五味

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

西门子PLC与Unity3D通讯丨串口通讯

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

串口笔记

串口 PC串口发数据 界面: 实现功能:连接串口,显示数据,设置界面UI 进制转换 str i.String("x").TOUpper();进制转换ToLower();将所有字母 转化为小写字母属性:

基于8051单片机实现电子时钟+数字秒表设计

概述 电子时钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许

PCB做板子步骤和经验

好久没做PCB板了,花了3天时间,复习, 完成了主控板的PCB绘制和在线下单。这里希望记录一下PCB制板的主要步骤,便于今后再次做板子的时候来复习。 1. 画原理图 原理图这块&#xf