Module: I2C::Drivers::MCP230xx
- Defined in:
- lib/i2c/drivers/mcp230xx.rb
Overview
Driver class for the Microchip MPC230xx IO-Expanders.
The interface is mostly compatible to the interface of the WiringPi gem. PWM is not supported though. On the other hand a more rubyesque interface is also provided.
Instance Method Summary collapse
-
#[](pin) ⇒ Integer
(also: #read)
Reads a IO-pin value.
-
#[]=(pin, value) ⇒ Object
(also: #write)
Sets a IO-pin value.
-
#check_pin(pin) ⇒ Object
Checks a pin number for validity.
-
#check_port(no) ⇒ Object
Checks a port number for validity.
-
#initialize(device, address) ⇒ Object
Creates an instance representing exactly one MCP230xx on one I2C-bus.
-
#mode(pin, pin_mode) ⇒ Object
Sets the mode of a IO-pin.
-
#mode?(pin) ⇒ Integer
Reads the mode of a IO-pin.
-
#port_for_pin(pin) ⇒ Array<Integer, Integer>
Returns a port no, index in port pair for a pin number.
-
#set_bit_value(byte, bit, value) ⇒ Integer
Sets a bit in a byte to a defied state not touching the other bits.
Instance Method Details
#[](pin) ⇒ Integer Also known as: read
Reads a IO-pin value.
105 106 107 108 109 110 111 112 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 105 def [](pin) check_pin(pin) # Raises if the pin is not valid index = port_for_pin(pin) @data = @device.read(@address, port_count, gpio[0]).unpack(@unpack_string) index = port_for_pin(pin) (@data[index[0]] >> index[1]) & 0x01 end |
#[]=(pin, value) ⇒ Object Also known as: write
Sets a IO-pin value.
91 92 93 94 95 96 97 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 91 def []=(pin, value) check_pin(pin) # Raises if the pin is not valid raise ArgumentError, 'invalid value' unless [0,1].include?(value) index = port_for_pin(pin) @data[index[0]] = set_bit_value(@data[index[0]], index[1], value) @device.write(@address, gpio[0], *@data) end |
#check_pin(pin) ⇒ Object
Checks a pin number for validity. Raises an exception if not valid. Returns nil otherwise.
122 123 124 125 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 122 def check_pin(pin) raise ArgumentError, "Pin not 0-#{max_pin_no}" unless (0..max_pin_no).include?(pin) nil end |
#check_port(no) ⇒ Object
Checks a port number for validity. Raises an exception if not valid. Returns nil otherwise.
131 132 133 134 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 131 def check_port(no) raise ArgumentError, "Only Ports 0-#{max_port_no} available." unless (0..max_port_no).include?(no) nil end |
#initialize(device, address) ⇒ Object
This implementation currently assumes that all registers of the same type are on a continuos address range. Implement a (less efficient) case for other situations.
Creates an instance representing exactly one MCP230xx on one I2C-bus.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 42 def initialize(device, address) if device.kind_of?(String) @device = ::I2C.create(device) else [ :read, :write ].each do |m| raise IncompatibleDeviceException, "Missing #{m} method in device object." unless device.respond_to?(m) end @device = device end @address = address @iodir = Array.new max_port_no.times { @iodir << 0xFF } # Direction is input initially @device.write(@address, port_count, iodir[0], *@iodir) @data = Array.new max_port_no.times { @data << 0xFF } @unpack_string = "C" * port_count @data = @device.read(@address, port_count, gpio[0]).unpack(@unpack_string) @dir = @device.read(@address, port_count, iodir[0]).unpack(@unpack_string) end |
#mode(pin, pin_mode) ⇒ Object
Sets the mode of a IO-pin.
79 80 81 82 83 84 85 86 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 79 def mode(pin, pin_mode) check_pin(pin) # Raises if the pin is not valid raise ArgumentError, 'invalid value' unless [0,1].include?(pin_mode) index = port_for_pin(pin) @dir[index[0]] = set_bit_value(@dir[index[0]], index[1], pin_mode) @device.write(@address, iodir[0], *@dir) end |
#mode?(pin) ⇒ Integer
Reads the mode of a IO-pin.
68 69 70 71 72 73 74 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 68 def mode?(pin) check_pin(pin) # Raises if the pin is not valid @dir = @device.read(@address, port_count, iodir[0]).unpack(@unpack_string) index = port_for_pin(pin) (@dir[index[0]] >> index[1]) & 0x01 end |
#port_for_pin(pin) ⇒ Array<Integer, Integer>
Returns a port no, index in port pair for a pin number.
E.g. Pin 14 is the is bit 7 of port 1. So the method returns [1,7].
143 144 145 146 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 143 def port_for_pin(pin) check_pin(pin) [pin / 8, pin % 8] end |
#set_bit_value(byte, bit, value) ⇒ Integer
Sets a bit in a byte to a defied state not touching the other bits.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/i2c/drivers/mcp230xx.rb', line 154 def set_bit_value(byte, bit, value) [byte, bit, value].each do |p| raise ArgumentError, "Arguments must be Integer" unless p.kind_of? Integer end raise ArgumentError, "Only bits 0..7 are available." unless bit < 8 raise ArgumentError, "Value needs to be 0 or 1." unless (value == 0) or (value == 1) mask = 0x00 mask = (0x01 << bit) case value when 0 byte = (byte & ((~mask) & 0xFF)) & 0xFF when 1 byte = (byte | mask) & 0xFF else raise ArgumentError, "Bit not 0-7." end byte end |