-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMuxMaxAllMCPV2.py
83 lines (75 loc) · 3.69 KB
/
MuxMaxAllMCPV2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Program designed to test an 8 x 8 array of reed switches and gives the chessboard coordinate
# This program sets up 4 MCP23017 port expanders as inputs as defined in DEVICE[] below
# This program uses the MUX TCA9548A with I2C address changed to x71 by taking A0 to 3v, this avoided a conflict with the HT16K33 which is also x70.
# Each MCP23017 is wired to channels 2, 3, 4, 5, on the MUX
#
# Will print to the monitor when the state of a chess board switch closes eg A1 Open or E4 Close
#
# Author : Max Dobres
# Date : 21 April 2017
#
# http://www.chess.fortherapy.co.uk/
#
# Copyright 2017 Max Dobres
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import smbus
import time
import math
# MUX stuff
I2C_address = 0x71 # address of mux changed to avoid conflict with led driver
I2C_bus_number = 1
bus = smbus.SMBus(I2C_bus_number)
# bus = smbus.SMBus(1) # Rev 2 Pi uses 1
# this program scans 64 inputs on 4 MCP23017 port exapanders and returns changes
mbrd = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] # mbrd is the 8 columns of the chess board this sets them to 11111111 : open w
chcol =["A","B","C","D","E","F","G","H",'X','Y']
DEVICE = [0x21,0x22,0x23, 0x24] # the 4 I2c Device address of the MCP23017s (A0-A2)
GPIOn = [0x12, 0x13]
IODIRA = 0x00 # APin direction register for first 8 ie 1 = input or 2= output
IODIRB = 0x01 # B Pin direction register
GPIOA = 0x12 # Register for inputs
GPIOB = 0x13 # B Register for inputs
GPPUA= 0x0C # Register for Pull ups A
GPPUB= 0x0D # Register for Pull ups B
# first we do a one time setup of the MCPs
for i in range(0,4): # for each of the 4 MCPs
# first calculate channel code to send to MUX
# MCPs on channels 2, 3, 4, 5,
i2c_channel=2**(i+2) # calculates binary that gives channel pos, ie channel 0 is 0b00000001 and channel 4 is b0b00010000
bus.write_byte(I2C_address,i2c_channel) # tell MUX to use this channel
# time.sleep(0.2)
#for each of the 4 devices
# Set all A 8 GPA pins as input. ie set them to 1 oXFF = 11111111
bus.write_byte_data(DEVICE[i],IODIRA,0xFF)
# Set pull up on GPA pins .ie from default of 0 to 11111111
bus.write_byte_data(DEVICE[i],GPPUA,0xFF)
# Set all B 8 GPB pins as input. ie set them to 1 oXFF = 11111111
bus.write_byte_data(DEVICE[i],IODIRB,0xFF)
# Set pull up on GPB pins .ie from default of 0 to 11111111
bus.write_byte_data(DEVICE[i],GPPUB,0xFF)
# now look for a change
while True:
# read the 8 registers
for k in range(0,4):
i2c_channel=2**(k+2) # calculates binary that gives channel pos, ie channel 0 is 0b00000001 and channel 4 is b0b00010000
bus.write_byte(I2C_address,i2c_channel) # tell MUX to use this channel
# time.sleep(0.1) # just in case
for l in range(2): # for each MCP register A and B
a = bus.read_byte_data(DEVICE[k],GPIOn[l])
if a != mbrd[(k*2)+l]: # there has been a change
c = a ^ mbrd[(k*2)+l] # bitwise operation copies the bit if it is set in one operand but not both.
dirx = "Close"
if a > mbrd[(k*2)+l] : dirx = "open" # if the number gets bigger a 0 has changed to a 1
y = math.frexp(c)[1] # calculates integer part of log base 2, which is binary bit position
print chcol[(k*2)+l], y, dirx, l
mbrd[(k*2)+l]=a # update the current state of the board
# time.sleep(0.1)