繁体   English   中英

从C#到Arduino读写串口数据

[英]Writing and reading serial data from C# to Arduino

我在 Visual Studio 中有一个 .net 应用程序,它与 Arduino Uno 通信。 Uno 连接到压力传感器。 我想通过串口从我的 .net 应用程序向 Arduino 发送一条消息,询问压力数据。 然后我希望 Arduino 响应最新的数据点,并通过串行将其发送回我的 .net 应用程序,然后绘制它并存储数据。

我可以从我的 Uno 连续发送 stream 的数据,应用程序会注册整个 stream。但这会产生明显的延迟。 我还尝试使用计时器将消息发送到我的 Uno,但这仅在我使用至少 2500 毫秒的线程休眠时有效,这对我的目的来说太长了。

我的问题是我找不到从 .net 应用程序连续发送请求的方法。 例如,我可以添加一个按钮,将命令发送到 Arduino,然后我得到正确的响应。 但我想以连续的方式高频地做这件事。

以下是我的代码的相关部分:

public void Read() //Reads sensor values from Uno
{
    while (port.IsOpen)
    {
        try
        {
            if (port.BytesToRead > 0)
            {
                string message = port.ReadLine();
                this.SetText(message);
            }
        }
        catch (TimeoutException) { }
    }
}

    private void SetText(string text)
    {
        if (this.labelPressure.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] {text});
        }
        else
        {
            this.labelPressure.Text = text;

            chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = false;
            chart1.Invoke((MethodInvoker)(() => chart1.Series["Pressure"].Points.AddXY(DateTime.Now.ToLongTimeString(), text)));

            if (chart1.Series[0].Points.Count > 20)
            {
                chart1.Series[0].Points.RemoveAt(0);
                chart1.ChartAreas[0].AxisX.Maximum = 0;
                chart1.ChartAreas[0].AxisX.Maximum = 20;
                chart1.ChartAreas[0].AxisY.Maximum = 10;
                chart1.ChartAreas[0].AxisY.Minimum = -90;
                chart1.ChartAreas[0].AxisY.Interval = 10;
            }
        }

    }

这部分代码用于读取整个数据 stream。我想发送给 Uno 的消息是

           string d2 = "M";
           port.Write(d2);

但我不知道如何持续、高频地向我的 Uno 发送此消息,然后收到答复。 有没有人有办法解决吗?

最好的算法是,您打开连接,发送测量请求并等待答案并从头开始。

有一个DataReceived事件,您可以使用它而不是在 while 循环中连续轮询数据。

using System;
using System.IO.Ports;

class PortDataReceived
{
    public static void Main()
    {
        SerialPort mySerialPort = new SerialPort("COM1");

        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.RtsEnable = true;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();
        mySerialPort.Write("M"); // initiate the query
        
        Console.ReadKey();
        mySerialPort.Close();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {
        var sp = (SerialPort)sender;
        var indata = sp.ReadLine();
        //process your message (here you refresh your controls in GUI app )
        /* process data on the GUI thread
        Application.Current.Dispatcher.Invoke(new Action(() => {
            this.labelPressure.Text = indata;
        }));
        */
        Console.WriteLine(indata);
        mySerialPort.Write("M"); // send message request again (it is a bit recursive solution, but maybe this is enough for your use case)
    }
}

首先在命令行解决方案中尝试此操作,如果您对数据频率感到满意,则在您的解决方案中实施它(删除 Console.* 行,取消注释注释代码,一切都应该有效)。

暂无
暂无

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

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