2014-05-06 91 views
2

我正在使用http://ruby-serialport.rubyforge.org/ Ruby gem使用Ruby腳本「驅動程序」來寫入和讀取串行端口。Ruby串行端口超時異常

我想從Windows和Linux操作系統中運行應用程序;順便說一句 ,這裏下面的代碼已在Windows 7

測試具體來說,我必須打印的熱敏打印機上ESC/POS文本數據, 連接到主機計算機與一個串行線(COM/USB端口)。

我沒有任何問題在打印機上打印數據(一流的&便宜的愛普生TM-T20)!

但我必須從設備管理錯誤/連接狀態的讀取數據,

通過例子來看看是否通電(上線)的打印機我會問打印機狀態與某些打印機設備ESC/POS commnads。

問題出現是因爲即使我設置串口超時(我的意思是SerialPort類初始化程序的settimg超時參數),沒有異常處理,這似乎沒有被gem預見到:-(,我無法理解如果打印機是活着還是斷電見的代碼塊:

begin 
    printer = SerialPort.new PRINTER_SERIALPORT_NAME, BAUDRATE 

    # http://curiosity.roguepenguin.net/?p=35 
    # timeouts are in milliseconds 
    printer.read_timeout = 2000 
    printer.write_timeout = 2000 

    puts "Success for SerialPort: #{ printer.inspect }" 

rescue => e 
    puts "Failed to open as SerialPort: #{ e.inspect }" 
end 

通過上面的代碼,在事實退出一個printer.read從2000毫秒..但我不知道是否比預期的,因爲我有少(0)字節回來..或因爲該設備關機..

所以,我嘗試使用Ruby超時(http://ruby-doc.org/stdlib-2.0.0/libdoc/timeout/rdoc/Timeout.html),從Winows 7 shell運行腳本,但不幸的是下面的代碼不能按預期運行(如果打印機關閉,我的意思是根本不會退出:-(,並且我沒有預期的Timeout::Error);不是嗎?

begin 
    Timeout.timeout(2) do 
    puts printer.read 
    end 
rescue Timeout::Error 
    puts "SerialPort timeout." 
rescue => e 
    puts "Serialport ERROR: Failed to open: #{ e.inspect }" 
end 

任何想法來解決這一點?

謝謝

喬治

+0

您正在使用哪個Ruby版本? –

+0

我使用Ruby版本2.0(通過Windows:2.0.0p195) –

+1

好吧 - 只要您使用的是舊版本的Ruby,在某些情況下超時時間不可靠的情況下,您可能會遇到很多困難。 –

回答

0

從我推測,指定read_timeout讀操作時,會立即返回(非阻塞)的文檔,從而從未引起Timeout::Error如你所願。

你可以嘗試設置超時0,根據文檔將阻塞,直到一個字節可用,看看是否會提高Timeout::Error

或嘗試設置沒有超時,看看是否有效。

或者,您可以指定一個負超時,該超時立即返回任何可用數據並根據該超時做出決定。

+0

謝謝Rkon!明天我會在你正確的建議下做更多的測試,並且你會在這裏反饋 –

0

對不起回答我自己的問題,只是分享一些測試,也是繼rkhon建議:

前提: 現在我測試使用Ruby 2。0在Windows 7安裝到使用USB連接PC機愛普生TM-T20打印機(和一個串行端口 - USB愛普生「匹配」)

關於的SerialPort(讀取)超時測試:

如果我設置:
printer.read_timeout <= 0

的SerialPort讀杭(不返回控制)

如果我設置: printer.read_timeout > 0

# read 1 byte 
printer.read(1) 

如果讀取緩衝區中不存在AVAILABLE字節,則在read_timeout毫秒後返回,否則立即返回讀取的字節。 Thta還好!

順便說一句,它似乎是serialport gem超時運行與優先(WINs)對Ruby語言超時支持;這意味着,如果我設置一個printer.read_timeout = 2000後來我做

# 1000 msecs 
Timeout.timeout(1) do 
    puts printer.read 
    end 

但我得到了控制後2000毫秒背...

管理錯誤/連接狀態:即使 我不能使用如果我發送(寫入)打印機的DLE EOT m(STATUS請求),那麼我可以檢查打印機的電源開啓/連接狀態,但沒有明確的超時異常...

我回來了(讀)沒有數據(無)

希望報告可能會有用...