Ruby串行端口超时异常

Ruby串行端口超时异常,ruby,serial-port,timeout,usb,thermal-printer,Ruby,Serial Port,Timeout,Usb,Thermal Printer,我正在使用Ruby脚本“驱动程序”从串行端口写入和读取数据 我想在Windows和Linux操作系统上运行应用程序; 顺便说一句,下面的代码已经在Windows7上测试过了 具体来说,我必须在热敏打印机上打印ESC/POS文本数据, 通过串行线(COM/USB端口)连接到主机 我在打印机上写入数据没有任何问题(一款超级便宜的Epson TM-T20) 但我必须管理从设备读取数据的错误/连接状态 举例来说,如果打印机通电(在线),我会通过一些ESC/POS命令向打印机设备询问打印机状态 出现问题的

我正在使用Ruby脚本“驱动程序”从串行端口写入和读取数据

我想在Windows和Linux操作系统上运行应用程序; 顺便说一句,下面的代码已经在Windows7上测试过了

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

我在打印机上写入数据没有任何问题(一款超级便宜的Epson TM-T20)

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

举例来说,如果打印机通电(在线),我会通过一些ESC/POS命令向打印机设备询问打印机状态

出现问题的原因是,即使我设置了串行端口超时(我是指SerialPort类初始值设定项的settimg timeout参数),但没有异常处理,这似乎是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
使用上面的代码,facts中的
打印机.read
将在2000毫秒后退出..但我不知道是因为我返回的字节少于预期的(0)字节..还是因为设备已关机

因此,我尝试使用Ruby Timeout(),从Winows 7 shell运行脚本,但不幸的是下面的代码没有按预期运行(如果打印机关闭,则
打印机.read
挂起,我的意思是根本不退出:-(,并且我没有预期的
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
有什么办法解决这个问题吗

多谢各位


giorgio

从文档中我收集到,当指定
读取超时时,读取操作将立即返回(非阻塞),因此不会像您预期的那样导致
超时::错误

您是否可以尝试将超时设置为0,根据文档,超时将被阻止,直到一个字节可用,并查看Ruby是否会引发
timeout::Error

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


或者,您可以指定一个负超时,该超时会立即返回任何可用数据,并根据该超时做出决定。

很抱歉回答我的问题,只是为了分享一些测试,还提供了以下建议:

前提: 我现在正在Windows 7上使用Ruby 2.0进行测试,将一台Epson TM-T20打印机通过USB连接(以及一个串行端口——USB Epson“matcher”)连接到电脑上

关于串行端口(读取)超时测试:

如果我设置:
printer.read\u超时0

若读取缓冲区中并没有可用字节,则在读取超时毫秒后返回,否则立即返回读取的字节。 没关系

顺便说一句,似乎serialport gem超时在Ruby语言超时支持下以优先级(WINs)运行;这意味着如果我设置了一个
printer.read\u timeout=2000
,然后我就这样做了

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

要管理错误/连接状态,请执行以下操作: 即使我不能使用异常超时,我也可以在没有显式超时异常的情况下检查打印机的开机/连接状态

我验证了如果我向打印机发送(写入)DLE EOT m(状态请求) 我返回(读取)无数据(无)


希望该报告有用…

您使用的是哪个Ruby版本?我使用的是Ruby 2.0版(在Windows上:2.0.0p195)好的-如果你使用的是旧版Ruby,在某些情况下超时是不可靠的,那就太冒险了。是的,我会使用Ruby releases>=2.0thanks Rkon!明天我会按照你的建议做更多的测试,你会在这里反馈
 # 1000 msecs
 Timeout.timeout(1) do
     puts printer.read
  end