pyLCD
pyLCD copied to clipboard
MCP23017 IO Expander
Hi,
I've just done a quick clone/convert for a backend for the MCP23017 GPI expander chip, use it as you will. It's not been tested or checked in any way yet as I'm not near my pi - just came across your code and liked it, so will be using it for my project, plus my little addition!
Notes: Needs some code to read and set individual pins as input/output instead of all at once, and there is unfortunately no PWM available AFAIK for the chip.
class MCP23017Backend:
# For the 16 pin MCP23017 (can also be used for the 8 pin version, but need to check for lack of pins
# useful quick reference for the pin definitions that you can use in the pinmap
a = [(0x12, 0), (0x12, 1), (0x12, 2), (0x12, 3), (0x12, 4), (0x12, 5), (0x12, 6), (0x12, 7)]
b = [(0x13, 0), (0x13, 1), (0x13, 2), (0x13, 3), (0x13, 4), (0x13, 5), (0x13, 6), (0x13, 7)]
def __init__(self, display, pinmap, bus_id, address): # bus_id is the i2c interface, address is 0x20/21/22 etc. (hex address of i2c address )
self.display = display
try:
import smbus
from time import sleep
self.bus = smbus.SMBus(bus_id)
except:
raise IOError("Could not export the MCP23017. Make sure that you have the smbus library installed, run as root and are on a Raspberry Pi.")
self.address = address.
self.reverse_pinmap = dict([(value, key) for key, value in pinmap.iteritems()])
self.bus.write_byte_data(self.address, 0x00, 0) # 1 is for input
self.bus.write_byte_data(self.address, 0x01, 0) # 1 is for input
def high(self, output):
value = self.bus.read_byte_data(self.address, register)
value |= (1 << pin)
self.bus.write_byte_data(self.address, register, value)
def low(self, output):
value = self.bus.read_byte_data(self.address, register)
value &= ~(1 << pin)
self.bus.write_byte_data(self.address, register, value)
def pulse(self, output):
self.high(output)
time.sleep(0.001)
self.low(output)
def all_low(self):
for output in self.reverse_pinmap.keys():
self.low(output)
def write_nibble(self, nibble, data = True):
self.write_bit(self.PIN_RS, data)
self.write_bit(self.PIN_D4, nibble[3])
self.write_bit(self.PIN_D5, nibble[2])
self.write_bit(self.PIN_D6, nibble[1])
self.write_bit(self.PIN_D7, nibble[0])
def write_bit(self, pin, bit):
if (bit):
self.high(pin)
else:
self.low(pin)
def write_byte(self, byte, data = True):
self.write_bit(self.PIN_RS, data)
for i in range(8):
self.write_bit(getattr(self, "PIN_D%i" % i), byte[i])
def set_brightness(self, level):
assert level >= 0
assert level <= 1023
self.display.brightness = level
self.write_bit(self.PIN_LED, level > 0)
Well, just take your time and test it! Seems great!
Hi @kolonuk, how about a pull request? Is it running stable? (For help see https://help.github.com/articles/about-pull-requests/)