Skip to content

Instantly share code, notes, and snippets.

@Dan-in-CA
Created April 15, 2016 22:58
Show Gist options
  • Save Dan-in-CA/4c524bd2b04fc6ff24322ae2515cad21 to your computer and use it in GitHub Desktop.
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
# !/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