Getting the info from MCP23017 with Python

4.9k views Asked by At

I bought a MCP23017 for my Raspberry Pi to increase the GPIO pins.

enter image description here

I have currently installed it and I'm trying to get the extra pins that I have; GPB0-GPB7 on the left and GPA0-GPA7 on the right to do my bidding.

I need to set them to input pins to read a HIGH and LOW status, and add the pull up resistors to them but this is as far as I have gotten:

import smbus
import time

bus = smbus.SMBus(1) # As I'm using an newer RPi.

DEVICE = 0x20 # this is what it shows when I check it.
IODIRA = 0x00
GPIOA  = 0x12

bus.write_byte_data(DEVICE,IODIRA,0xFF)
bus.write_byte_data(DEVICE,0x0C,0xff)

value = bus.read_byte_data(DEVICE,GPIOA)

When I try to read the value, it gives me strange numbers, and I can barely find any explanation on the Hexidecimals ans the Binary numbers and it's compeltly throwing me off. The datasheet seems like Chinese to me..

Any help would REALLY be appreciated!

1

There are 1 answers

1
AudioBubble On BEST ANSWER

This script will turn on the internal pull-up resistors for GPIOA and GPIOB. Then it will print the values of all the registers once per second. You can use the output to watch the register values change as you change the inputs.

import smbus
import time

DEVICE = 0x20

address_map = {
    0x00: 'IODIRA',   0x01: 'IODIRB',   0x02: 'IPOLA',   0x03: 'IPOLB',
    0x04: 'GPINTENA', 0x05: 'GPINTENB', 0x06: 'DEFVALA', 0x07: 'DEVFALB',
    0x08: 'INTCONA',  0x09: 'INTCONB',  0x0a: 'IOCON',   0x0b: 'IOCON',
    0x0c: 'GPPUA',    0x0d: 'GPPUB',    0x0e: 'INTFA',   0x0f: 'INTFB',
    0x10: 'INTCAPA',  0x11: 'INTCAPB',  0x12: 'GPIOA',   0x13: 'GPIOB',
    0x14: 'OLATA',    0x15: 'OLATB'
}
register_map = {value: key for key, value in address_map.iteritems()}
max_len = max(len(key) for key in register_map)

def print_values(bus):
    print "-" * 20
    for addr in address_map:
        value = bus.read_byte_data(DEVICE, addr)
        print "%-*s = 0x%02X" % (max_len, address_map[addr], value)

bus = smbus.SMBus(1)
bus.write_byte_data(DEVICE, register_map['GPPUA'], 0xFF)
bus.write_byte_data(DEVICE, register_map['GPPUB'], 0xFF)

counter = 0
try:
    while True:
        print_values(bus)
        counter += 1
        print "counter = %s" % counter
        time.sleep(1.0)
except KeyboardInterrupt:
    print "Keyboard interrupt"

Example Output

--------------------
IODIRA   = 0xFF
IODIRB   = 0xFF
IPOLA    = 0x00
IPOLB    = 0x00
GPINTENA = 0x00
GPINTENB = 0x00
DEFVALA  = 0x00
DEVFALB  = 0x00
INTCONA  = 0x00
INTCONB  = 0x00
IOCON    = 0x00
IOCON    = 0x00
GPPUA    = 0xFF
GPPUB    = 0xFF
INTFA    = 0x00
INTFB    = 0x00
INTCAPA  = 0x00
INTCAPB  = 0x00
GPIOA    = 0xFF
GPIOB    = 0xE9
OLATA    = 0x00
OLATB    = 0x00
counter = 3

I am using the MCP23017 on an Adafruit LCD Keypad Kit, so some of the pins are being pulled low by the board.

Understanding the Port Values

Each port has 8 GPIO pins. If all pins for a port are pulled high, the hex value for the port will be 0xFF. If a pin is pulled low, the bit for that pin will be zero. For example, if GPA0 is pulled low, the GPIOA register will have a value of 0xFE:

1111 1110 = 0xFE