首页 文章

Ruby Serialport Timeout异常

提问于
浏览
2

我正在使用http://ruby-serialport.rubyforge.org/ 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

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

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

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

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

  • 0

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

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

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

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

    serialport读挂(不返回控件)

    如果我设置: printer.read_timeout > 0

    # read 1 byte 
    printer.read(1)
    

    如果读缓冲区中没有AVAILABLE字节,则在read_timeout毫秒后返回,否则立即返回读取的字节 . 没关系!

    顺便说一句,看起来串口宝石超时运行优先级(WIN)对Ruby语言超时支持;这意味着,如果我设置 printer.read_timeout = 2000 ,然后我做

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

    不过我在2000毫秒后得到了控制权......

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

    我验证了如果我向打印机发送(写入)DLE EOT m(STATUS请求),我会回来(读取)NO DATA(nil)

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

相关问题