3

1000000ボーレートでFTDIRS485コネクタ(通常のcomportソフトウェアインターフェイスを備えています)を介してデバイスとMonoで通信する必要があります。OS-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と同じメッセージを受信します。

では、モノラルのシリアルポートの欠点は何ですか?設定や設定が足りませんか?

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);

このハックは美しくはありませんが、最終的にFTDIモデムはMono+Linuxおよび.Net+Windowsで動作します。

他の回避策は、独自のシリアルポートラッパーを実装してそれをPInvokingするか、@skolimaが提案したようにモノラルバグを修正することです。

ボーレートがASCII以外で、sttyを使用できない場合は更新します。解決策として、Pythonを使用できます。以下のコメントを参照してください。@DorianScholzに感謝します。

于 2012-11-05T14:58:50.490 に答える