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# 的新手,不太擅长它......所以我需要帮助。 谢谢之前。

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 = "";
}