c#串口通信并处理接收的多个参数
最近摸索做个上位机,简单记录一下关键的几个部分
c#做串口通信主要使用的是System.IO.Ports类,其实还是十分方便的
最终效果如下:
千万不要忘记了下面这个
填写串口相关配置
我们可以通过GetPortNames方法获取本机的端口列表,注意:不同设备连接电脑后端口不一定相同
string[] sps = SerialPort.GetPortNames();
配置其他串口相关
例如波特率列表
string[] baud = { "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600" };
comboBox2.Items.AddRange(baud); //添加波特率列表
打开串口
其实主要就是用当前串口属性判断是否是打开状态
private void Button1_Click(object sender, EventArgs e)
{
//trycatcj处理串口打开过程中的异常
try
{
//将可能产生异常的代码放置在try块中
//根据当前串口属性来判断是否打开
if (serialPort1.IsOpen)
{
//串口已经处于打开状态
serialPort1.Close(); //关闭串口
button1.Text = "打开串口";
button1.BackColor = Color.ForestGreen;
comboBox1.Enabled = true;
comboBox2.Enabled = true;
comboBox3.Enabled = true;
comboBox4.Enabled = true;
comboBox5.Enabled = true;
ReceptTb.Text = ""; //清空接收区
SendTb.Text = ""; //清空发送区
}
else
{
//串口已经处于关闭状态,则设置好串口属性后打开
comboBox1.Enabled = false;
comboBox2.Enabled = false;
comboBox3.Enabled = false;
comboBox4.Enabled = false;
comboBox5.Enabled = false;
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
serialPort1.DataBits = Convert.ToInt16(comboBox3.Text);
if (comboBox4.Text.Equals("None"))
serialPort1.Parity = System.IO.Ports.Parity.None;
else if (comboBox4.Text.Equals("Odd"))
serialPort1.Parity = System.IO.Ports.Parity.Odd;
else if (comboBox4.Text.Equals("Even"))
serialPort1.Parity = System.IO.Ports.Parity.Even;
else if (comboBox4.Text.Equals("Mark"))
serialPort1.Parity = System.IO.Ports.Parity.Mark;
else if (comboBox4.Text.Equals("Space"))
serialPort1.Parity = System.IO.Ports.Parity.Space;
if (comboBox5.Text.Equals("1"))
serialPort1.StopBits = System.IO.Ports.StopBits.One;
else if (comboBox5.Text.Equals("1.5"))
serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive;
else if (comboBox5.Text.Equals("2"))
serialPort1.StopBits = System.IO.Ports.StopBits.Two;
serialPort1.Open(); //打开串口
button1.Text = "关闭串口";
button1.BackColor = Color.Firebrick;
this.Activate();
}
}
catch (Exception ex)
{
//捕获可能发生的异常并进行处理
//捕获到异常,创建一个新的对象,之前的不可以再用
serialPort1 = new System.IO.Ports.SerialPort();
//刷新COM口选项
comboBox1.Items.Clear();
comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
//响铃并显示异常给用户
System.Media.SystemSounds.Beep.Play();
button1.Text = "打开串口";
button1.BackColor = Color.ForestGreen;
MessageBox.Show(ex.Message);
comboBox1.Enabled = true;
comboBox2.Enabled = true;
comboBox3.Enabled = true;
comboBox4.Enabled = true;
comboBox5.Enabled = true;
}
}
消息传送
这个也没有太多特别的,只要调用Write方法即可
private void SendBtn_Click(object sender, EventArgs e)
{
try
{
Console.WriteLine(serialPort1.IsOpen);
//首先判断串口是否开启
if (serialPort1.IsOpen)
{
//串口处于开启状态,将发送区文本发送
serialPort1.Write(SendTb.Text);
SendTb.Text = "";
}
}
catch (Exception ex)
{
//捕获到异常,创建一个新的对象,之前的不可以再用
serialPort1 = new System.IO.Ports.SerialPort();
//刷新COM口选项
comboBox1.Items.Clear();
comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
//响铃并显示异常给用户
System.Media.SystemSounds.Beep.Play();
button1.Text = "打开串口";
button1.BackColor = Color.ForestGreen;
MessageBox.Show(ex.Message);
comboBox1.Enabled = true;
comboBox2.Enabled = true;
comboBox3.Enabled = true;
comboBox4.Enabled = true;
comboBox5.Enabled = true;
}
}
以上的几个基本功能其实只要调用方法再加上处理异常即可
接收消息
这个接收消息就非常灵活了,说简单简单,说难也有点难,如果要求不高,只是为了展示出接收的消息,的确可以有很简单的方法
这是最简单的方法,只是单纯的将缓存区得到的字符拼接在一起,但是如果传进来的数据不只一类,我们需要将其中每一种分离出来,这种及时从缓存区取出来并拼接在一起就不太适用了,因为从缓存区取出的字符不一定是完整的
String str = serialPort1.ReadExisting();
因此,我求助于搜索引擎,了解到要解决这个问题,我们需要先将得到的字符放在缓存区中,等缓存区积攒了一定的字符再进行读取,每次提取一定的字符后,清空缓存区,将我拿到的这一串字符,转换为数组,我这个例子中有三个参数x y z,我就是将三个参数从下位机中按顺序传入,然后接收的时候以逗号作为分隔符进行拆分(我在单片机上发送消息的时候就用逗号分隔参数了),那么按顺序我们得到的数据就是x1,x2,x3···那么我们只要记录下现在处理的是哪个参数就可以按需处理了。
但是依然有不能解决的问题,就是若频率过高,处理的速度就跟不上了,但是现实情况中并不是每几毫米调用一次,所以我觉得这个问题也可以忽略不计
private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
//因为要访问UI资源,所以需要使用invoke方式同步ui
this.Invoke((EventHandler)(delegate
{
int byteNumber = serialPort1.BytesToRead;
Thread.Sleep(20);
//延时等待数据接收完毕。
while ((byteNumber < serialPort1.BytesToRead) && (serialPort1.BytesToRead < 77))
{
byteNumber = serialPort1.BytesToRead;
Thread.Sleep(20);
}
int n = serialPort1.BytesToRead; //记录下缓冲区的字节个数
//Console.WriteLine("n" + n);
byte[] buf = new byte[n]; //声明一个临时数组存储当前来的串口数据
serialPort1.Read(buf, 0, n); //读取缓冲数据到buf中,同时将这串数据从缓冲区移除
string str = System.Text.Encoding.Default.GetString(buf);
string[] strArray = str.Split(',');
int count = 0;
for (int i = 0; i < strArray.Length; i++)
{
if(count == 0)
{
textBox1.Text = strArray[i];
}else if(count == 1)
{
textBox2.Text = strArray[i];
}else if(count == 2)
{
textBox3.Text = strArray[i];
}
count++;
if(count == 3)
{
count = 0;
}
}
}
)
);
}
catch (Exception ex)
{
//响铃并显示异常给用户
System.Media.SystemSounds.Beep.Play();
MessageBox.Show(ex.Message);
}
}
那么下一步是为其添加上一个视频面板以及遥控手柄,加油继续学习
c#串口通信并处理接收的多个参数的更多相关文章
- .NET 串口通信中断接收,包含0X1A(作为EOF)
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
- C#串口通信—向串口发送数据,同步接收返回数据
最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...
- Qt串口通信接收数据不完整的解决方法
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
- Qt串口通信接收数据不完整的解决方法(传输图片)
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
- System.IO.Ports.SerialPort串口通信接收完整数据
C#中使用System.IO.Ports.SerialPort进行串口通信网上资料也很多,但都没有提及一些细节: 比如 串口有时候并不会一次性把你想要的数据全部传输给你,可能会分为1次,2次,3次分别 ...
- Java实现RS485串口通信,发送和接收数据进行解析
最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的 ...
- .NET 串口通信
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
- BluetoothChat用于蓝牙串口通信的修改方法
本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这 ...
- Win10 IoT C#开发 4 - UART 串口通信
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug ...
随机推荐
- Spring AOP简介与底层实现机制——动态代理
AOP简介 AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想.AOP 是 OOP(面向对象编程 Object Oriented Programmi ...
- Xcode11 踩坑记录
1.UITextView控件莫名导致崩溃 如上图所示,点击Step over 前进进入编译器内部 在lldb控制台输入指令 po $arg1 看到编译器给的提示是由于UITextView的问题. 解决 ...
- Unity3D for iOS初级教程:Part 1/3(下)
转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111735.html 一个手指来统治他们 但是等等,你还没有完全完成! 如果你玩游戏有一 ...
- 设计模式GOF23(行为型模式)
场景: – 公司里面,报销个单据需要经过流程: • 申请人填单申请,申请给经理 • 小于1000,经理审查. • 超过1000,交给总经理审批. • 总经理审批通过 – 公司里面,请假条的审批过程: ...
- Proxmox VE虚拟化管理平台-相关概念
请阅读此文用户务必阅读以下链接,其中包含了汉化作者.张自然copy过来的原因等信息. www.zhangziran.com/proxmox-docs-zh-cn.htm a Proxmox VE 集群 ...
- IP,MAC
MAC寻址与IP寻址 两者是协议上的区分,MAC地址是网卡的物理地址,是提供二层交换机转发数据的,交换机会在自己的内部形成一个MAC地址表,然后根据这个表转发数据包:再者,如果说网络规模大一点的话,机 ...
- 计算机二级Python
概述 计算机二级在近两年新加了python的选择,趁机考了一下,顺便记录一下学习的一些所获 第一章 程序设计语言概述 考纲考点: 这一部分主要是介绍计算机语言的公共常识,一些尝试我就按照自己的理解方式 ...
- 什么是cookie?什么是session?session和cookie有什么区别?
在技术面试中,经常被问到“说说Cookie和Session的区别”,大家都知道,Session是存储在服务器端的,Cookie是存储在客户端的,然而如果让你更详细地说明,你能说出几点?今天个推君就和大 ...
- NodeJS3-4基础API----fs(文件系统)
异步的形式总是将完成回调作为其最后一个参数. 传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常. 如果操作成功完成,则第一个参数将为 null 或 undefined. 1.读取文件操作 ...
- Kubernetes 集群升级docker版本
Kubernetes 集群升级docker版本 原则:升级完一台正常后再接着升下一台. Work Node 一.迁移上的pod(保证业务,但期间会出现抖动) kubectl drain $NODE ...