Pages

Monday, January 07, 2013

MCP23008 IO Expander - Decimal keypad

Now I have stepwise refined the functions for more flexibility and consistancy.  The main test functions become the followng.

# * Test MCP23008/MCP23017 GP *




TestToggleMCP23008Port(MCP23008BaseAddress1, 0.5, 4) # toggleTime 0.5 second, toggleCount 4
TestToggleMCP23017Ports(MCP23017BaseAddress1, 0.3, 6) # toggleTime 0.3 second, toggleCount 6

# * Test stepping motors *
# TestMove2Motors(MCP23008BaseAddress1)
# * Test decimal keypad *
TestReadKeypadRows(MCP23008BaseAddress2)

# *****************************************************************************
# *** tiox1v.py ***
# Program  - Test MCP23008 and MCP23017
# Version  - 1.v
# Date     - 2012nov30
# Update   - 2013jan07
# Author   - tlfong01
# File     - tiox1v_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
# *****************************************************************************
# * GPIO naming and setting up *
# * 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]
# *****************************************************************************
# * Global constants *
# * 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 naming *
LowNibble = 0
HighNibble = 1
BothNibble = 2 # full byte of 8 bits
# * Nibble constants *
HighNibble1LowNibble0 = 0xf0
HighNibble0LowNibble1 = 0x0f
# * LED and buzzer states *
Off = False
On = True
# * Button states *
ButtonPressed = False
ButonReleased = True

# *****************************************************************************
# * GPIO functions *
# Note: 5V0 max = 50 mA, 3V3 max = 300 mA, per GPIO pin max = 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 Buzzer, LED, Button 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)
# *****************************************************************************
# * 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
# To detect I2C device base addresses
# sudo i2cdetect -y 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
# * Register base addresses *
MCP23017BaseAddress1 = 0x22 # 1 LED, 1 button
MCP23008BaseAddress1 = 0x24 # 2 unipolar stepping motors
MCP23008BaseAddress2 = 0x25 # 1 decimal keypad
# * Port type *
PortA = 0
PortB = 1
# * Byte patterns *
# * Data bytes *
AllOutput = 0x00
AllHigh = 0xff
AllLow =  0x00
AlternateHighLow = 0xaa
AlternateLowHigh = 0x55
# * Direction setting bytes *
HalfHighHalfLow = 0xf0
HalfLowHalfHigh = 0x0f
Nibble1HighNibble2Low = 0xf0
Nibble1LowNibble2High = 0x0f
# * Toggle testing parameters *
ToggleTime = 0.2
ToggleCount = 4
# * MCP23008/MCP23017 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
# * MCP23008/MCP23017 Band0/Band1 register address offset arrays *
RegisterAddressOffsetArray0 = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,          
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a]
              
RegisterAddressOffsetArray1 = [0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x11, 0x13, 0x15, 0x17, 0x19,          
     0x01, 0x03, 0x05, 0x07, 0x09, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a]
# * Write/Read MCP23008/MCP23017 registers *
def writeDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType, dataByte):
    if (portType == PortA) | (portType == PortA):
       addressOffset = registerAddressArray[dataRegisterIndex]
    if (portType == PortB):
       addressOffset = registerAddressArray[dataRegisterIndex + 11]
    smBus1.write_byte_data(registerBaseAddress, addressOffset, dataByte)
def ReadDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType):
    if (portType == PortA):
       addressOffset = registerAddressArray[dataRegisterIndex]
    if (portType == PortB):
       addressOffset = registerAddressArray[dataRegisterIndex + 11]
    dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
    return dataByte
# * Test MCP23008/MCP23017 toggle port functions *
def TestToggleMCP23008Port(registerBaseAddress, toggleTime, toggleCount):
    # Set port all output
    writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
    # Toggle port
    for i in range(toggleCount):
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllHigh)
 sleep(toggleTime)
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllLow)
  sleep(toggleTime)
def TestToggleMCP23017Ports(registerBaseAddress, toggleTime, toggleCount):
    # Set both ports all pins output
    writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
    writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortB, AllOutput)
    # Toggle both ports
    for i in range(toggleCount):
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllHigh)
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortB, AllHigh)
 sleep(toggleTime)
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllLow)
        writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortB, AllLow)
  sleep(toggleTime)
# * Interrupt functions *
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
# * 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 interrupt *
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, RegisterAddressOffsetArray0, InputOutputDirection, PortA, 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, RegisterAddressOffsetArray0, OutputLatch, PortA, hexString1)
    sleep(StepTime)
        writeDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, OutputLatch, PortA, hexString2)
        sleep(StepTime)
def WriteMotorWindingFullStepSequence13232414(RegisterBaseAddress, NibbleType, StepCount, StepTime): #move motor using 13-23-24-14 sequence
    # Set port all output
    writeDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, InputOutputDirection, PortA, 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, RegisterAddressOffsetArray0, OutputLatch, PortA, 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)
# *****************************************************************************
# * Decimal 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 port status's high nibble (GP4~7)
def SetupKeypad(registerBaseAddress):
   # Set IO port high nibble input, low nibble output
   writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, HighNibbleInputLowNibbleOutput)
   # Write all zeros to keypad rows (GP0~2)
   writeDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, HighNibble1LowNibble0)
def TestReadKeypadRows(registerBaseAddress): # read keypad input rows 0~3
    SetupKeypad(registerBaseAddress)
    while True:
       sleep(1)
       dataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
       print "Row data (GP4~7) = ", hex(dataByte)        
## * 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, RegisterAddressOffsetArray0, InputOutputDirection, PortA, 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()
# *****************************************************************************
# * Main test functions *
SetupGPIO()
StartBeep()
# * Test RPi GPIO *
# 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
# * Test MCP23008/MCP23017 GP *
TestToggleMCP23008Port(MCP23008BaseAddress1, 0.5, 4) # toggleTime 0.5 second, toggleCount 4
TestToggleMCP23017Ports(MCP23017BaseAddress1, 0.3, 6) # toggleTime 0.3 second, toggleCount 6

# * Test stepping motors *
# TestMove2Motors(MCP23008BaseAddress1)
# * Test decimal keypad *
TestReadKeypadRows(MCP23008BaseAddress2)
#TestScanKeypad()
# *****************************************************************************
# End of Program
# *****************************************************************************
.END

No comments:

Post a Comment