Skip to content

Commit c56a932

Browse files
author
Sylvan Butler
committed
basic PCF8574 functionality
1 parent af4a24b commit c56a932

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

Adafruit_GPIO/PCF8574.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
'''
2+
Adafruit compatible using BaseGPIO class to represent a PCF8574/A IO expander
3+
Copyright (C) 2015 Sylvan Butler
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6+
associated documentation files (the "Software"), to deal in the Software without restriction,
7+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
8+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all copies or substantial
12+
portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
'''
20+
21+
import Adafruit_GPIO as GPIO
22+
import Adafruit_GPIO.I2C as I2C
23+
24+
25+
26+
IN = GPIO.IN
27+
OUT = GPIO.OUT
28+
HIGH = GPIO.HIGH
29+
LOW = GPIO.LOW
30+
31+
32+
class PCF8574(GPIO.BaseGPIO):
33+
"""Class to represent a PCF8574 or PCF8574A GPIO extender. Compatible
34+
with the Adafruit_GPIO BaseGPIO class so it can be used as a custom GPIO
35+
class for interacting with device.
36+
"""
37+
38+
NUM_GPIO = 8
39+
40+
def __init__(self, address, i2c=None, **kwargs):
41+
address = int(address)
42+
self.__name__ = \
43+
"PCF8574" if address in range(0x20, 0x28) else \
44+
"PCF8574A" if address in range(0x38, 0x40) else \
45+
"Bad address for PCF8574(A): 0x%02X not in range [0x20..0x27, 0x38..0x3F]" % address
46+
if self.__name__[0] != 'P':
47+
raise ValueError(self.__name__)
48+
# Create I2C device.
49+
if i2c is None:
50+
i2c = I2C
51+
self._device = i2c.get_i2c_device(address, **kwargs)
52+
# Buffer register values so they can be changed without reading.
53+
self.iodir = 0xFF # Default direction to all inputs is in
54+
self.gpio = 0x00
55+
self._write_pins()
56+
57+
58+
def _write_pins(self):
59+
self._device.writeRaw8(self.gpio | self.iodir)
60+
61+
def _read_pins(self):
62+
return self._device.readRaw8() & self.iodir
63+
64+
def _validate_pin(self, pin):
65+
# Raise an exception if pin is outside the range of allowed values.
66+
if pin < 0 or pin >= self.NUM_GPIO:
67+
raise ValueError('Invalid GPIO value, must be between 0 and {0}.'.format(self.NUM_GPIO))
68+
69+
def _bit2(self, src, bit, val):
70+
bit = 1 << bit
71+
return (src | bit) if val else (src & ~bit)
72+
73+
74+
def setup(self, pin, mode):
75+
self.setup_pins({pin: mode})
76+
77+
def setup_pins(self, pins):
78+
if False in [y for x,y in [(self._validate_pin(pin),mode in (IN,OUT)) for pin,mode in pins.iteritems()]]:
79+
raise ValueError('Invalid MODE, IN or OUT')
80+
for pin,mode in pins.iteritems():
81+
self.iodir = self._bit2(self.iodir, pin, mode)
82+
self._write_pins()
83+
84+
85+
def output(self, pin, value):
86+
self.output_pins({pin: value})
87+
88+
def output_pins(self, pins):
89+
[self._validate_pin(pin) for pin in pins.keys()]
90+
for pin,value in pins.iteritems():
91+
self.gpio = self._bit2(self.gpio, pin, bool(value))
92+
self._write_pins()
93+
94+
95+
def input(self, pin):
96+
return self.input_pins([pin])[0]
97+
98+
def input_pins(self, pins):
99+
[self._validate_pin(pin) for pin in pins]
100+
inp = self._read_pins()
101+
return [bool(inp & pin) for pin in pins]

0 commit comments

Comments
 (0)