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, flow_control = :NONE, data_bits = 8) ⇒ 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, flow_control = :NONE, data_bits = 8) ⇒ PosixSerialDriver
Returns a new instance of PosixSerialDriver.
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 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 28 def initialize(port_name = '/dev/ttyS0', baud_rate = 9600, parity = :NONE, stop_bits = 1, write_timeout = 10.0, read_timeout = nil, flow_control = :NONE, data_bits = 8) # 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 Data Bits: #{data_bits}") unless [5, 6, 7, 8].include?(data_bits) 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.const_get("CS#{data_bits}") # data bits cflags |= Termios::CLOCAL # Ignore Modem Control Lines cflags |= Termios::CSTOPB if stop_bits == 2 cflags |= Termios::PARENB if parity cflags |= Termios::PARODD if parity == :ODD cflags |= Termios::CRTSCTS if flow_control == :RTSCTS 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
85 86 87 88 89 90 91 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 85 def close if @handle # Close the serial Port @handle.close @handle = nil end end |
#closed? ⇒ Boolean
Returns Whether the serial port has been closed.
94 95 96 97 98 99 100 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 94 def closed? if @handle false else true end end |
#read ⇒ String
Returns Binary data read from the serial port.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 128 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.
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 144 def read_nonblock data = '' begin data = @handle.read_nonblock(65535) rescue Errno::EAGAIN, Errno::EWOULDBLOCK # Do Nothing end data end |
#write(data) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/cosmos/io/posix_serial_driver.rb', line 103 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 |