SerialPort 类和 DataReceived 事件...获取字节。使用 ReadLine 还是 ReadExisting?有什么例子吗?

发布于 2024-10-03 16:20:33 字数 1890 浏览 0 评论 0原文

我想通过串行发送和接收字节。我的接收器应该异步获取字节。我写了下面的小例子,看起来可行,但它给我留下了一种不安的感觉。

  1. 我真的应该使用 WriteLine、ReadLine 吗?正如现在所写,是否有可能为每个字节调用事件处理程序 m_port_DataReceived 中的代码?这就是我对“DataReceived”事件的理解;也许我错了。 ReadLine 会阻塞直到看到行尾字符吗?

  2. 我应该在事件处理程序中使用“if (e.EventType == SerialData.Eof)”构造吗?你可以看到我已经把它注释掉了。我尝试过但无法让它工作。什么时候会出现 SerialData.Eof?我的想法是,我可以在所有字节都存在之前等待,然后再调用“ReadExisting”。然而,“if”语句从未评估为 true。但是,强制代码转到 ReadExisting 确实正确读取了所有字节。

  3. 一般来说,设置代码以接收来自串行端口的字节的最佳方法是什么?发送方将每 125 毫秒发送小块字节,但不会发送特殊字符。字节数据包在时间上是间隔开的,所以我认为不存在将数据包混合在一起的问题。更严重的问题是,“一旦你看到一个字节,就去读取所有内容,只要你等待很短的时间,你就会得到所有内容”。在这种情况下,是否有首选方法?

提前致谢, 戴夫

public class SerialPortController
{
    SerialPort m_port;

    public SerialPortController(bool server)
    {


        if (server)
        {
            m_port = new SerialPort("COM4"); 
            m_port.BaudRate = 115200;
            m_port.Open();
            byte[] sillyBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
            ASCIIEncoding encoding = new ASCIIEncoding();
            string output_string = encoding.GetString(sillyBytes);
            m_port.WriteLine(output_string);
            //m_port.Write(sillyBytes, 0, 8);                  
        }
        else
        {
            m_port = new SerialPort("COM5"); 
        m_port.DataReceived += new SerialDataReceivedEventHandler(m_port_DataReceived);
            m_port.BaudRate = 115200;
            m_port.Open();
        }
        int character = Console.Read();
    }

    void m_port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //if (e.EventType == SerialData.Eof)
        {
           // string answer = m_port.ReadExisting();
            string answer = m_port.ReadLine();
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] byte_answer = encoding.GetBytes(answer);

        }
    }
}

I would like to send and receive bytes over serial. My receiver should get the bytes asynchronously. I've written the small example below that appears to work, but it leaves me with an unsettled feeling.

  1. Should I really be using WriteLine, ReadLine? As it's written now, is it possible that the code in the event handler m_port_DataReceived is going to be called for each and every byte? That was my understanding of the event "DataReceived"; perhaps I'm wrong. Does ReadLine block until it sees an end of line character?

  2. Should I somehow use the "if (e.EventType == SerialData.Eof)" construct in the event handler? You can see I have it commented out. I tried it and could not get it to work. When would one expect a SerialData.Eof? My idea was that I could wait before all bytes were present before calling "ReadExisting". However, the "if" statement never evaluated to true. Force the code to go to ReadExisting did correctly read all the bytes however.

  3. In general, what's the best way to set up my code to receive bytes coming over the serial port? The sender will be sending small chunks of bytes every 125 msecs, but will not be sending special characters. The packets of bytes are spaced out in time, so I don't think there's a problem of mixing packets together. More the problem is, "once you see one byte, go read everything, as long as you wait a very short time, you'll get everything". Given this scenario, is there a preferred way?

Thanks in advance,
Dave

public class SerialPortController
{
    SerialPort m_port;

    public SerialPortController(bool server)
    {


        if (server)
        {
            m_port = new SerialPort("COM4"); 
            m_port.BaudRate = 115200;
            m_port.Open();
            byte[] sillyBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
            ASCIIEncoding encoding = new ASCIIEncoding();
            string output_string = encoding.GetString(sillyBytes);
            m_port.WriteLine(output_string);
            //m_port.Write(sillyBytes, 0, 8);                  
        }
        else
        {
            m_port = new SerialPort("COM5"); 
        m_port.DataReceived += new SerialDataReceivedEventHandler(m_port_DataReceived);
            m_port.BaudRate = 115200;
            m_port.Open();
        }
        int character = Console.Read();
    }

    void m_port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //if (e.EventType == SerialData.Eof)
        {
           // string answer = m_port.ReadExisting();
            string answer = m_port.ReadLine();
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] byte_answer = encoding.GetBytes(answer);

        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぺ禁宫浮华殁 2024-10-10 16:20:33

MSDN 中有示例这显示了这个的简单用法。

它使用 ReadExisting 而不是 ReadLine。

还来自文档:

不保证每个接收到的字节都会引发 DataReceived 事件。使用 BytesToRead 属性确定缓冲区中剩余多少数据需要读取。

private static void DataReceviedHandler(
                    object sender,
                    SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    Console.WriteLine("Data Received:");
    Console.Write(indata);
}

There´s and example at MSDN which shows simple use of this.

And it used ReadExisting instead of ReadLine.

Also from the docs:

The DataReceived event is not guaranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer.

private static void DataReceviedHandler(
                    object sender,
                    SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    Console.WriteLine("Data Received:");
    Console.Write(indata);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文