Code Monkey home page Code Monkey logo

rubyserial's Introduction

rubyserial

RubySerial is a simple Ruby gem for reading from and writing to serial ports.

Unlike other Ruby serial port implementations, it supports all of the most popular Ruby implementations (MRI, JRuby, & Rubinius) on the most popular operating systems (OSX, Linux, & Windows). And it does not require any native compilation thanks to using RubyFFI https://github.com/ffi/ffi.

The interface to RubySerial should be (mostly) compatible with other Ruby serialport gems, so you should be able to drop in the new gem, change the require and use it as a replacement. If not, please let us know so we can address any issues.

Build Status Build status Test Coverage

Installation

$ gem install rubyserial

Usage

require 'rubyserial'
serialport = Serial.new '/dev/ttyACM0' # Defaults to 9600 baud, 8 data bits, and no parity
serialport = Serial.new '/dev/ttyACM0', 57600
serialport = Serial.new '/dev/ttyACM0', 19200, 8, :even

Methods

write(data : String) -> Int

Returns the number of bytes written. Emits a RubySerial::Error on error.

read(length : Int) -> String

Returns a string up to length long. It is not guaranteed to return the entire length specified, and will return an empty string if no data is available. Emits a RubySerial::Error on error.

getbyte -> Fixnum or nil

Returns an 8 bit byte or nil if no data is available. Emits a RubySerial::Error on error.

RubySerial::Error

A wrapper error type that returns the underlying system error code and inherits from IOError.

Running the tests

The test suite is written using rspec, just use the rspec command.

Test dependencies

To run the tests on OS X and Linux, you must also have the socat utility program installed.

Installing socat on OS X

brew install socat

Installing socat on Linux

sudo apt-get install socat

Test on Windows

To run the tests on Windows requires com0com which can be downloaded from here:

https://github.com/hybridgroup/rubyserial/raw/appveyor_deps/setup_com0com_W7_x64_signed.exe

License

Apache 2.0. See LICENSE for more details.

rubyserial's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubyserial's Issues

Using blocks in gets

Hello guys,

What do you think of giving the possibility of using blocks in the function gets?

Simple example:

def gets(sep=$/, limit=nil)
  if block_given?
    loop do
      yield(gets_p(sep,limit))
    end
  else
    gets_p(sep, limit)
  end
end

private

def gets_p(sep, limit)
  sep = "\n\n" if sep == ''
  # This allows the method signature to be (sep) or (limit)
  (limit = sep; sep="\n") if sep.is_a? Integer
  bytes = []
  loop do
    current_byte = getbyte
    bytes << current_byte unless current_byte.nil?
    break if (bytes.last(sep.bytes.to_a.size) == sep.bytes.to_a) || ((bytes.size == limit) if limit)
  end

  bytes.map { |e| e.chr }.join
end

Use:

serial.gets do |value|
end

or

serial.gets

ERROR_SEM_TIMEOUT (semaphore timeout) when using with Windows 10 and Ruby from RubyInstaller

Related to synthead/timex_datalink_client#308.

When using Ruby from RubyInstaller running Windows 10, rubyserial raises ERROR_SEM_TIMEOUT (RubySerial::Error) while using an example script with the timex_datalink_client gem. This is a semaphore timeout in Windows that appears to be raised from FFI. This is while using a Teensy LC as a serial device.

Here is the exception:

C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/rubyserial-0.6.0/lib/rubyserial/windows.rb:73:in `write': ERROR_SEM_TIMEOUT (RubySerial::Error)
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client/notebook_adapter.rb:35:in `block (2 levels) in write'
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client/notebook_adapter.rb:32:in `each'
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client/notebook_adapter.rb:32:in `block in write'
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client/notebook_adapter.rb:31:in `each'
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client/notebook_adapter.rb:31:in `write'
        from C:/Ruby32-x64/lib/ruby/gems/3.2.0/gems/timex_datalink_client-0.12.1/lib/timex_datalink_client.rb:113:in `write'
        from ./timexTest.rb:132:in `<main>'

Steps to reproduce:

  1. Have a Windows 10 machine handy with Ruby installed from RubyInstaller.
  2. Install the timex_datalink_client gem at version 0.12.1.
  3. Have a serial device ready. (Note: The timex_datalink_client gem only writes data to the device, so any arbitrary serial device will work. If you want, you can use a Teensy LC and flash it with https://github.com/synthead/timex-datalink-arduino/releases/tag/v1.0.0 if you want an exact reproduction case.)
  4. Copy the complete code example for Timex Datalink protocol 1 to a file, and run it with Ruby.
  5. Observe the error above.

9-bit support

Some rare protocols (like MDB) supports 9-bit. Can somebody change this gem for supporting 9 bits too?

Windows not correctly handling number of bytes read

If reading 723 bytes (0x2d3) from the serial port, the interpreted value from the .unpack(H4) processing will be 0xd302 (54018 bytes), causing an out-of-bounds crash in the buff.get_bytes call. Issue found on 64-bit Windows 7 with Ruby 2.0.0

Serial#gets("\r") does not work with ruby 1.9.3 and Windows

In ruby 1.9.3 String#bytes returns an enumerator, not an array as in ruby 2.1.
Because of that the first condition in line 86 in windows.rb will never return true.

The following slight modification to line 86 in windows.rb will make the code work with 1.9.3 as well:
break if (bytes.last(sep.bytes.to_a.size) == sep.bytes.to_a) || ((bytes.size == limit) if limit)

Enhancement Request: Allow for easier opening of COMx (x>=10) on Windows

I'm using rubyserial 0.2.1.

Currently, when using rubyserial on Windows I get the following results when opening a serial port:

irb(main):001:0> require 'rubyserial'
=> true
irb(main):002:0> ser1=Serial.new("COM8")
=> #<Serial:0x000000024ecc88 @fd=#<FFI::Pointer address=0x00000000000098>, @open=true>
irb(main):003:0> ser2=Serial.new("COM17")
RubySerial::Exception: ERROR_FILE_NOT_FOUND
        from C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/rubyserial-0.2.1/lib/rubyserial/windows.rb:10:in `initialize'
        from (irb):3:in `new'
        from (irb):3
        from C:/Ruby21-x64/bin/irb:11:in `<main>'
irb(main):004:0> ser2=Serial.new("\\\\.\\COM17")
=> #<Serial:0x0000000329a448 @fd=#<FFI::Pointer address=0x0000000000009c>, @open=true>

Arguably it is my mistake that opening COM17 fails the first time, but it seems asymmetric to me that it works with COM8.

I added the following line to windows.rb and this seems to work:
added this to Serial#initialize (windows.rb, line 5)
address = "\\\\.\\#{address}" # needed for com-ports >= COM10

Now the behavior is symmetric:

irb(main):001:0> require 'rubyserial'
=> true
irb(main):002:0> ser1=Serial.new( "COM8" )
=> #<Serial:0x00000002dd7640 @fd=#<FFI::Pointer address=0x00000000000098>, @open=true>
irb(main):003:0> ser2=Serial.new( "COM17" )
=> #<Serial:0x0000000341a2f0 @fd=#<FFI::Pointer address=0x0000000000009c>, @open=true>

Adding the prefix multiple times doesn't seem to matter (I've tried it), so it should be safe to blindly add the prefix by default as I did.

Maybe this could be added in the next release.

Add support for disabling flow control

I'd like to disable flow control for a serial port I am using with rubyserial on OSX. Is this possible today? If so, how?

If not possible today, I'd like to implement it.

Exception Overkill

Why does RubySerial::Exception inherit from Exception instead of StandardError?

I thought Exception class should be used when further program execution is discouraged or impossible but I get this kind of exception-level for file not found.

Serial doesn't play nice with File on Win8

I'm working on a simple script to send a data file to a microcontroller and then display whatever the micro sends back. The current test-firmware simply echoes every byte that it gets over the UART, but ultimately it's supposed to process the bytes and return the results.

It seems that if I open the serial port before opening the data file, the port gets hung up. But, if I read the file into memory, and close it, before opening the port, everything works fine.

I'm probably doing something wrong here, but I'm not seeing it. Any ideas?

This is the script that doesn't work...

require 'rubyserial'

puts "Hello world"

serialport = Serial.new 'COM4', 125000

Thread.new do
    loop { printf("%c", serialport.read(1)) }
end

File.open('data/sim-data-01.txt') {|f|}

5.times { serialport.write('a') }   # This should be echoed by the micro

loop do 
end

But, this version works just fine...

require 'rubyserial'

puts "Hello world"

File.open('data/sim-data-01.txt') {|f|}

serialport = Serial.new 'COM4', 125000

Thread.new do
    loop { printf("%c", serialport.read(1)) }
end

5.times { serialport.write('a') }   # This should be echoed by the micro

loop do
end

The only difference between the two is the location of the call to File.open.

Here's the output of ruby -v:
ruby 2.1.5p273 (2014-11-13 revision 48405) [x64-mingw32]

Not able to open Comx on Windows 8.1

Hi

I am trying to open port on windows 8.1

irb(main):001:0> require 'rubyserial'
=> true
irb(main):002:0> ser1=Serial.new("COM1")
RubySerial::Exception: ERROR_FILE_NOT_FOUND
from C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rubyserial-0.2.4/lib/rubyserial/windows.rb:10:in initialize' from (irb):2:innew'
from (irb):2
from C:/Ruby22-x64/bin/irb:11:in `

'irb(main):003:0>

I have tried with this way also as mentioned in the below link

#22

has anyone faced this issue on windows 8.1 ?.

thanks

flush buffers

Hi,

The library offers some kind of flushing?

SerialPort provides flush_input and flush_output, I'm considering migrate to rubyserial.

How do you handle this situations? Are they of little use?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.