Ruby Serialport Timeout异常

时间:2014-05-06 08:38:23

标签: ruby serial-port timeout usb thermal-printer

我正在使用SerialPort Ruby gem来编写和读取一个串口,使用Ruby脚本“driver”。

我想从Windows和Linux Os运行该应用程序; 顺便说一句,下面的代码已在Windows 7上测试过。

具体来说,我必须在热敏打印机上打印ESC / POS文本数据, 连接到带有串行线(COM / USB端口)的主机。

我在打印机上写数据时没有任何问题(优质廉价的Epson TM-T20)!

但我必须管理错误/连接状态从设备读取数据,

通过示例查看打印机是否打开电源(在线)我会通过某些ESC / POS通讯向打印机设备询问打印机状态。

问题出现的原因是,即使我设置串口超时(我的意思是SerialPort类初始化程序的settimg超时参数),没有异常处理,这似乎没有宝石预见:-(,我无法理解是否打印机处于活动状态或已关闭电源。请参阅一大堆代码:

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 Timeout(http://ruby-doc.org/stdlib-2.0.0/libdoc/timeout/rdoc/Timeout.html),从Winows 7 shell运行脚本,但不幸的是下面的代码没有按预期运行(如果打印机关闭,printer.read HANG ,我的意思是不要退出:-(,我没有预期的Timeout::Error); stange不是吗?

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

有什么想法解决问题吗?

谢谢

乔治

2 个答案:

答案 0 :(得分:0)

从我收集的文档中我指出,当指定read_timeout时,读取操作将立即返回(非阻塞),因此永远不会像您期望的那样导致Timeout::Error

你能尝试设置0的超时,根据文档将阻塞,直到一个字节可用,看看Ruby是否会引发Timeout::Error

或者尝试根本不设置超时,看看是否有效。

或者你可以指定一个否定超时,它会立即返回任何可用的数据,并根据它做出决定。

答案 1 :(得分:0)

抱歉回答自己的问题,只是为了分享一些测试,也遵循rkhon的建议:

前提: 我现在正在使用带有USB连接的PC上的Epson TM-T20打印机在Windows 7上使用Ruby 2.0进行测试(以及串行端口 - USB Epson" matcher")

关于SerialPort(读取)超时测试:

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

serialport read hang(不返回控件)

如果我设置: printer.read_timeout > 0

# read 1 byte 
printer.read(1)
如果读缓冲区中没有AVAILABLE字节,则在read_timeout毫秒后返回

,否则立即返回读取的字节。 好的!

BTW,似乎串口宝石超时运行优先级(WIN)与Ruby语言超时支持;这意味着,如果我设置printer.read_timeout = 2000,之后我会

 # 1000 msecs
 Timeout.timeout(1) do
     puts printer.read
  end
然而,我在2000毫秒后得到了控制权......

管理错误/连接状态: 即使我不能使用异常超时,我也可以检查打印机的电源开启/连接状态,而且没有明确的超时异常...

我验证了如果我向打印机发送(写入)DLE EOT m(STATUS请求) 我回来了(读)没有数据(无)

希望报告有用......