【问题标题】:C# streaming large file through serialPort to an Arduino UNOC#通过serialPort将大文件流式传输到Arduino UNO
【发布时间】:2017-05-24 14:32:25
【问题描述】:

我想通过串行端口将包含 G 代码的文本文件流式传输到 Arduino UNO。

Arduino 通过 SerialEvent 接收所有字节,并将其添加到名为 buffer 的 char 数组中。如果缓冲区已满,它应该发送一个“!;”通过串行端口到 C#。 这很好用,因为我已经使用 Arduino IDE 的 Serial Montior 应用程序对其进行了测试。但我不能像 C# 发送它那样快地输入文本:)

C# 程序逐行读取 G 代码文件,然后将一行中的每个字符发送到 arduino。在每个字符之后,我想检查 Arduino 是否告诉我缓冲区是否已满。否则继续流式传输。

不知何故,c# 从来没有注意到“!;”甚至在流式传输时从 Arduino 读取任何字节。我感觉 serialPort.Write() 函数阻塞了端口。

这是 Arduino 代码:

void serialEvent()
{
  // wenn im Puffer noch platz ist
  if (buffercount < MAX_BUF)
  {
    char c = (char)Serial.read();
    buffer[buffercount++] = c;
  }
  else
  {
    Serial.print("!;");
  }
}

每次 Arduino 在端口上接收字节时都会触发 serialEvent。 Max_BUF 的值为 64。

这是 C# 代码:

private void startStreaming(string Text)
{
    string[] stringSeparators;
    string Text2Stream;

    if (Text == "")
    {
        Text2Stream = File.ReadAllText(textBoxSelectFile.Text);
        stringSeparators = new string[] { "\n" };
    }
    else
    {
        stringSeparators = new string[] { "\r\n" };
        Text2Stream = Text;
    }

    string[] t2s = Text2Stream.Split(stringSeparators, StringSplitOptions.None);
    foreach (string zeile in t2s)
    {

        if (zeile.Contains(")") || zeile.Contains("("))
        {
            continue;
        }

        // Code schicken
        foreach (char c in zeile)
        {
            if (c == ' ') continue;
            serialPort.Write(c.ToString());
            if (serialPort.BytesToRead > 0)
            {
                if(serialPort.ReadExisting() == "!;")
                   {
                    **wait and do smth.**
                   }
            }
        }
        serialPort.Write(";");
        addTextToLog(zeile);

    }
}

serialPort.ReadExisiting() 永远不会发生,因为从来没有BytesToRead。 这 ”;”既是行尾的标志。 startStreaming 在异步线程中以BackGroundWorker 启动。

【问题讨论】:

    标签: c# arduino serial-port streaming communication


    【解决方案1】:

    不知何故,c# 从来没有注意到“!;”甚至在流式传输时从 Arduino 读取任何字节。我感觉 serialPort.Write() 函数阻塞了端口。

    Write 命令没有阻塞端口。 arduino 比你的电脑慢得多。所以在这两行之间:

    serialPort.Write(c.ToString());
    
    if (serialPort.BytesToRead > 0)
    

    arduino 已被占用,尚未收到任何数据。因此BytesToRead0。我马上想到了两种解决方法。

    1) 使用serialPort.DataReceived 事件进行异步处理。每次接收数据时都会触发此事件。然后您可以对该事件中收到的数据做出反应,或者

    2) 给 arduino 一些时间System.Threading.Thread.Sleep(1000);

    serialPort.Write(c.ToString());
    System.Threading.Thread.Sleep(1000);
    if (serialPort.BytesToRead > 0)
    

    您需要找出等待的最短时间跨度。

    【讨论】:

    • 听起来很合法,但是当 C# 应用程序继续流式传输时,它从来没有收到任何东西。我认为您的答案可能是正确的,但我很好奇它是否因此 100% 正确。如果我继续流式传输,则没有响应。
    • 我已经用你提到的 sleep() 对其进行了测试,但这也无济于事:(也许我在 arduino 方面遗漏了一些东西?
    • 如果我告诉 Arduino 在收到一个也不起作用的字节后将 smth 写入 serialPort。 char c = (char)Serial.read();缓冲区[缓冲区计数++] = c; Serial.print("L");
    • 您是否尝试过将收到的字符立即发送回计算机?这行得通吗?
    • 在 Arduino 方面,我删除了将字符添加到缓冲区的部分。所以它也不会做任何工作。然后我添加了一条线,它将接收到的字符立即发送回去,这就像一个魅力。我什至不需要在 C# 中添加睡眠。也许我的 arduino 代码有问题……我会及时通知您。
    猜你喜欢
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多