C#SerialPort - 奇怪的行为

时间:2012-02-03 12:16:20

标签: c# wpf serial-port

我正在尝试使用串行端口与相机连接。现在,相机有自己的专有协议,相当简单,使用6字节命令和确认。

现在,我正在使用C#来编写与摄像头连接的程序,因为这样我就可以使用WPF了,而且我对C#很满意。

当我尝试将相机设置为检索图像时,我的问题就出现了。当我单步执行程序时,串行端口对象在执行此操作时非常正常。然而,一旦我全速运行,由于某种原因,我最终得到了端口上的消息非常糟糕,甚至错过了。在我开始检索实际数据之前,我已经到了设置过程的结束,并且仍然存在仍在缓冲区中的端口的命令和事物。

现在,无论如何,这个解决方案只是一个非常hacky尝试学习协议并让事情在当下工作,我完全打算稍后改进它,但我无法弄清楚它为什么这样做。在我确认最后一个数据包之前,相机不应该发送下一个数据包,所以我只能假设串口对象有问题,而不是相机或我对协议的处理。

可能是因为我(懒惰地,是的)在UI线程上有这个功能吗?

以下是代码:

private void retreivePhoto()
    {
        progressBar1.Visibility = Visibility.Visible;
        photo = new FileStream(Environment.CurrentDirectory + @"/photos/" + (photoNum++) + ".jpg", FileMode.OpenOrCreate);
        port.Open();
        progressBar1.Value = 0.5;
        setup.theMessage = setup.JPEG();
        port.Write(setup.theMessage, 0, setup.theMessage.Length);
        while (port.BytesToRead < 0) ;
        port.Read(received.theMessage, 0, received.theMessage.Length);
        setup.theMessage = setup.Package();
        port.Write(setup.theMessage, 0, setup.theMessage.Length);
        while (port.BytesToRead < 0) ;
        port.Read(received.theMessage, 0, received.theMessage.Length);
        setup.theMessage = (byte[])Message.SNAPSHOT.Clone();
        port.Write(setup.theMessage, 0, setup.theMessage.Length);
        while (port.BytesToRead < 0) ;
        port.Read(received.theMessage, 0, received.theMessage.Length);
        setup.theMessage = (byte[])Message.BLANK.Clone();
        setup.theMessage[1] = (byte)Message.MessageTypes.GETPICTURE;
        setup.theMessage[2] = (byte)Message.PictureType.SNAPSHOT;
        port.Write(setup.theMessage, 0, setup.theMessage.Length);
        while (port.BytesToRead < 0) ;
        port.Read(received.theMessage, 0, received.theMessage.Length);
        while (port.BytesToRead < 0) ;
        port.Read(received.theMessage, 0, received.theMessage.Length);
        int length = (received.theMessage[5] << 16) + (received.theMessage[4] << 8) + received.theMessage[3];
        length /= data.theMessage.Length-6;
        byte[] temp = {0xaa, 0x0e, 0x00, 0x00, 0x00, 0x00};
        port.DiscardInBuffer();
        port.Write(temp, 0, temp.Length);

        int next = 0;
        int bytes;

        for (int i = 0; i < length; i++)
        {
            if ((bytes = port.BytesToRead) > 0)
            {
                port.Read(data.theMessage, 0, data.theMessage.Length);
                if (bytes < data.theMessage.Length)
                {
                    photo.Write(data.theMessage, 4, bytes - 6);
                }
                else
                {
                    photo.Write(data.theMessage, 4, data.theMessage.Length - 6);
                }
                photo.Flush();
            }


            next = ((data.theMessage[1] << 8) + data.theMessage[0]) + 1;

            byte[] nextBytes = System.BitConverter.GetBytes(next);

            if (length - i == 1)
            {
                temp[4] = temp[5] = 0xf0;
            }
            else
            {
                temp[4] = nextBytes[0];
                temp[5] = nextBytes[1];
            }

            port.Write(temp, 0, temp.Length);
        }

        progressBar1.Value = 1.0;
        photo.Flush();
        photo.Close();
        port.Close();
        progressBar1.Visibility = Visibility.Hidden;

    }

以下是相机的数据表,其中描述了协议。 http://www.4dsystems.com.au/downloads/micro-CAM/Docs/uCAM-DS-rev7.pdf

1 个答案:

答案 0 :(得分:1)

while (port.BytesToRead < 0) ;
port.Read(received.theMessage, 0, received.theMessage.Length);

并不意味着您将读取received.theMessage.Length个字节。它可以是介于1和1之间的任何东西。 received.theMessage.Length。您应该检查返回的值