3

我必须通过 FTDI RS485 连接器(具有通常的 comport 软件接口)以 1000000 波特率在 Mono 中与设备通信。操作系统 - Linux(Ubuntu ... Mint13 特别是),单声道 2.10.2。

首先我在 Linux 上运行简单的 python 测试程序:

 >> import serial
 >> ser = serial.Serial("/dev/ttyUSB0",1000000, timeout=0.5)
 >> ser.write(":DCS3FF8;")   # Some message to the device with crc
 >> ser.readall()
 ':CDS P0 M0 E0 L1 S07B3B;'  #This is the correct response from the device

 >> print ser
 Serial<id=0x2ce71d0, open=True>(port='/dev/ttyUSB0', baudrate=1000000, bytesize=8, parity='N', stopbits=1, timeout=0.5, xonxoff=False, rtscts=False, dsrdtr=False)

设备正确响应。一切正常。这表明在 Linux 上一切运行良好。

然后我退出 python 并尝试将 Mono 与代码一起使用:

     var serialPort = new SerialPort();
     serialPort.PortName = "/dev/ttyUSB0";
     serialPort.BaudRate = 1000000;

     serialPort.Open();
     serialPort.Write(":DCS3FF8;");
     Thread.Sleep(150);
     Console.WriteLine("BytesToRead: '{0}'", serialPort.BytesToRead);
     Console.WriteLine("Existing   : '{0}'", serialPort.ReadExisting());

使用命令编译并运行它:

     dmcs serial_try.cs && mono serial_try.exe

并得到 TimeoutException,serialPort.BytesToRead 为 0。同时我看到连接器的两个灯都在闪烁(有东西正在传输)。

当我在 Windows 上的 .NET 上运行相同的代码时,它成功地与设备通信并接收到与 python 相同的消息。

那么单声道上的 SerialPort 有什么好处呢?我错过了一些设置或配置吗?

4

1 回答 1

5

在单声道上读取 FTDI 设备的问题被发现是由波特率错误引起的。

错误的想法:如果将波特率设置为大于 921600,则实际波特率设置为 9600。

说起来很有趣(如果您浪费时间试图弄清楚为什么不能在单声道上与 SerialPort 通信),这与一个较旧的错误有关。说明无法设置波特率 921600。所以看起来这个错误被修复到了 921600 而不是更高。

为了解决这个错误,可以在端口打开后调用 stty 来设置实际波特率。所以添加这个函数:

    private void ForceSetBaudRate(string portName, int baudRate)
    {
        if (Type.GetType ("Mono.Runtime") == null) return; //It is not mono === not linux! 
        string arg = String.Format("-F {0} speed {1}",portName , baudRate);
        var proc = new Process
            {
                EnableRaisingEvents = false,
                StartInfo = {FileName = @"stty", Arguments = arg}
            };
        proc.Start();
        proc.WaitForExit();
    }

并在串行打开后立即调用:

    _serialPort.PortName = PortName;
    _serialPort.BaudRate = BaudRate;
    _serialPort.Open();
    ForceSetBaudRate(PortName, BaudRate);

hack 并不漂亮,但最终 FTDI 调制解调器可以在 Mono + Linux 和 .Net + Windows 上运行。

其他解决方法可能是实现您自己的串行端口包装器并对其进行 PInvoking,或者按照@skolima 的建议修复单声道错误。

如果波特率不是 ASCII 则更新,因此不能使用 stty,python 可以用作解决方案。请参阅下面的评论。感谢@Dorian Scholz。

于 2012-11-05T14:58:50.490 回答