Created
April 15, 2016 22:58
-
-
Save Dan-in-CA/4c524bd2b04fc6ff24322ae2515cad21 to your computer and use it in GitHub Desktop.
Alternate gpio_pins.py for use with the MCP23017 i2c shift register. Thanks to Jerry Beech
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# !/usr/bin/python | |
# -*- coding: utf-8 -*- | |
import gv | |
try: | |
import RPi.GPIO as GPIO | |
gv.platform = 'pi' | |
rev = GPIO.RPI_REVISION | |
if rev == 1: | |
# map 26 physical pins (1based) with 0 for pins that do not have a gpio number | |
if gv.use_pigpio: | |
gv.pin_map = [0,0,0,0,0,1,0,4,14,0,15,17,18,21,0,22,23,0,24,10,0,9,25,11,8,0,7] | |
else: | |
gv.pin_map = [0,0,0,0,0,5,0,7,8,0,10,11,12,13,0,15,16,0,18,19,0,21,22,23,24,0,26] | |
elif rev == 2: | |
# map 26 physical pins (1based) with 0 for pins that do not have a gpio number | |
if gv.use_pigpio: | |
gv.pin_map = [0,0,0,2,0,3,0,4,14,0,15,17,18,27,0,22,23,0,24,10,0,9,25,11,8,0,7] | |
else: | |
gv.pin_map = [0,0,0,0,0,5,0,7,8,0,10,11,12,13,0,15,16,0,18,19,0,21,22,23,24,0,26] | |
elif rev == 3: | |
# map 40 physical pins (1based) with 0 for pins that do not have a gpio number | |
if gv.use_pigpio: | |
gv.pin_map = [0,0,0,2,0,3,0,4,14,0,15,17,18,27,0,22,23,0,24,10,0,9,25,11,8,0,7,0,0,5,0,6,12,13,0,19,16,26,20,0,21] | |
else: # ***** Used by jdb RPI2 | |
gv.pin_map = [0,0,0,3,0,5,0,7,8,0,10,11,12,13,0,15,16,0,18,19,0,21,22,23,24,0,26,0,0,29,0,31,32,33,0,35,36,37,38,0,40] | |
else: | |
print 'Unknown pi pin revision. Using pin mapping for rev 3' | |
except ImportError: | |
try: | |
import Adafruit_BBIO.GPIO as GPIO # Required for accessing General Purpose Input Output pins on Beagle Bone Black | |
gv.pin_map = [None]*11 # map only the pins we are using | |
gv.pin_map.extend(['P9_'+str(i) for i in range(11,17)]) | |
gv.platform = 'bo' | |
except ImportError: | |
gv.pin_map = [i for i in range(27)] # assume 26 pins all mapped. Maybe we should not assume anything, but... | |
gv.platform = '' # if no platform, allows program to still run. | |
print 'No GPIO module was loaded from GPIO Pins module' | |
from blinker import signal | |
zone_change = signal('zone_change') | |
try: | |
if gv.use_pigpio: | |
import pigpio | |
pi = pigpio.pi() | |
else: | |
GPIO.setwarnings(False) | |
GPIO.setmode(GPIO.BOARD) #IO channels are identified by header connector pin numbers. Pin numbers are | |
except Exception: | |
pass | |
global pin_rain_sense | |
global pin_relay | |
try: | |
if gv.platform == 'pi': # If this will run on Raspberry Pi: | |
GPIO.setmode(GPIO.BOARD) | |
pin_rain_sense = gv.pin_map[8] | |
pin_relay = gv.pin_map[10] | |
elif gv.platform == 'bo': # If this will run on Beagle Bone Black: | |
pin_rain_sense = gv.pin_map[15] | |
pin_relay = gv.pin_map[16] | |
except AttributeError: | |
pass | |
try: | |
if gv.use_pigpio: | |
pi.set_mode(pin_rain_sense, pigpio.INPUT) | |
pi.set_mode(pin_relay, pigpio.OUTPUT) | |
else: | |
GPIO.setup(pin_rain_sense, GPIO.IN) | |
GPIO.setup(pin_relay, GPIO.OUT) | |
except NameError: | |
pass | |
## *********************Addded by jdb 4-2016 | |
#print 'gv_use_gpio: ' + ' ' + str(gv.pin_map) | |
#print 'pin_rain_sense: ' + str(pin_rain_sense) + ' pin_relay: '+ str(pin_relay) | |
## ********************* | |
def setup_pins(): | |
""" | |
Define and setup GPIO pins for shift register operation | |
""" | |
global pin_sr_dat | |
global pin_sr_clk | |
global pin_sr_noe | |
global pin_sr_lat | |
global pi | |
try: | |
if gv.platform == 'pi': # If this will run on Raspberry Pi: | |
if not gv.use_pigpio: | |
GPIO.setmode(GPIO.BOARD) # IO channels are identified by header connector pin numbers. Pin numbers are always the same regardless of Raspberry Pi board revision. | |
pin_sr_dat = gv.pin_map[13] | |
pin_sr_clk = gv.pin_map[7] | |
pin_sr_noe = gv.pin_map[11] | |
pin_sr_lat = gv.pin_map[15] | |
elif gv.platform == 'bo': # If this will run on Beagle Bone Black: | |
pin_sr_dat = gv.pin_map[11] | |
pin_sr_clk = gv.pin_map[13] | |
pin_sr_noe = gv.pin_map[14] | |
pin_sr_lat = gv.pin_map[12] | |
except AttributeError: | |
pass | |
#### setup GPIO pins as output or input #### | |
try: | |
if gv.use_pigpio: | |
pi.set_mode(pin_sr_noe, pigpio.OUTPUT) | |
pi.set_mode(pin_sr_clk, pigpio.OUTPUT) | |
pi.set_mode(pin_sr_dat, pigpio.OUTPUT) | |
pi.set_mode(pin_sr_lat, pigpio.OUTPUT) | |
pi.write(pin_sr_noe, 1) | |
pi.write(pin_sr_clk, 0) | |
pi.write(pin_sr_dat, 0) | |
pi.write(pin_sr_lat, 0) | |
else: | |
GPIO.setup(pin_sr_noe, GPIO.OUT) | |
GPIO.setup(pin_sr_clk, GPIO.OUT) | |
GPIO.setup(pin_sr_dat, GPIO.OUT) | |
GPIO.setup(pin_sr_lat, GPIO.OUT) | |
GPIO.output(pin_sr_noe, GPIO.HIGH) | |
GPIO.output(pin_sr_clk, GPIO.LOW) | |
GPIO.output(pin_sr_dat, GPIO.LOW) | |
GPIO.output(pin_sr_lat, GPIO.LOW) | |
except NameError: | |
pass | |
def disableShiftRegisterOutput(): | |
"""Disable output from shift register.""" | |
global pi | |
try: | |
pin_sr_noe | |
except NameError: | |
if gv.use_gpio_pins: | |
setup_pins() | |
try: | |
if gv.use_pigpio: | |
pi.write(pin_sr_noe, 1) | |
else: | |
GPIO.output(pin_sr_noe, GPIO.HIGH) | |
except Exception: | |
pass | |
def enableShiftRegisterOutput(): | |
"""Enable output from shift register.""" | |
global pi | |
try: | |
if gv.use_pigpio: | |
pi.write(pin_sr_noe, 0) | |
else: | |
GPIO.output(pin_sr_noe, GPIO.LOW) | |
except Exception: | |
pass | |
def setShiftRegister(srvals): | |
"""Set the state of each output pin on the shift register from the srvals list.""" | |
global pi | |
try: | |
if gv.use_pigpio: | |
pi.write(pin_sr_clk, 0) | |
pi.write(pin_sr_lat, 0) | |
for s in range(gv.sd['nst']): | |
pi.write(pin_sr_clk, 0) | |
if srvals[gv.sd['nst']-1-s]: | |
pi.write(pin_sr_dat, 1) | |
else: | |
pi.write(pin_sr_dat, 0) | |
pi.write(pin_sr_clk, 1) | |
pi.write(pin_sr_lat, 1) | |
else: | |
GPIO.output(pin_sr_clk, GPIO.LOW) | |
GPIO.output(pin_sr_lat, GPIO.LOW) | |
for s in range(gv.sd['nst']): | |
GPIO.output(pin_sr_clk, GPIO.LOW) | |
if srvals[gv.sd['nst']-1-s]: | |
GPIO.output(pin_sr_dat, GPIO.HIGH) | |
else: | |
GPIO.output(pin_sr_dat, GPIO.LOW) | |
GPIO.output(pin_sr_clk, GPIO.HIGH) | |
GPIO.output(pin_sr_lat, GPIO.HIGH) | |
except Exception: | |
pass | |
def set_output(): | |
"""Activate triacs according to shift register state.""" | |
print '\n......NOTE: set_output in gpio_pins.py has started ...........' | |
# This is the old origional version: | |
""" | |
with gv.output_srvals_lock: | |
gv.output_srvals = gv.srvals | |
disableShiftRegisterOutput() | |
setShiftRegister(gv.output_srvals) # gv.srvals stores shift register state | |
enableShiftRegisterOutput() | |
zone_change.send() | |
""" | |
# ************************* Added by JDB 4-2016 | |
# this is the new version for using with the MCP23017 i2c shift register: | |
rz = '' ## Setup variable to old the value of currently running zone(s) | |
rbin = '11111111' ### First 8 zones on A side of shift register ### All zones OFF | |
rbinB = '11111111' ### Second 8 zones on B side of shift register ## All zones OFF | |
import smbus | |
import gv | |
bus = smbus.SMBus(1) # Rev 2 Pi uses 1 | |
DEVICE = 0x20 # Device address (A0-A2) | |
IODIRA = 0x00 # Pin direction register for Bank A | |
IODIRB = 0x01 # Pin direction register for Bank B | |
OLATA = 0x14 # Register for outputs for Bank A | |
OLATB = 0x15 # Register for outputs for Bank B | |
GPIOA = 0x12 # Register for inputs for Bank A | |
GPIOB = 0x13 # Register for inputs for Bank A | |
# Set all pins to outputs [[[ NOTE THIS MUST be CHANGED for rain sensor, etc]]] | |
bus.write_byte_data(DEVICE,IODIRA,0x00) ## All pins assumed to be outputs | |
bus.write_byte_data(DEVICE,IODIRB,0x00) ## All pins assumed to be outputs | |
# loop through zones and set string rbin to be a binnary string showing which zones are on | |
for num in range(len(gv.srvals)): # Cycle thrpough zones to see if it is on | |
if gv.srvals[num] == 1: # This zone number "num" is ON | |
rz = rz + str(num+1) | |
if num < 8: # if first 8 zones | |
rbin = rbin [:num] + '0' + rbin [num+1:] | |
else: # if zones 9-16 | |
rbinB = rbinB [:num] + '1' + rbinB [num+1:] | |
else: # Zone is OFF | |
if num < 8: # if first 8 zones | |
rbin = rbin [:num] + '1' + rbin [num+1:] | |
else: # if zones 9-16 | |
rbinB = rbinB [:num] + '1' + rbinB [num+1:] | |
# Reverese the binnary string so zone 1 is 11111110 and zone 8 is 01111111 | |
print (rbinB) | |
rbin = rbin [::-1] | |
rbinB = rbinB [::-1] | |
# Create a integer of the decimal value of the rbin string | |
runzonedecimal = int(rbin,2) | |
runzonedecimalB = int(rbinB,2) | |
print 'Number of stations shown on system: ' + str(gv.sd['nst']) | |
print 'Currently running zones: ' + rz | |
print 'Rbin for A and B:' + rbin + ' ' + rbinB | |
print 'Running zone decimal values A and b: ' +str(runzonedecimal) + ' ' + str(runzonedecimalB) | |
print 'Value of variable gv.srvals: ' + str(gv.srvals) | |
# write to the device with the active zones to activate / deactivate zones | |
bus.write_byte_data(DEVICE,OLATA,runzonedecimal) | |
bus.write_byte_data(DEVICE,OLATB,runzonedecimalB) | |
print ('.......New Zone Running Cycle Completed in gpio_pins.py set_output ........\n') | |
# ********************************** End - Added by JDB 4-2016 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment