当前位置: 首页 > wzjs >正文

上传文件到网站根目录个人作品主页wordpress

上传文件到网站根目录,个人作品主页wordpress,百度关键词优化软件怎么样,凡科网站怎么关闭建设中索引 一、SerialPort串口通信二、使用SerialPort1.创建SerialPort对象,进行基本配置2.写入串口数据①.写入串口数据的方法②.封装数据 3.读取串口数据①.读取串口数据的方法②.解析数据 4.读取串口数据的时机①.DataReceived事件②.多线程接收数据 5.粘包问题处理 一…

索引

  • 一、SerialPort串口通信
  • 二、使用SerialPort
    • 1.创建SerialPort对象,进行基本配置
    • 2.写入串口数据
      • ①.写入串口数据的方法
      • ②.封装数据
    • 3.读取串口数据
      • ①.读取串口数据的方法
      • ②.解析数据
    • 4.读取串口数据的时机
      • ①.DataReceived事件
      • ②.多线程接收数据
    • 5.粘包问题处理

一、SerialPort串口通信

C#中的SerialPort类是.NET框架提供的一个用于串口通信的强大工具,主要用于实现计算机与外部设备(如传感器、嵌入式设备、PLC等)之间的数据交换。

二、使用SerialPort

1.创建SerialPort对象,进行基本配置

使用SerialPort时,直接创建一个SerialPort对象即可,其基本配置项包括:

PortName:串口号,如COM1。
BaudRate:波特率,如9600或115200。
DataBits:数据位,通常为7或8。
StopBits:停止位,通常为1、1.5或2。
Parity:奇偶校验位,如None(无校验)、Odd(奇校验)或Even(偶校验)。

代码如下:

    /// <summary>/// 串口号/// </summary>[Label("串口号")] public string portName;/// <summary>/// 波特率/// </summary>[Label("波特率")] public int baudRate;/// <summary>/// 数据位/// </summary>[Label("数据位")] public int dataBits;/// <summary>/// 停止位/// </summary>[Label("停止位")] public StopBits stopBits;/// <summary>/// 奇偶校验位/// </summary>[Label("奇偶校验位")] public Parity parity;private SerialPort _serialPort;protected override void Awake(){base.Awake();_serialPort = new SerialPort();_serialPort.PortName = portName;_serialPort.BaudRate = baudRate;_serialPort.DataBits = dataBits;_serialPort.StopBits = stopBits;_serialPort.Parity = parity;try{_serialPort.Open();}catch (Exception e){Log.Error(e.Message);}}

2.写入串口数据

①.写入串口数据的方法

写入串口数据的方法非常简单,如下:

		//将数据封装为字节数组(可以直接强转字符串,也可以按16进制处理等)byte[] bytes = EncapsulatePackage(data);_serialPort.Write(bytes, 0, bytes.Length);

②.封装数据

如何封装数据取决于数据交换的协议,比如直接强转字符串:

	    /// <summary>/// 单个数据包结束符(换行符)/// </summary>private const byte EndSign = 10;/// <summary>/// 封装数据包(这里要求所有字符必须为ASCII码,也即是一个字符只占一个字节)/// </summary>/// <param name="data">原始数据</param>/// <returns>数据包</returns>private byte[] EncapsulatePackage(string data){byte[] bytes = new byte[data.Length + 1];for (int i = 0; i < data.Length; i++){bytes[i] = (byte)data[i];}//在每个数据包后面补充【结束符】,表明此数据包结束bytes[bytes.Length - 1] = EndSign;return bytes;}

这里以简单协议进行讲解(每个数据包以【换行符】代表结束符)。

3.读取串口数据

①.读取串口数据的方法

读取串口数据的方法非常简单,如下:

		//建立数据缓冲区(大小为串口中可读取数据大小:_serialPort.BytesToRead)byte[] bytes = new byte[_serialPort.BytesToRead];_serialPort.Read(bytes, 0, bytes.Length);//解析数据包string data = AnalyzePackage(bytes);

②.解析数据

如何解析数据取决于数据交换的协议,比如直接强转字符串:

        /// <summary>/// 解析数据包/// </summary>/// <param name="bytes">数据包</param>/// <returns>数据</returns>private string AnalyzePackage(byte[] bytes){return Encoding.Default.GetString(bytes);}

4.读取串口数据的时机

那么对如上的简单的写入、读取串口数据有了基本的了解之后,接下来便是相对不那么简单的部分了。

首先,写入串口数据的时机由我们说了算,何时调用便何时写入,这点毋容置疑。

但是,读取串口数据的时机该是何时?参考下面两种方式。

①.DataReceived事件

SerialPort的DataReceived事件当对象对应的串口接收到了数据时便会触发,用他来读取数据简直不要太丝滑

	    protected override void Awake(){base.Awake();//......_serialPort.DataReceived += OnDataReceived;//......}private void OnDataReceived(object sender, SerialDataReceivedEventArgs e){if (_serialPort.IsOpen && _serialPort.BytesToRead > 0){//建立数据缓冲区(大小为串口中可读取数据大小:_serialPort.BytesToRead)byte[] bytes = new byte[_serialPort.BytesToRead];_serialPort.Read(bytes, 0, bytes.Length);//解析数据包string data = AnalyzePackage(bytes);}}

但是,这里必须得有一个但是,只要在Unity中用过SerialPort的都会知道DataReceived这玩意他不起作用,主要原因如下(别怀疑,就是问的AI):

1.Unity引擎对System.IO.Ports命名空间的支持有限,尤其是对DataReceived事件的支持存在缺陷。在Unity中,DataReceived事件通常不会像在常规C#项目中那样正常触发,这主要是因为Unity的运行环境与普通.NET应用有所不同,特别是在事件处理机制上存在差异。
2.DataReceived事件需要在一个独立的线程中监听串口数据,但在Unity中,主线程(用于游戏逻辑和渲染)和串口数据接收线程之间的同步机制存在问题。因此,DataReceived事件可能无法被正确触发。
3.Unity的Update和FixedUpdate等事件函数运行在主线程中,而串口数据接收通常需要多线程支持。当串口操作在主线程中执行时,可能会因为线程冲突导致DataReceived事件无法触发。

那么,我们不得不考虑更换其他方案了。

②.多线程接收数据

老样子,像处理Socket通信那样,多线程永远是最强的利器:

    private Thread _receiveThread;protected override void Awake(){base.Awake();//新建一个线程,启动数据接收方法ReceivedData_receiveThread = new Thread(new ThreadStart(ReceivedData));_receiveThread.Start();}protected override void OnDestroy(){base.OnDestroy();_receiveThread.Abort();_receiveThread = null;}/// <summary>/// 从串口接收数据/// </summary>private void ReceivedData(){while (true){if (_serialPort.IsOpen && _serialPort.BytesToRead > 0){try{//建立数据缓冲区(大小为串口中可读取数据大小:_serialPort.BytesToRead)byte[] bytes = new byte[_serialPort.BytesToRead];_serialPort.Read(bytes, 0, bytes.Length);//解析数据包string data = AnalyzePackage(bytes);//......}catch (Exception e){Log.Error(e.Message);}}}}

5.粘包问题处理

当然,到此时我们并不能高枕无忧,还有另一个在数据交换领域普遍存在的问题需要我们解决,那就是数据的粘包问题。

粘包问题是指多个数据包在接收端被错误地合并成一个数据包,导致接收方无法正确区分每个数据包的边界。这通常发生在连续发送多个数据包时,接收端来不及解析或缓冲区管理不当的情况下。

就像Socket通信一样,发送方发出的数据是A03568,但接收方可能会分多次接收到,比如2次才接收完,那就可能是A03568,接收方只是一个机器不是人,自然不知道这2个包该连起来合成一个包,那么后续的处理自然就乱套了。

这就是通信协议存在的必要了,以我们的简单通信协议为例(每个数据包以【换行符】代表结束符),在读取数据的方法中进行防粘包处理:

    private byte[] _buffer = new byte[16];private List<byte> _receiveBuffer = new List<byte>();/// <summary>/// 从串口接收数据/// </summary>private void ReceivedData(){while (true){if (_serialPort.IsOpen && _serialPort.BytesToRead > 0){try{//读取一次数据(最大不超过缓冲区大小)int count = _serialPort.Read(_buffer, 0, Mathf.Min(_buffer.Length, _serialPort.BytesToRead));for (int i = 0; i < count; i++){//如果为结束符,则代表一个数据包接收完成,解析该包if (_buffer[i] == EndSign){string data = AnalyzePackage(_receiveBuffer.ToArray());//清空缓冲区_receiveBuffer.Clear();//处理数据HandlerData(data);Log.Info($"接收串口数据:{data}");}//否则加入数据缓冲区else{_receiveBuffer.Add(_buffer[i]);}}}catch (Exception e){Log.Error(e.Message);}}}}

代码很简单,相信处理过字节流的人应该都能看懂,事实上在串口通信中如上的简单通信协议已能胜任大多数情况。


文章转载自:

http://7vDZxtvS.txfxy.cn
http://JFpIPScy.txfxy.cn
http://HKM8YSHU.txfxy.cn
http://wkcIEnlp.txfxy.cn
http://V6tsLCD1.txfxy.cn
http://CdHhltqd.txfxy.cn
http://5NIkjp8t.txfxy.cn
http://7FUmtngm.txfxy.cn
http://G0Nt0q5W.txfxy.cn
http://yTMlaldS.txfxy.cn
http://b6osO8eQ.txfxy.cn
http://WDzEriwe.txfxy.cn
http://BXilSK2z.txfxy.cn
http://cC7cfR52.txfxy.cn
http://G8TP7bAL.txfxy.cn
http://P21ToYou.txfxy.cn
http://B2WeyaNB.txfxy.cn
http://IGCDUk3s.txfxy.cn
http://FltO7gaz.txfxy.cn
http://4lAsh0Ta.txfxy.cn
http://Zsabag2m.txfxy.cn
http://1gWX1oCO.txfxy.cn
http://yHdXrR0Y.txfxy.cn
http://B8XFknSv.txfxy.cn
http://9ppLhPek.txfxy.cn
http://LSRWxIIK.txfxy.cn
http://GhUwJ6aw.txfxy.cn
http://Zr57R4q0.txfxy.cn
http://0fXEX9RP.txfxy.cn
http://juGZxK1L.txfxy.cn
http://www.dtcms.com/wzjs/734087.html

相关文章:

  • 免费域名网站推荐新闻头条新闻
  • 做网站界面一般用什么来做制作小程序教程
  • 展示型手机网站ae免费模板下载网站
  • 承德住房和城乡建设局网站关闭了网站设计师认证培训
  • 公司网站公司新闻wordpress只能显示字
  • 大网站服务器维护费用江门百度seo
  • 昆明企业为什么要做网站学院网站建设管理办法
  • 制作网站源码软件学校介绍网站模板
  • 大气红色网站会qt怎么做网站
  • 南山网站建设公司校园网设计方案
  • 网站建设进程表资兴网站建设
  • 网站模板编辑软件网站建设除了中企动力
  • 石家庄个人建网站百度网站首页提交入口
  • 南雄市住房和城乡建设局网站sem是什么的缩写
  • 大学生网站开发项目计划书范文网站开发的价格
  • 好网站分享手机网站怎么搜索引擎
  • php大型网站开发视频网站建设几个要素
  • 网站续费合同书长沙 外贸网站建设公司
  • 网站免费建站2网站死链接怎么删除
  • 桂林北京网站建设企业为什么做企业网站和推广
  • 公司网站建设多少费用哪儿济南兴田德润联系电话wordpress 图片加速
  • gov域名网站有哪些中国新闻社总编辑
  • 域名备案与网站不一致深圳住建网
  • 做好网站外链建设的最新方法wordpress win8模板
  • 东莞专业的网站建设网络推广怎样网站建设
  • 做软件代理去哪个网站wordpress数据库密码错误
  • 工具站seo网站建设玖金手指谷哥十一
  • 西安大型网站开发用jquery做的网站
  • flash网站效果集团网站设计欣赏
  • 网站站内优化怎么做网站建设主要业务流程设定