繁体   English   中英

向/从串行端口读取和写入数据

[英]Read and write data to/from Serial Port

我正在构建一个控制台应用程序,该应用程序将在 Windows 的任务计划程序中安排,以每天在设定的时间运行我的代码。 总结一下,这个应用程序将通过SerialPort读写。 当我向 Arduino 发送一些东西时,我需要从中接收一些东西来完成我发送的内容并执行命令。

换句话说,我会发送一些东西,看看门是否打开,如果是,应用程序将运行一个代码来关闭它。 如果门已经关闭,我将发送一堆字符以显示到 Arduino LED 显示屏中。

所以我开发了一个代码,但我不确定它是否完全正确,如果可能的话帮助我改进它。 有什么我可以做的改变吗?

static void Main(string[] args)
{
    SerialPort comport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
    comport.Open();

    string start = "?";
    string carriageReturn = "\r";
    string text = string.Empty;

    string mensage = "@" + "r" + "\r";
    string mensage2 = "@" + "{" + texto + "\r";

    try
        {
            while (true)
            {
                //Send to the Arduino
                comport.Write(start+ "*" + carriageReturn);

                //If the serial port have bytes to read
                if (comport.BytesToRead > 0)
                { 
                    //Buffer with data
                    byte[] dados = HexStringToByteArray(mensage);

                    //Handle data
                    comport.Read(dados, 0, dados.Length);

                    //Send again to execute the the command
                    comport.Write(start + "*" + carriageReturn);
                }

                if (comport.BytesToRead > 0)
                { 
                    comport.Write(start + "*" + carriageReturn);

                    byte[] dados2 = HexStringToByteArray(mensage2);

                    comport.Read(dados2, 0, dados2.Length);

                    comport.Write(text);
                }
                comport.Close();
            }
        }

        catch(Exception ex)
        {
        }
}

private static byte[] HexStringToByteArray(string s)
{
    s = s.Replace(" ", "");
    byte[] buffer = new byte[s.Length / 2];

    for (int i = 0; i < s.Length; i += 2)
        buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
        return buffer;
}

编辑:

我的基本输入输出映射/关系是:

我将发送?*\\r到 Arduino,然后我将等待答案。

如果Arduino 的答案是@r\\r我会再次发送?*\\r

如果Arduino 的答案是@{/r我会向他发送一个字符串。

这是我的修订的第一次尝试。

您应该考虑使用DataReceived事件并有一个退出策略。 到目前为止,您的程序永远不会退出。

static void Main(string[] args)
{
    SerialPort port = new SerialPort("COM1", 9600, Parity.Odd, 7, StopBits.One);
    // register the event
    port.DataReceived += Port_DataReceived;
    //open the port
    port.Open();

    try
    {
        // start the communication
        port.Write("?*\r");

        Console.WriteLine("Waiting for response");

        // Your manual exit strategy. Hit a kKeyboard-key to end this game
        while (!Console.KeyAvailable)
        {
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Writing failed! \nError: " + ex.Message);
    }        
}

DataReceived事件将在 Arduino 向您发送信息后立即触发。 如果没有,您可以手动退出程序。

在事件内部,您可以执行整个逻辑。 由于您已经发布了输入-输出映射,因此您可以将其修改为您在帖子中编写的可靠代码。 如果只有两种情况,您还可以使用 switch/case 结构:

private static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort port = sender as SerialPort;

    // read input
    string incoming = port.ReadExisting();

    switch (incoming)
    {
        case "@r\r":
            // send the message back
            port.Write("?*\r");
            break;
        case @"@{/r":
            port.Write("Display this!");
            break;
        default:
            Console.WriteLine("Unknown command from Arduino!\n Command: " + incoming);
            break;
    }
}

我希望它有帮助

如果我正确理解您的描述(关门将由 arduino 完成,对吗?),这就是任务:

  • 任务计划控制台应用程序通过串行触发 arduino 以检查状态并执行某些操作(如果状态表明这是必要的)
  • Arduino 报告状态(最终该任务已执行)

你可以很简单地做到:

"?" --> PC sends a trigger: Check door status and behave accordingly

然后 PC 等待响应:

"1"  <-- Arduino response ( door was already closed )
"2"  <-- or alternate response ( I closed the door )

Arduino 可以发送任何其他内容来指示错误。 (随意发明尽可能多)

此外,arduino 可能根本没有响应。 那么你预定的控制台应用程序会做什么呢?

您不需要发送/接收超过一个字节的数据,即可让 Arduino 和您的小型串行 PC 代码更简单。

PC 代码没有用户界面,因此如果关门需要一段时间,Arduino 无需立即响应。

暂无
暂无

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

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