簡體   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