Class: Cosmos::PosixSerialDriver
- Defined in:
- lib/cosmos/io/posix_serial_driver.rb
Overview
Serial driver for use on Posix serial ports found on UNIX based systems
Instance Method Summary collapse
-
#close ⇒ Object
Disconnects the driver from the comm port.
-
#closed? ⇒ Boolean
Whether the serial port has been closed.
-
#initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil) ⇒ PosixSerialDriver
constructor
A new instance of PosixSerialDriver.
-
#read ⇒ String
Binary data read from the serial port.
-
#read_nonblock ⇒ String
Binary data read from the serial port.
- #write(data) ⇒ Object
Constructor Details
#initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil) ⇒ PosixSerialDriver
Returns a new instance of PosixSerialDriver.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 21 def initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil) # Convert Baud Rate into Termios constant begin baud_rate = Object.const_get("Termios::B#{baud_rate}") rescue NameError raise(ArgumentError, "Invalid Baud Rate, Not Defined by Termios: #{baud_rate}") end # Verify Parameters raise(ArgumentError, "Invalid parity: #{parity}") if parity and !SerialDriver::VALID_PARITY.include?(parity) raise(ArgumentError, "Invalid Stop Bits: #{stop_bits}") unless [1,2].include?(stop_bits) @write_timeout = write_timeout @read_timeout = read_timeout parity = nil if parity == :NONE # Open the serial Port @handle = Kernel.open(port_name, File::RDWR | File::NONBLOCK) flags = @handle.fcntl(Fcntl::F_GETFL, 0) @handle.fcntl(Fcntl::F_SETFL, flags & ~File::NONBLOCK) @handle.extend Termios # Configure the serial Port tio = Termios::new_termios() iflags = 0 iflags |= Termios::IGNPAR unless parity cflags = 0 cflags |= Termios::CREAD # Enable receiver cflags |= Termios::CS8 # 8-bit bytes cflags |= Termios::CLOCAL # Ignore Modem Control Lines cflags |= Termios::CSTOPB if stop_bits == 2 cflags |= Termios::PARENB if parity cflags |= Termios::PADODD if parity == :ODD tio.iflag = iflags tio.oflag = 0 tio.cflag = cflags tio.lflag = 0 tio.cc[Termios::VTIME] = 0 tio.cc[Termios::VMIN] = 1 tio.ispeed = baud_rate tio.ospeed = baud_rate @handle.tcflush(Termios::TCIOFLUSH) @handle.tcsetattr(Termios::TCSANOW, tio) end |
Instance Method Details
#close ⇒ Object
Disconnects the driver from the comm port
73 74 75 76 77 78 79 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 73 def close if @handle # Close the serial Port @handle.close @handle = nil end end |
#closed? ⇒ Boolean
Returns Whether the serial port has been closed.
82 83 84 85 86 87 88 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 82 def closed? if @handle false else true end end |
#read ⇒ String
Returns Binary data read from the serial port.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 115 def read begin data = @handle.read_nonblock(65535) rescue Errno::EAGAIN, Errno::EWOULDBLOCK result = IO.fast_select([@handle], nil, nil, @read_timeout) if result retry else raise Timeout::Error, "Read Timeout" end end data end |
#read_nonblock ⇒ String
Returns Binary data read from the serial port.
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 131 def read_nonblock data = '' begin data = @handle.read_nonblock(65535) rescue Errno::EAGAIN, Errno::EWOULDBLOCK # Do Nothing end data end |
#write(data) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 91 def write(data) num_bytes_to_send = data.length total_bytes_sent = 0 bytes_sent = 0 data_to_send = data loop do begin bytes_sent = @handle.write_nonblock(data_to_send) rescue Errno::EAGAIN, Errno::EWOULDBLOCK result = IO.fast_select(nil, [@handle], nil, @write_timeout) if result retry else raise Timeout::Error, "Write Timeout" end end total_bytes_sent += bytes_sent break if total_bytes_sent >= num_bytes_to_send data_to_send = data[total_bytes_sent..-1] end end |