1

好吧,在过去的 4 天里,我一直在用 C# 中的这个 SerialPort 控件苦苦挣扎,但没有令人满意的结果。让我解释:

我有一个与 ac# prog 通信的设备(Arduino UNO 板),它模拟一个秤(简单的请求/响应模式),设备发送一个由 3 个字节组成的命令序列(要求称重):CHR(27)+P +CHR(13) 所以模拟器以模拟重量响应(我已经整理了设备如何捕获和解析这个重量,所以这不再是问题)。使用 DataReceive 事件似乎我正在使用 Serialport.Read() 丢失数据,所以到目前为止我浪费了这种方法。模拟器必须始终监听所述序列。字节数,并且必须有一个 GUI。

如果需要进一步澄清,我可以提供我到目前为止所做的代码。希望您能对此有所了解。

提前致谢。

更新 1


这是我到目前为止的代码:

ConcurrentQueue<byte> queue = new ConcurrentQueue<byte>();
....
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
   bool listening = true;
   while(listening)
   {
     if(serialPort.BytesToRead > 0)
     {
        byte b = (byte)serialPort.ReadByte();
        queue.Enqueue(b);
     }
   }
}

因此,由于命令必须以字符 13(ASCII 中的 CR)结尾:

public string GetCommand()
{
    string ret = "";
    byte[] ba = new byte[1];
    byte b = (byte)' ';

    while(b!=13)
    {
       if(queue.TryDequeue(out b))
       {
          ba[0] = b;
          ret += ASCIIEncoding.ASCII.GetString([ba]);
       } 
    }
    return ret;
}

为了测试这个 GetCommand() 方法,我在 button_click 事件中从主 ui 线程调用它,但它挂起应用程序,我需要创建另一个线程来调用 GetCommand() 吗?

4

2 回答 2

3

这适用于少量数据。但是如果数据更大,比如传递一些 http 信息,那么队列大小可能不够。所以我认为你应该使用非阻塞类型的架构。

于 2012-11-09T04:02:14.760 回答
1

有关如何实现发送方的信息,请参阅此答案。

对于读取端,使用专用线程,在该线程中从端口读取消息,将其放入合适的并发数据结构(例如ConcurrentQueue)中并立即循环返回以等待来自串行端口的下一个输入。

在单独的线程上使用来自队列的输入。

可能有更有效的方法,但这种方法易于实施且万无一失。

于 2012-04-12T05:32:10.150 回答