Now I have connected the decimal keypad to MCP23008's GPs and used the following function to check that the function polls the keypad rows every second and could detect if any one row is pressed.
# Read MCP23008 GP4 ~ GP7
def TestReadKeypadRows(): # read keypad input rows 0~3
RegisterBaseAddress = MCP23008BaseAddress2
# setIOxPinsLowNibbleOutputHighNibbleInput(RegisterBaseAddress)
smBus1.write_byte_data(0x25, 0, 0xf0)
# writeIOxPinsAllLow(RegisterBaseAddress)
smBus1.write_byte_data(0x25, 0x0a, 0x00)
nibble = 0xf0
while True:
# oneBeep()
sleep(1)
# nibble = smBus1.read_byte_data(RegisterBaseAddress, GPIO_REGISTER)
nibble = smBus1.read_byte_data(0x25, 9)
print "GP4 to GP7 = ", hex(nibble)
.END
# *****************************************************************************
# *** tiox1q.py ***
# Program - Test MCP23008 and MCP23017
# Version - 1.q
# Date - 2012nov30
# Update - 2013jan05
# Author - tlfong01
# File - tiox1q_2013jan06.py
# Blog - http://tlfong01.blogspot.hk/
# Purpose - test basics of Raspberry Pi GPIO
# Hardware - Raspberry Pi Model B Revsion 2.0 [2012oct/nov/dec]
# Software - Raspbian Wheezy (2012sep15), Python 2.7.3
# GPIO 0.4.1a http://pypi.python.org/pypi/RPi.GPIO/0.4.1a
# Wiring - RPi Board Numbering
# P1-02 5V, P1-04 5V, P1-06 Gnd
# P1-01 3V3, P1-03 I2C SDA1, P1-05 I2C SCL1
# P1-08 UART TxD (MCP23017 Reset)
# P1-10 UART RxD (MCP23017 INTB)
# P1-12 RPi GPIO_GEN1 (BCM18) LED (P1-12 > LED > 330R > Gnd)
# P1-14 Gnd
# P1-16 GPIO_GEN4 - Buzzer, 3V3 5mA (P1-16 > Buzzer > Gnd)
# P1-18 GPIO_GEN5 Button (3V3 > 10K > Contact 1/2 > 330R > Gnd)
# P1-20 Gnd
# P1-22 GPIO_GEN6 - MCP23008 INT / MCP23017 INTA
# *****************************************************************************
# *** Import Python modules ***
import smbus
import sys
import RPi.GPIO as GPIO
from time import sleep
import select # interrupt module
# *****************************************************************************
# *** Configure RPi GPIO pins ***
# * RPi.GPIO setting *
GPIO.setmode(GPIO.BOARD) # Use RPi GPIO numbering, Not BCM numbering
GPIO.setwarnings(False) # Disable linux's "pin already in use warning"
# * P1 pins numbering *
RPiGPIOgen1 = 12 # Brown (P1-12, BCM GPIO 18) LED
RPiGPIOgen4 = 16 # Yellow (P1-16, BCM GPIO 23) Buzzer
RPiGPIOgen5 = 18 # Green (P1-18, BCM GPIO 24) Button
RPiGPIOgen6 = 22 # Blue (P1-22, BCM GPIO 25) IOx Interrupt
RPiTxD = 8 # Orange (P1-08) UART TxD
RPiRxD = 10 # Yellow (P1-10) UART RxD
# * IO device pins assignment *
LEDpin = RPiGPIOgen1
BuzzerPin = RPiGPIOgen4
ButtonPin = RPiGPIOgen5
InterruptPin = RPiGPIOgen6
TxDpin = RPiTxD
RxDpin = RPiRxD
# * IO pins list *
OutputPinList = [LEDpin, BuzzerPin, TxDpin]
InputPinWithNoPullUpList = [ButtonPin, RxDpin]
InputPinWithPullUpList = [InterruptPin]
# * No need to set the I2C pins SCL1 and SDA1, because they are automatically set by
# Raspbian Wheezy
# *****************************************************************************
# * Loop counters *
TwoTimes = 2
FourTimes = 4
EightTimes = 8
TenTimes = 10
TwentyTimes = 20
FiftyTimes = 50
OneHundredTimes = 100
TwoHundredTimess = 200
FourHundredTimes = 400
# * Elapse times *
TwentyMilliSeconds = 0.02
FiftyMilliSeconds = 0.05
TenthSecond = 0.1
QuarterSecond = 0.25
HalfSecond = 0.5
OneSecond = 1
OneAndHalfSeconds = 1.5
TwoSeconds = 2
OnTime = TenthSecond
OffTime = QuarterSecond
ButtonDebouncingTime = QuarterSecond
TestTime = FiftyMilliSeconds
# * Nibble *
LowNibble = 0
HighNibble = 1
BothNibble = 2 # full byte of 8 bits
# * LED and buzzer states *
Off = False
On = True
# * Button states *
ButtonPressed = False
ButonReleased = True
# *****************************************************************************
# *** RPi GPIO functions ***
# Reference - Raspberry Pi Python GPIO Version - GPIO 0.4.1a
# http://pypi.python.org/pypi/RPi.GPIO/0.4.1a
# RPi Model B 5V0 max current draw: 50 mA
# RPi Model B 3V3 max current draw: 300 mA
# GPIO maximum current draw per pin: 17mA source, 12mA sink
# * Setup, read, write GPIO pins *
setupOutputPin = lambda oPin: GPIO.setup(oPin, GPIO.OUT) # set GPIO pin as output
setupInputPinWithNoPullUp = lambda iPin: GPIO.setup(iPin, GPIO.IN, pull_up_down=GPIO.PUD_OFF) # set GPIO pin as input, no pull up
setupInputPinWithPullUp = lambda iPin: GPIO.setup(iPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set GPIO pin as input, with pull up
writeOutputPin = lambda oPin, oValue: GPIO.output(oPin, oValue) # write value to output pin
setupWriteOutputPin = lambda oPin, oValue: (setupOutputPin(oPin), writeOutputPin(oPin, oValue)) # set and write
readInputPin = lambda iPin: GPIO.input(ButtonPin) # read value from input pin
def SetupGPIOpins(outputPinList, inputPinWithNoPullUpList, inputPinWithPullUpList): # set up GPIO pins in InputPinList and OutputPinList
for oPin in outputPinList:
setupWriteOutputPin(oPin, Off)
for iPin in inputPinWithNoPullUpList:
setupInputPinWithPullUp(iPin)
for iPin in inputPinWithPullUpList:
setupInputPinWithPullUp(iPin)
def SetupGPIO(): # set up GPIO pins
SetupGPIOpins(OutputPinList, InputPinWithNoPullUpList, InputPinWithPullUpList )
# * pulse and echo functions *
def pulsePin(oPin, onTime, offTime): # blink LED or beep buzzer
writeOutputPin(oPin, On)
sleep(onTime)
writeOutputPin(oPin, Off)
sleep(offTime)
def echoPin(iPin, oPin): # echo input pin to output pin, e.g. button to LED or buzzer
while True:
if readInputPin(iPin) == ButonReleased:
pass
else:
pulsePin(oPin, OnTime, OffTime)
break
continue
def togglePin(oPin, toggleTime): # toggle pin
writeOutputPin(oPin, On)
sleep(toggleTime)
writeOutputPin(oPin, Off)
sleep(toggleTime)
# * Test GPIO functions *
def TestBuzzer(): # beep 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(BuzzerPin, OnTime, OffTime)
def TestLED(): # blink 8 times
SetupGPIO()
for i in range (EightTimes):
pulsePin(LEDpin, OnTime, OffTime)
def TestButtonEchoBuzzer(): #
SetupGPIO()
for i in range (TenTimes):
echoPin(ButtonPin, BuzzerPin)
def TestButtonEchoLED(): #
SetupGPIO()
for i in range (TenTimes):
echoPin(ButtonPin, LEDpin)
def TestToggleTxDpin():
while True:
togglePin(TxDpin, TwoSeconds)
# *****************************************************************************
# Beep functions *
def beep(count):
for i in range(count):
pulsePin(BuzzerPin, OnTime, OffTime)
def StartBeep():
beep(TwoTimes)
sleep(1)
def endBeep():
beep(FourTimes)
def oneBeep():
beep(1)
# *****************************************************************************
# *** IO Expander MCP23008 / MCP23017 ***
# * Bash script using i2cTools's i2cset command to toggle GPIO pins *
#!/bin/bash
# i2cset -y 1 0x20 0x00 0x00
# count=0
# while [ $count -lt 10 ];
# do
# i2cset -y 1 0x20 0x0a 0x00
# sleep 0.5
# i2cset -y 1 0x20 0x0a 0xff
# sleep 0.5
# let count++
# done
# To run i2c-X commands in user mode: sudo chmod 666 /dev/i2c-X
# sudo chmod 666 /dev/i2c-1
# * Setup SMBus *
I2C_BUS_NUMBER = 1 # P1-03 = SDA1, P1-05 = SCL1
smBus1 = smbus.SMBus(I2C_BUS_NUMBER) # global variable, cannot be set by a function
# ****************************************************************************
# * MCP23008/MCP23017 IO Expander *
# * Register base addresses *
MCP23017BaseAddress1 = 0x22
MCP23008BaseAddress1 = 0x24
MCP23008BaseAddress2 = 0x25
RegisterBaseAddress = 0x24
BaseAddress0x24 = 0x24
MCP23008_1_REGISTER_BASE_ADDRESS = 0x20
MCP23008BaseAddress2 = 0x21
# * Port type *
MCP23008Port = 0
MCP23017PortA = 0
MCP23017PortB = 1
# * Byte patterns *
AllOutput = 0x00
AllHigh = 0xff
AllLow = 0x00
HalfHighHalfLow = 0xf0
HalfLowHalfHigh = 0x0f
Nibble1HighNibble2Low = 0xf0
Nibble1LowNibble2High = 0x0f
AlternateHighLow = 0xaa
AlternateLowHigh = 0x55
ToggleTime = 0.2
ToggleCount = 4
# * Register address offsets *
InputOutputDirection = 0
InputPolarity = 1
InterruptOnChangeEnable = 2
InterruptOnChangeDefaultValue = 3
InterruptOnChangeMode = 4
Configuration = 5
PullUpResistor = 6
InterruptFlag = 7
InterruptCapture = 8
PortStatus = 9
OutputLatch = 10
# * Register address offset arrays *
MCP23008RegisterAddressArray = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a]
MCP23017Band0RegisterAddressArray = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a]
MCP23017Band1RegisterAddressArray = [0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x11, 0x13, 0x15, 0x17, 0x19,
0x01, 0x03, 0x05, 0x07, 0x09, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a]
def writeDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType, dataByte):
if (portType == MCP23008Port) | (portType == MCP23017PortA):
addressOffset = registerAddressArray[dataRegisterIndex]
if (portType == MCP23017PortB):
addressOffset = registerAddressArray[dataRegisterIndex + 11]
smBus1.write_byte_data(registerBaseAddress, addressOffset, dataByte)
def TestToggleMCP23017BothPorts():
# Set both ports all output
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, InputOutputDirection, MCP23017PortA, AllOutput)
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, InputOutputDirection, MCP23017PortB, AllOutput)
# Toggle both ports
for i in range(ToggleCount):
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, OutputLatch, MCP23017PortA, AllHigh)
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, OutputLatch, MCP23017PortB, AllHigh)
sleep(ToggleTime)
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, OutputLatch, MCP23017PortA, AllLow)
writeDataByte(MCP23017BaseAddress1, MCP23017Band0RegisterAddressArray, OutputLatch, MCP23017PortB, AllLow)
sleep(ToggleTime)
def TestToggleMCP23008Port(togglePatternX, togglePatternY):
# Set port all output
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, InputOutputDirection, MCP23008Port, AllOutput)
# Toggle port
for i in range(ToggleCount):
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, OutputLatch, MCP23008Port, togglePatternX)
sleep(ToggleTime)
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, OutputLatch, MCP23008Port, togglePatternY)
sleep(ToggleTime)
# * Direction setting *
DIRECTION_BYTE_ALL_OUTPUT = 0x00
DIRECTION_BYTE_LowNibble_OUTPUT_HighNibble_INPUT = 0xf0
# * Data pattern *
DATA_BYTE_ALL_ZERO = 0x00
DATA_BYTE_ALL_ONE = 0xff
DATA_BYTE_HighNibble_ONE_LowNibble_ZERO = 0xf0
DATA_BYTE_HighNibble_ZERO_LowNibble_ONE = 0x0f
# * Interrupt setting *
ENABLE_INTERRUPT_HighNibble = 0xf0
DEFAULT_COMPARE_VALUE_HighNibble = 0xf0
INTERRUPT_CONTROL_COMPARE_DEFAULT_HighNibble = 0xf0
INTERRUPT_PIN_PUSH_PULL_DRIVER_HIGH_ACTIVE = 0b00111010 # 0x3a, no auto add incre, no slew rate
INTERRUPT_PIN_OPEN_DRAIN = 0b00111000 # 0x38, no auto add incre, no slew rate
# * Setup IO direction *
def setIOxPinsAllOutput(registerBaseAddress): # set up all 8 IOx pins as output
smBus1.write_byte_data(registerBaseAddress, IO_DIRECTION_REGISTER, DIRECTION_BYTE_ALL_OUTPUT)
def setIOxPinsLowNibbleOutputHighNibbleInput(registerBaseAddress): # set low nibble output, high nibble input
smBus1.write_byte_data(registerBaseAddress, IO_DIRECTION_REGISTER, DIRECTION_BYTE_LowNibble_OUTPUT_HighNibble_INPUT)
# * Writing data *
def writeIOxPinsAllLow(registerBaseAddress): # write zeros to all 8 IOx output pins
smBus1.write_byte_data(registerBaseAddress, OUTPUT_LATCH_REGISTER, DATA_BYTE_ALL_ZERO)
def writeIOxPinsAllHigh(registerBaseAddress): #write ones to all 8 IOx output pins
smBus1.write_byte_data(registerBaseAddress, OUTPUT_LATCH_REGISTER, DATA_BYTE_ALL_ONE)
def writeIOxPins(registerBaseAddress, dataHexString): # write 8 bit hex string to IOx output pins
smBus1.write_byte_data(registerBaseAddress, OUTPUT_LATCH_REGISTER, dataHexString)
# * Reading data *
def readIOxPinsByte(registerBaseAddress): # read 8 bit hex data from GPIO register (= 8 output pin)
hexByte = smBus1.read_byte_data(0x25, 9)
return hexByte
def readIOxPinsHighNibble(registerBaseAddress): # read high nibble from GPIO resister (= upper nible of output pins)
hexByte = readIOxPinsByte(registerBaseAddress)
hexNibble = hexByte >> 4
return hexNibble
# * Interrupt setting *
def enableInterruptOnChangeHighNibble(registerBaseAddress): # enable high nibble interrupt on change
smBus1.write_byte_data(registerBaseAddress, INTERRUPT_ON_CHANGE_REGISTER, ENABLE_INTERRUPT_HighNibble)
def setInterruptOnChangeDefaultHighNibble(registerBaseAddress): # set high nibble default compare values
smBus1.write_byte_data(registerBaseAddress, DEFAULT_COMPARE_VALUE_REGISTER, DEFAULT_COMPARE_VALUE_HighNibble)
def setInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress): # enable high nibble compare default
smBus1.write_byte_data(registerBaseAddress, INTERRUPT_CONTROL_REGISTER, INTERRUPT_CONTROL_COMPARE_DEFAULT_HighNibble)
def setHighNibbleCompareDefault(registerBaseAddress): # set high nibble compare default
enableInterruptOnChangeHighNibble(registerBaseAddress)
setInterruptOnChangeDefaultHighNibble(registerBaseAddress)
setInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress)
def setInterruptPinPushPullHighActive(registerBaseAddress): # interrupt pin push pull high active, no auto add inc, no slew rate
smBus1.write_byte_data(registerBaseAddress, IO_CONTROL_REGISTER, INTERRUPT_PIN_PUSH_PULL_DRIVER_HIGH_ACTIVE)
def setInterruptPinOpenDrain(registerBaseAddress): # interrupt pin open drain, no auto add inc, no slew rate
smBus1.write_byte_data(registerBaseAddress, IO_CONTROL_REGISTER, INTERRUPT_PIN_OPEN_DRAIN)
# * Interrupt reading *
def readInterruptFlagPinsHighNibble(registerBaseAddress): # read high nibble interrupt flag register
hexByte = smBus1.read_byte_data(registerBaseAddress, INTERRUPT_FLAG_REGISTER)
hexNibble = hexByte >> 4
return hexNibble
def readInterruptCapturePinsHighNibble(registerBaseAddress): # read high nibble interrupt capture register
hexByte = smBus1.read_byte_data(registerBaseAddress, INTERRUPT_CAPTURE_REGISTER)
hexNibble = hexByte >> 4
return hexNibble
# * Testing *
def TestInterruptPinFallingEdgeDetection():
GPIO.cleanup() # set all input pins no pull up, disable all interutp detection setting
SetupGPIO()
GPIO.set_low_event(InterruptPin) # set up low level detection
for i in range(30):
if GPIO.event_detected(InterruptPin):
break
else:
print "No interrupt detected.", i
sleep(1)
continue
GPIO.set_low_event(InterruptPin, enable = False) # disable detection
print "End of test, or interrupt detected"
# *****************************************************************************
# *** Unipolar Stepping Motor 28BYJ48/NPM-PF35/PX245 ***
# Unipolar Stepping Motor Switching Sequence
# 1. Wave sequence = 1 - 3 - 2 - 4 (A-, B-, A+, B+)
# 2. Full step sequence = 13 - 14 - 24 - 23 (A-B-, A-B+, A+B+, A+B-)
# 3. Half step sequence = 13 - 1 - 14 - 4 - 24 - 2 - 23 - 3
# 4. One step swing = 1 - 3 - 1 - 3 (A-, B-, A-, B-)
# Winding A-(1) A+(2) B-(3) B+(4) COM
# NPM PF35 Black Yellow Brown Orange Red
# 28BYJ48 Blue Pink Yellow Orange Red
# PX245 Black Green Blue Red Yellow/White
# * Convert decimal pin number to hex *
def convert1PinToHex(p): # convert 1 of 8 high pin to hex
hexString = 0x01
for count in range(p-1):
hexString = hexString << 1
return hexString
def convert2PinToHex(p1, p2): # convert 2 of 8 high pins to hex
return (convert1PinToHex(p1) | convert1PinToHex(p2))
def convert2PinToHighNibble(p1, p2): # convert 2 of 8 high pins to high nibble
lowNibble = convert1PinToHex(p1) | convert1PinToHex(p2)
highNibble = lowNibble << 4
return highNibble
# * Move unipolar stepping motor *
def WriteMotorWindingWaveSequence1324(RegisterBaseAddress, NibbleType, StepCount, StepTime): # move motor using 13-24 sequence
# Set port all output
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, InputOutputDirection, MCP23008Port, AllOutput)
if NibbleType == LowNibble:
hexString1 = convert2PinToHex(1, 3)
hexString2 = convert2PinToHex(2, 4)
else:
hexString1 = convert2PinToHighNibble(1, 3)
hexString2 = convert2PinToHighNibble(2, 4)
for i in range(StepCount):
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, OutputLatch, MCP23008Port, hexString1)
sleep(StepTime)
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, OutputLatch, MCP23008Port, hexString2)
sleep(StepTime)
def WriteMotorWindingFullStepSequence13232414(RegisterBaseAddress, NibbleType, StepCount, StepTime): #move motor using 13-23-24-14 sequence
# Set port all output
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, InputOutputDirection, MCP23008Port, AllOutput)
if NibbleType == LowNibble:
motorWindingActivationPatternArray = (0x05, 0x06, 0x0a, 0x09)
else:
motorWindingActivationPatternArray = (0x50, 0x60, 0xa0, 0x90)
for i in range(StepCount):
for pattern in motorWindingActivationPatternArray:
writeDataByte(MCP23008BaseAddress1, MCP23008RegisterAddressArray, OutputLatch, MCP23008Port, pattern)
sleep(StepTime)
def TestConvert1PinToHex(): # test convert 1 high pin to hex
print "*** Testing 1 pin number decimal 0 ~ 7 converted to hexdecimal 0x01 ~ 0x80"
for d in range(8):
print hex(convert1PinToHex(d))
def TestConvert2PinToHex(p1, p2): # test convert 2 high pins to hex
print "*** Testing 2 pin numbers decimal 0 ~ 7 converted to hexdecimal"
print "Pin 1 = ", p1, "Pin 2 = ", p2
print "Hex = ", hex(convert2PinToHex(p1, p2))
def TestConvert2PinToHighNibble(p1, p2): # test convert 2 of 8 high pins to high nibble
print "*** Testing 2 pin numbers decimal 0 ~ 7 converted to high nibble"
print "Pin 1 = ", p1, "Pin 2 = ", p2
print "HighNibble = ", hex(convert2PinToHighNibble(p1, p2))
def TestMove2Motors(RegisterBaseAddress): # move 2 motors one after another
oneBeep()
WriteMotorWindingWaveSequence1324(MCP23008BaseAddress1, LowNibble, TwentyTimes, FiftyMilliSeconds)
oneBeep()
WriteMotorWindingWaveSequence1324(MCP23008BaseAddress1, HighNibble, TwentyTimes, FiftyMilliSeconds)
#oneBeep()
#WriteMotorWindingFullStepSequence13232414(MCP23008BaseAddress1, LowNibble, TwentyTimes, FiftyMilliSeconds)
#oneBeep()
#WriteMotorWindingFullStepSequence13232414(MCP23008BaseAddress1, HighNibble, TwentyTimes, FiftyMilliSeconds)
# *****************************************************************************
# *** Keypad ***
# Keypad scanning procedure version 1.0
# 1. Set 3 column ports GP0, GP1, GP2 as output (GP3 don't care)
# 2. Set 4 row ports GP4, GP5, GP6, GP7 as input
# 3. Write LOW to all column ports
# 4. Wait for interrupt
# 5. Pressing any key would cause an interrupt
# 6. When interrupt occurs check which row reads LOW
# 7. Write LOW only to column GP0, if row port still LOW, then this column 0
# has a key pressed, if not, check if column 1, if not column 3.
# 8. Calculate the key using the column and row data.
# Read MCP23008 GP4 ~ GP7
def TestReadKeypadRows(): # read keypad input rows 0~3
RegisterBaseAddress = MCP23008BaseAddress2
# setIOxPinsLowNibbleOutputHighNibbleInput(RegisterBaseAddress)
smBus1.write_byte_data(0x25, 0, 0xf0)
# writeIOxPinsAllLow(RegisterBaseAddress)
smBus1.write_byte_data(0x25, 0x0a, 0x00)
nibble = 0xf0
while True:
# oneBeep()
sleep(1)
# nibble = smBus1.read_byte_data(RegisterBaseAddress, GPIO_REGISTER)
nibble = smBus1.read_byte_data(0x25, 9)
print "GP4 to GP7 = ", hex(nibble)
## * keypad base address and smBus setting *
keypadRegisterBaseAddress = MCP23008BaseAddress2
keypadSmBus = smBus1
# * Keypad columns numbering *
ColumnOutputPin0 = 0
ColumnOutputPin1 = 1
ColumnOutputPin2 = 2
ColumnOutputPinTuple = ColumnOutputPin0, ColumnOutputPin1, ColumnOutputPin2
# * Keypad row numbering *
RowInputPin0 = 0
RowInputPin1 = 1
RowInputPin2 = 2
RowInputPin3 = 3
RowInputPinTuple = RowInputPin0, RowInputPin1, RowInputPin2, RowInputPin2
# * Keypad matrix numbering *
KeyPadMatrixTuple = ColumnOutputPinTuple, RowInputPinTuple
# * Write keypad column data patterns *
ColumnAllLow = 0b000
Column0Low = 0b110
Column1Low = 0b101
Column2Low = 0b011
ColumnLowTuple = Column0Low, Column1Low, Column2Low
# * Read keypad data patterns *
RowAllHigh = 0b1111
Row0Low = 0b1110
Row1Low = 0b1101
Row2Low = 0b1011
Row3Low = 0b0111
RowLowTuple = Row0Low, Row1Low, Row2Low, Row3Low
# * Set, write, read keypad pins *
def SetupKeypad(keypadRegisterBaseAddress):
#writeDataByte(MCP23008BaseAddress2, MCP23008RegisterAddressArray, InputOutputDirection, MCP23008Port, 0xf0)
smBus1.write_byte_data(0x25, 0, 0xf0)
def writeColumnPins(keypadRegisterBaseAddress, columnPattern):
hexString = 0xff & columnPattern
#writeIOxPins(keypadRegisterBaseAddress, hexString)
smBus1.write_byte_data(0x25, 0x0a, hexString)
def readRowPins():
hexNibble = readIOxPinsHighNibble(keypadRegisterBaseAddress)
return hexNibble
# * Test polling/interrupt keypad *
def scanKeypad(registerBaseAddress):
SetupKeypad(registerBaseAddress)
#setInterruptPinOpenDrain(registerBaseAddress) # *** interrupt pin open drain !!!
writeColumnPins(registerBaseAddress, ColumnAllLow)
#setHighNibbleCompareDefault(registerBaseAddress) # *** testing interrupt ***
# Loop until one key pressed
keyPressed = False
while True:
nibble = readRowPins()
if nibble == Row0Low:
row = 0
keyPressed = True
print "Row 0 key pressed"
elif nibble == Row1Low:
row = 1
keyPressed = True
print "Row 1 key pressed"
elif nibble == Row2Low:
row = 2
keyPressed = True
print "Row 2 key pressed"
elif nibble == Row3Low:
row = 3
keyPressed = True
print "Row 3 key pressed"
else:
row = 9
#print "No key or more than one key pressed"
if keyPressed == True:
# Check which column the key is pressed
column = 9
writeColumnPins(registerBaseAddress, Column0Low)
nibble = readRowPins()
if nibble != RowAllHigh:
column = 0
print "Column 0 key pressed"
else:
writeColumnPins(registerBaseAddress, Column1Low)
nibble = readRowPins()
if nibble != RowAllHigh:
column = 1
print "Column 1 key pressed"
else:
writeColumnPins(registerBaseAddress, Column2Low)
nibble = readRowPins()
if nibble != RowAllHigh:
column = 2
print "Column 2 key pressed"
else:
print "Error"
# Calculate which key pressed
keyNumber = (row * 3) + (column + 1)
print "Key pressed = ", '{0:8}'.format(str(keyNumber).zfill(2).rjust(10))
# *******************************************************************************
# checking interrupt
# *******************************************************************************
# Check which column interrupt
interruptFlagNibble = readInterruptFlagPinsHighNibble(registerBaseAddress)
interruptCaptureNibble = readInterruptCapturePinsHighNibble(registerBaseAddress)
print "Interrupt flag nibble = ", '{0:8}'.format((str(bin(interruptFlagNibble)).zfill(4)).rjust(10))
print "Interrupt capture nibble = ", '{0:8}'.format((str(bin(interruptCaptureNibble)).zfill(4)).rjust(10))
keyPressed = False
sleep(1)
else:
pass
def TestScanKeypad():
scanKeypad(MCP23008BaseAddress2)
# *****************************************************************************
# * Old test functions *
# testLEDandBuzzer()
# testButton() !!! not working !!!
# blink8LEDsIOx1()
# blink4LEDsIOx2()
# testConvert1PinToHex()
# blink4LEDsIOx2()
# move1MotorUsingMCP23008_2(MCP23008BaseAddress2, HalfSecond,
# OneSecond, FourTimes, TwentyTimes, OneSecond)
# *****************************************************************************
# *** Old test functions ***
#TestReadGP4567() # OK 2012dec14
#TestScanKeypad()
#endBeep()
# *****************************************************************************
# *** Current test functions ***
#TestBuzzer() # beep buzzer 4 times
#TestLED() # blink LED 8 tmes
#TestButtonEchoBuzzer() # echo buton with buzzer 10 times
#TestButtonEchoLED() # echo buton with LED 10 times
#TestToggleTxDpin() # toggle TxD pin every 2 seconds
#TestToggleMCP23017BothPorts()
#TestToggleMCP23008Port(HalfHighHalfLow, HalfLowHalfHigh)
#TestToggleMCP23008Port(AlternateHighLow, AlternateLowHigh)
#TestToggleMCP23008Port(AllHigh, AllLow)
#TestToggleMCP23008Port(AlternateHighLow, AlternateLowHigh)
SetupGPIO()
StartBeep()
TestToggleMCP23017BothPorts()
TestMove2Motors(MCP23008BaseAddress1)
TestReadKeypadRows()
#TestScanKeypad()
# *****************************************************************************
# End of Program
# *****************************************************************************
No comments:
Post a Comment