简体   繁体   English

C#从传感器读取串行数据

[英]C# Reading Serial data from sensor

I want to make a GUI for my device to show the value of each sensor. 我想为我的设备制作一个GUI,以显示每个传感器的值。 My device send data with this format 我的设备以这种格式发送数据

:1*895*123; :1*987*145;

* is use to separate data from sensors *用于从传感器中分离数据

; is for the end of data 用于数据结束

: is for start of data in next loop :用于下一个循环中的数据开始

I have variables dot, Rx1 and Ry2 to storing the data and show it on label, but looks like my program didn't works.. here's my code 我有变量dot,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));
    }


}

I'm still new in c# and not so good with it.. so i need help. 我仍然是C#的新手,但对它的了解不是很好。.所以我需要帮助。 thanks before. 之前感谢。

Are you sure that you're getting complete packets in the data received method? 您确定要通过数据接收方法获取完整的数据包吗? if not you'll need to buffer them up to be sure it's working properly. 如果不是,则需要缓冲它们以确保其正常工作。

You could try something like this. 您可以尝试这样的事情。

// 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;
}

If you getting just one chunk of data after reading. 如果读取后仅获得一小块数据。 For example :1*895*123; 例如: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

and if you receive :1*895*123; :1*987*145; 如果您收到:1*895*123; :1*987*145; :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];  
}

But then in labels you just see latest chunk data, so you need store a list of your data. 但是,在标签中,您只会看到最新的块数据,因此需要存储数据列表。 For example you can create class: 例如,您可以创建类:

class chunkData
{
    public string dot;
    public string posX;
    public string posY;
}

and use it like this: 并像这样使用它:

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
}

EDIT : here is what you can do if you receiving data symbol by symbol: 编辑 :如果您通过符号接收数据,这是您可以做的事情:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM