2012-11-03 88 views
2

我必須通過FTDI RS485連接器(具有通常的comport軟件接口)以1000000波特率在Mono中與設備進行通信。操作系統 - Linux(Ubuntu的... Mint13要特別),單聲道2.10.2。Mono Linux上使用串口的高波特率時的錯誤

首先,我在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上一切正常。

然後我退出蟒蛇,並嘗試使用單聲道與代碼:

 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相同的代碼,它通信成功與設備,並收到同一消息與蟒蛇。

那麼單聲道上的SerialPort有什麼問題呢?我錯過了一些設置或配置嗎?

+0

這些事件沒有實現,而且在寫入/讀取扁平字符串之前(MS.NET也是這樣,因爲它不允許自定義編碼),所以遇到問題 - 您是否嘗試寫入字節[]? – skolima

+0

是的。我檢查過了。一切都很好。 – MajesticRa

+0

然後,您需要查看https://github.com/mono/mono/blob/master/support/serial.c和https://github.com/mono/mono/tree/master/mcs /class/System/System.IO。端口,並嘗試自己修復文本編碼層,恐怕。 – skolima

回答

4

讀取單聲道FTDI設備的問題被發現是由bug with baud rate造成的。

錯誤的想法:如果一個設置波特率磨碎機比921600的實際波特率設置爲9600

搞笑地說(如果你浪費你的時間試圖弄清楚爲什麼你無法交流與串行端口在單聲道),這是有關older bug。在不可能設定波特率921600的情況下。所以它看起來像這個bug被修正到了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調制解調器工作在單+的Linux和.Net + Windows操作系統。

其他解決方法可能是在實現您自己的串行端口封裝和PInvoking它或修復單聲道錯誤爲@skolima建議。

更新如果波特率是非ASCII的,所以不能使用stty,python可以作爲解決方案。見下面的評論。感謝@Dorian Scholz。

+1

感謝您的支持,它幫助我獲得了Repetier Host 3D打印軟件與Linux上的Solidoodle 2打印機配合使用。 我必須修改一下你的解決方法,因爲打印機運行在250000波特上,這是非ansi,因此不被stty支持。 但是使用python作爲可執行文件和一個最小腳本作爲參數它工作得很好: string arg = String.Format(「 - c \」import serial; serial.Serial('{0}',{1})\「 「,port,baudRate); –

相關問題