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

时间:2012-05-31 07:27:47

标签: c#

我想为我的设备制作一个GUI来显示每个传感器的值。我的设备使用此格式发送数据

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

*用于将数据与传感器分开

;用于数据结尾

:用于下一循环中的数据开始

我有变量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));
    }


}

我仍然是c#的新手而且不太好...所以我需要帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

您确定在收到数据的方法中获得了完整的数据包吗?如果不是,你需要缓冲它们以确保它正常工作。

你可以尝试这样的事情。

// 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 :(得分:0)

如果您在阅读后只获得一大块数据。例如: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 = "";
}