C# 从传感器读取串行数据
本文关键字:数据 读取 传感器 | 更新日期: 2023-09-27 18:35:45
我想为我的设备制作一个GUI来显示每个传感器的值。我的设备使用此格式发送数据
:1*895*123;
:1*987*145;
*
用于将数据与传感器分离
;
用于数据结束
:
用于在下一个循环中开始数据
我有变量点,Rx1和Ry2来存储数据并将其显示在标签上,但看起来我的程序不起作用。 这是我的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string TestText, Rx1, Ry1, dot;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM7";
serialPort1.BaudRate = 2400;
serialPort1.Open();
if (serialPort1.IsOpen)
{
button1.Enabled = false;
button2.Enabled = true;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
button1.Enabled = true;
button2.Enabled = false;
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
TestText = serialPort1.ReadExisting();
string[] nameArray = TestText.Split ('*');
foreach (string name in nameArray)
{
dot = nameArray[0];
Rx1 = nameArray[1];
Ry1 = nameArray[2];
}
}
private void label3_Click(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
label3.Text = dot;
posY.Text = Ry1;
posX.Text = Rx1;
}
//this.Invoke(new EventHandler(DisplayText));
}
}
我仍然是 c# 的新手,不太擅长它......所以我需要帮助。 谢谢之前。
您确定在数据接收方法中获得了完整的数据包吗? 如果没有,则需要缓冲它们以确保它正常工作。
你可以尝试这样的事情。
// A buffer for the incoming data strings.
string buffer = string.Empty;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// buffer up the latest data.
buffer += serialPort1.ReadExisting();;
// there could be more than one packet in the data so we have to keep looping.
bool done = false;
while (!done)
{
// check for a complete message.
int start = buffer.IndexOf(":");
int end = buffer.IndexOf(";");
if (start > -1 && end > -1 && start < end)
{
// A complete packet is in the buffer.
string packet = buffer.Substring(start + 1, (end - start) - 1);
// remove the packet from the buffer.
buffer = buffer.Remove(start, (end - start) + 1);
// split the packet up in to it's parameters.
string[] parameters = packet.Split('*');
rx1 = parameters[0];
ry1 = parameters[1];
dot = parameters[2];
}
else
done = true;
}
如果你在读取后只得到一个数据块。例如:1*895*123;
TestText = serialPort1.ReadExisting();//:1*895*123;
string[] nameArray = TestText.Split(new []{":", "*", ";"}, StringSplitOptions.RemoveEmptyEntries);
label3.Text = nameArray[0];//1
posY.Text = nameArray[1]; //895
posX.Text = nameArray[2]; //123
如果您收到:1*895*123; :1*987*145;
var chunks = s.Split(new [] { ":", ";", " "}, StringSplitOptions.RemoveEmptyEntries);
foreach (var chunk in chunks)
{
string[] data = chunk.Split(new [] { "*" }, StringSplitOptions.RemoveEmptyEntries);
label3.Text = data[0];
posY.Text = data[1];
posX.Text = data[2];
}
但是在标签中,您只能看到最新的区块数据,因此您需要存储数据列表。例如,您可以创建类:
class chunkData
{
public string dot;
public string posX;
public string posY;
}
并像这样使用它:
private List<chunkData> dataList = new List<chunkData>();
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
TestText = serialPort1.ReadExisting();
var chunks = TestText.Split(new [] { ":", ";", " "}, StringSplitOptions.RemoveEmptyEntries);
foreach (var chunk in chunks)
{
string[] data = chunk.Split(new [] { "*" }, StringSplitOptions.RemoveEmptyEntries);
dataList.Add(new chunkData(){dot=data[0], posX=data[1], posY=data[2]})
}
//display dataList to DataGridView or other control
}
编辑:如果您逐个符号接收数据,您可以执行以下操作:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string temp = serialPort1.ReadExisting();
if(temp == ";") //OK we have end of data lets process it
splitAndDisplay();
else
TestText += temp;
}
private void splitAndDisplay()
{
string[] nameArray = TestText.Split(new []{":", "*"}, StringSplitOptions.RemoveEmptyEntries);
this.Invoke(new Action(() =>
{
label3.Text = nameArray[0];
posY.Text = nameArray[1];
posX.Text = nameArray[2];
}));
TestText = "";
}