Now I have moved on to GZP 16o8i reading. I wrote a simple read GZP8i function with the following statements.
guzuntypiSpi = spidev.SpiDev()
guzuntypiSpi.open(0, 0)
dummyDataByteList = [0x55]
inputDataByteList = guzuntypiSpi.xfer2(dummyDataByteList)
PrintEightBitPattern("guzuntypi byte read = ", inputDataByteList[0])
Then I shorted bit 0 and bit 3 of GZP16o8i to ground and ran the test function, which outputs the following as expected.
guzuntypi byte read = 11110110
So far so good.
Sunday afternoon jogging time.
.END
# *****************************************************************************
# !/usr/bin/python2.7
#
# Hardware/Software
# FongLab Fp70 - 2013feb
# Author
# tlfong01 <http://tlfong01.blogspot.hk/>
# Configuration
# Raspberry Pi Bv2 512MB, Raspbian Wheezy, Python 2.7.3, RPI.GPIO 0.5.0a,
# PythonWiringPi 1.0.5, RPIO v0.8.4
# License
# GNU GPLv3
# Warranty
# For hobbist only. Use at your own risk. There is not any warranty.
# System development methodologies/Programming paradims
# Software prototyping, Test-driven (TDD), Iterative and incremental (IID),
# Agile/Functional Programming (FP), Object Oriented Programming (OOP).
# Specifications summary
# 5V0max 50mA, 3V3max 300mA, PerPinMax 17mA source 12mA sink
# References
# IO Expander
# 1. Mcirochip Application Notes AN1043 (GPIO Expander)
# Matrix keypad
# 2. Microchip Application Notes AN1081 (Matrix Keypad)
# LCD1602
# 3. ShenZhen YaJingDa Electronics YJD1602A-1 datasheet (2007-09-08)
# 4. PowerTip PC-1602F datasheet (11/10/2004)
# 5. Sitronix ST7066U Dot Matrix LCD Controller/Driver datasheet (01/03/01)
# Raspberry Pi communities
# eLinux - http://elinux.org/RPi_Community
# element14 - http://www.element14.com/community/groups/raspberry-pi
# *****************************************************************************
# 0. Contents ******************************************************************
#
# 1. Program title
# 2. Python imports
# 3. RPi GPIO pin assignment, MCP230xx register base assignment
# 4. Global constants
# 5. GPIO Functions
# 6. Debugging and documentation functions (beep, print bit/byte, message)
# 7. IO Expander Mcp23008, Mcp23017
# 8. Decimal keypad
# 9. LCD - LCD1602. LCD2004
# 10. Stepping motor - unlpolar steppers 28BYJ48/NPM-PF35/PX245
# 11. Demultiplexor
# 12. Old test functions
# 13. Main program
# 1. Program Title ************************************************************
ProgramTitle1 = "GuzuntyPi Test01"
ProgramTitle2 = "FPL709 20130317a"
# ProgramTitle1 = "RPIO.PWM 2013"
# ProgramTitle2 = "Servo testing"
# ProgramTitle1 = "Guzunty Pi 2013"
# ProgramTitle2 = "XC9572XL M12"
# ProgramTitle1 = "SPI603 20130312a"
# ProgramTitle2 = "FPL603 20130312a"
# 2 Python imports ***********************************************************
import sys
import time
import select
# import RPi.GPIO as GPIO # Use RPi.GPIO
import RPIO as GPIO # Use RPIO
import smbus
import spidev
from RPIO import PWM
smBus1 = smbus.SMBus(1)
# GPIO.setmode(GPIO.BOARD) # Use Raspberry Pi P1 header pin numbering
GPIO.setmode(GPIO.BCM) # Use BMC GPIO channel number
# 3. GPIO and IO Expander pin/address assignments *****************************
I2cBaseAddress0 = 0x20
I2cBaseAddress1 = 0x21
I2cBaseAddress2 = 0x22
I2cBaseAddress3 = 0x23
I2cBaseAddress4 = 0x24
I2cBaseAddress5 = 0x25
I2cBaseAddress6 = 0x26
I2cBaseAddress7 = 0x27
# System A I2C base address assignment *
Mcp23017BaseAddress1 = 0x22 # LED, button
Mcp23008BaseAddress1 = 0x24 # stepping motors
Mcp23008BaseAddress2 = 0x25 # keypad
Mcp23008BaseAddress3 = 0x26 # LCD1602
# System B I2C base address assignment *
Mcp23017BaseAddressSystemB1 = 0x20
Mcp23008BaseAddressSystemB1 = 0x21
Mcp23008BaseAddressSystemB1 = 0x21
# * GPIO pin numbering *
# GPIO.setwarnings(False) # Disable linux's "pin already in use warning" !!! DO NOT DISABLE !!!
# * RPi GPIO pin 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-13 RPi GPIO_GEN2 (BCM17) LED (P1-13 > LED > 330R > Gnd) !!! New
# P1-14 Gnd
# P1-20 Gnd
# P1-22 GPIO_GEN6 - Mcp23008 INT / Mcp23017 INTA
# P5-05 GPIO_GEN9 - Buzzer, 3V3 5mA (P5-05 > Buzzer > Gnd) !!! New
# P5-06 GPIO_GEN10 Button (3V3 > 10K > Contact 1/2 > 330R > Gnd) !!! New
# * BCM GPIO channel numbering *
RPiGPIOgen2 = 27 # (P1-13, BCM GPIO 27) Test LED
RPiGPIOgen9 = 30 # (P5-05, BCM GPIO 30) Buzzer
RPiGPIOgen10 = 31 # (P5-06, BCM GPIO 31) Button
LEDpin = RPiGPIOgen2
BuzzerPin = RPiGPIOgen9
ButtonPin = RPiGPIOgen10
RPiTxD = 14 # (P1-08, BCM GPIO 14) UART TxD
RPiRxD = 15 # (P1-10, BCM GPIO 15) UART RxD
TxdPin = RPiTxD
RxdPin = RPiRxD
RPiGPIOgen6 = 25 # (P1-22, BCM GPIO 25) IOx/keypad interrupt
RPiGPIOgen1 = 18 # (P1-12, BCM GPIO 18) PCM_CLK
RPiGPIOGclk = 04 # (P1-07, BCM GPIO 04) GPIO_GCLK
RPiPcm = RPiGPIOgen1
RPiGpclk0 = RPiGPIOGclk
# * I2C, SPI, JTAG,
RpiGpioSpiSelect0 = 7 # SPI_CE1_N (P1-26, BCM GPIO 7)
RpiGpioSpiSelect1 = 8 # SPI_CE0_N (P1-24, BCM GPIO 8)
RpiGpioSpiMiso = 9 # SPI_MISO (P1-21, BCM GPIO 9)
RpiGpioSpiMosi = 10 # SPI_MOSI (P1-10, BCM GPIO 10)
RpiGpioSpiClk = 11 # SPI_SCLK (P1-23, BCM GPIO 11)
SpiClockPin = RpiGpioSpiClk
SpiMosiPin = RpiGpioSpiMosi
SpiMisoPin = RpiGpioSpiMiso
SpiSelect0Pin = RpiGpioSpiSelect0
SpiSelect1Pin = RpiGpioSpiSelect1
RPiGPIOgen1 = 18 # PCM_CLK (P1-12, BCM GPIO 18) used
RPiGPIOGclk = 4 # GPIO_GCLK (P1-07, BCM GPIO 04) not used
RpiGpioGen0 = 17 # GPIO_GEN0 (P1-11, BCM GPIO 17, Alt Jtag TCK)
RpiGpioGen3 = 22 # GPIO_GEN0 (P1-15, BCM GPIO 22, Alt Jtag TDO)
RpiGpioGen4 = 23 # GPIO_GEN4 (P1-16, BCM GPIO 23, Alt Jtag TDI)
RpiGpioGen5 = 24 # GPIO_GEN5 (P1-18, BCM GPIO 24, Alt Jtag TMS)
JtagTckPin = RpiGpioGen0
JtagTdoPin = RpiGpioGen3
JtagTdiPin = RpiGpioGen4
JtagTmsPin = RpiGpioGen5
# * GPIO input/output pins list *
#OutputPinList = [LEDpin, BuzzerPin, TxdPin, SpiClockPin, SpiMosiPin, SpiSelect0Pin, SpiSelect1Pin]
#InputPinWithPullUpList = [ButtonPin, RxdPin, RPiGPIOgen6, SpiMisoPin]
OutputPinList = [LEDpin, BuzzerPin, TxdPin]
InputPinWithPullUpList = [ButtonPin, RxdPin, RPiGPIOgen6]
InputPinWithNoPullUpList = []
JtagOutputPinList = [JtagTckPin, JtagTdoPin, JtagTmsPin]
JtagInputPinList = [JtagTdiPin]
#JtagOutputPinList = [JtagTckPin, JtagTdoPin, JtagTmsPin, JtagTdiPin] # debug only
#JtagInputPinList = [] # debug only
# 4. 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
OneHundredMilliSeconds = 0.1
TwoHundredMilliSeconds = 0.2
TenthSecond = 0.1
QuarterSecond = 0.25
HalfSecond = 0.5
OneSecond = 1
OneAndHalfSeconds = 1.5
TwoSeconds = 2
# * On/Off times *
OnTime = TenthSecond
OffTime = QuarterSecond
ButtonDebouncingTime = QuarterSecond
TestTime = FiftyMilliSeconds
OnTime = 0.1
OffTime = 0.25
# 5. GPIO Functions ***********************************************************
# * Local constants *
# * 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
# * Interrupt states *
Low = False
High = True
# * 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:
setupInputPinWithNoPullUp(iPin)
for iPin in inputPinWithPullUpList:
setupInputPinWithPullUp(iPin)
def SetupGPIO(): # set up GPIO pins
SetupGPIOpins(OutputPinList, InputPinWithNoPullUpList, InputPinWithPullUpList )
def CleanUpGpio(): #
GPIO.cleanup()
def SetupJtagGpio():
SetupGPIOpins(outputPinList = JtagOutputPinList, inputPinWithNoPullUpList = JtagInputPinList, inputPinWithPullUpList = [])
def TestJtagGpio():
SetupGPIOpins(outputPinList = JtagOutputPinList, inputPinWithNoPullUpList = JtagInputPinList, inputPinWithPullUpList = [])
# * pulse/echo/toggle functions *
def pulsePin(oPin, onTime, offTime): # blink LED or beep buzzer
writeOutputPin(oPin, On)
time.sleep(onTime)
writeOutputPin(oPin, Off)
time.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)
time.sleep(toggleTime)
writeOutputPin(oPin, Off)
time.sleep(toggleTime)
# * Test Buzzer, LED, Button *
def TestBuzzer(): # beep 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(BuzzerPin, OnTime, OffTime)
def TestLED(): # blink 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(LEDpin, OnTime, OffTime)
def TestGpioPin(oPin, toggleTime, toggleCount):
for i in range(toggleCount):
togglePin(oPin, toggleTime)
def TestButtonEchoBuzzer(): #
SetupGPIO()
print "\n", "Press button 4 times.", "\n"
for i in range (FourTimes):
echoPin(ButtonPin, BuzzerPin)
def TestButtonEchoTxD(): #
SetupGPIO()
print "\n", "Press button 4 times.", "\n"
for i in range (FourTimes):
echoPin(ButtonPin, TxdPin)
def TestButtonEchoRxD(): #
SetupGPIO()
print "\n", "Press button 4 times.", "\n"
for i in range (FourTimes):
echoPin(ButtonPin, RxdPin)
def TestRxdEchoTxD(): #
SetupGPIO()
print "\n", "RxD Echo TxD - Press button 4 times.", "\n"
for i in range (FourTimes):
echoPin(RxdPin, TxdPin)
def TestButtonEchoLED(): #
SetupGPIO()
print "\n", "Press button 4 times.", "\n"
for i in range (FourTimes):
echoPin(ButtonPin, LEDpin)
def TestTxdPin(): # blink 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(TxdPin, OnTime, OffTime)
def TestRxdPin(): # blink 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(RxdPin, OnTime, OffTime)
def TestTxdPinRxdPin1(): # blink, read 4 times
SetupGPIO()
for i in range (FourTimes):
writeOutputPin(TxdPin, On)
if readInputPin(RxdPin) == High:
print "RxD input = High"
else:
print "RxD input = Low"
time.sleep(1)
writeOutputPin(TxdPin, Off)
if readInputPin(RxdPin) == High:
print "RxD input = High"
else:
print "RxD input = Low"
time.sleep(1)
def TestTxdPinRxdPin2(): #
SetupGPIO()
print "\n", "Short to Ground RxdPin 4 times.", "\n"
for i in range (FourTimes):
echoPin(RxdPin, TxdPin)
# GPIO Interrupt function !!! not yet tested !!!
def TestInterruptPinFallingEdgeDetection(): # !!! Not tested !!!
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
time.sleep(1)
continue
GPIO.set_low_event(InterruptPin, enable = False) # disable detection
print "End of test, or interrupt detected"
def TestJtagPins(toggleTime, testCount):
SetupJtagGpio()
Beep(1)
for i in range(testCount):
togglePin(JtagTckPin, toggleTime)
Beep(1)
for i in range(testCount):
togglePin(JtagTdoPin, toggleTime)
Beep(1)
for i in range(testCount):
togglePin(JtagTmsPin, toggleTime)
# Beep(1)
# for i in range(testCount):
# togglePin(JtagTdiPin, toggleTime)
# Beep(2)
# for i in range(testCount):
# if readInputPin(JtagTdiPin) == High:
# print "JtagTdiPin = High"
# else:
# print "JtagTdiPin = Low"
# for i in range(testCount):
# writeOutputPin(JtagTdoPin, On)
# if readInputPin(JtagTdiPin) == High:
# print "JtagTdiPin = High"
# else:
# print "JtagTdiPin = Low"
# time.sleep(1)
# writeOutputPin(JtagTdoPin, Off)
# if readInputPin(JtagTdiPin) == High:
# print "JtagTdiPin = High"
# else:
# print "JtagTdiPin = Low"
# time.sleep(1)
for i in range(testCount):
writeOutputPin(JtagTdoPin, 1)
if readInputPin(JtagTdiPin) == 1:
print "JtagTdiPin = 1"
else:
print "JtagTdiPin = 0"
time.sleep(1)
writeOutputPin(JtagTdoPin, 0)
if readInputPin(JtagTdiPin) == 1:
print "JtagTdiPin = 1"
else:
print "JtagTdiPin = 0"
time.sleep(1)
Beep(3)
GPIO.cleanup()
# 5. Debugging and documentation functions ************************************
# * Data bit processing and printing *
def SetDataBit(dataByte, bitIndex):
setDataByte = 0x01 << bitIndex
dataByte = dataByte | setDataByte
return dataByte
def ResetDataBit(dataByte, bitIndex):
resetDataByte = ~(0x01 << bitIndex)
dataByte = dataByte & resetDataByte
return dataByte
def ConvertIntegerToFourBitPattern(integer):
FourBitPattern = [""]
for k in range(4):
FourBitPattern = [i+j for i in ['0','1'] for j in FourBitPattern]
return FourBitPattern[integer]
def ConvertIntegerToEightPattern(integer):
EightBitPattern = [""]
for k in range(8):
EightBitPattern = [i+j for i in ['0','1'] for j in EightBitPattern]
return EightBitPattern[integer]
def PrintEightBitPattern(message, dataByte):
eightBitPattern = ConvertIntegerToEightPattern(dataByte)
print message, eightBitPattern
def PrintFourBitPattern(message, dataByte):
fourBitPattern = ConvertIntegerToFourBitPattern(dataByte)
print message, fourBitPattern
def Beep(count):
for i in range(count):
pulsePin(BuzzerPin, OnTime, OffTime)
def StartBeep():
Beep(2)
time.sleep(1)
def StopBeep():
Beep(2)
def OneBeep():
Beep(1)
def FourBeeps():
Beep(4)
def StartProgram():
message = "\n" + "*** Start Program - " + ProgramTitle1 + " ***" + "\n"
CleanUpGpio()
SetupGPIO()
StartBeep()
print message
def StopProgram():
SetupGPIO()
StopBeep()
# print "\n" + "*** Resetting GPIO input, no pull up/down, no event detect. ***" + "\n"
CleanUpGpio()
print "\n" + "*** Stop Program ***" + "\n"
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# 7. IO Expander Mcp23008, Mcp23017 *******************************************
# * Local constants *
# * Port type *
PortA = 0
PortB = 1
# * Mcp23008/Mcp23017 register address offsets index Bank 0 *
InputOutputDirection = 0
InputPolarity = 1
InterruptEnable = 2
DefaultValue = 3
CompareMode = 4
BankInterruptPinMode = 5
PullUp = 6
InterruptFlag = 7
InterruptCapture = 8
PortStatus = 9
OutputLatch = 10
# * Data constant bytes *
AllOutputByte = 0x00
AllInputByte = 0xff
AllHighByte = 0xff
AllLowByte = 0x00
AllPullUpByte = 0xff
# * Direction setting bytes *
HalfHighHalfLow = 0xf0
HalfLowHalfHigh = 0x0f
Nibble1HighNibble2Low = 0xf0
Nibble1LowNibble2High = 0x0f
HighNibbleInputLowNibbleOutput = 0xf0
# * Mcp23008/Mcp23017 Bank0/Bank1 register address offset arrays *
Mcp23008RegisterAddressOffsetArray = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a]
RegisterAddressOffsetArrayBank0 = [0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14,
0x01, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x1d, 0x0f, 0x11, 0x13, 0x15]
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * Mcp23008 Functions *
def SetupPortAllOutputMcp23008(registerBaseAddress):
WriteDataByteMcp23008(registerBaseAddress, InputOutputDirection, AllOutputByte)
def SetupPortAllInputMcp23008(registerBaseAddress):
WriteDataByteMcp23008(registerBaseAddress, InputOutputDirection, AllInputByte)
def WriteDataByteMcp23008(registerBaseAddress, dataRegisterIndex, dataByte):
addressOffset = Mcp23008RegisterAddressOffsetArray[dataRegisterIndex]
smBus1.write_byte_data(registerBaseAddress, addressOffset, dataByte)
def ReadDataByteMcp23008(registerBaseAddress, dataRegisterIndex):
addressOffset = Mcp23008RegisterAddressOffsetArray[dataRegisterIndex]
dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
return dataByte
def WriteDataBitMcp23008(registerBaseAddress, dataRegisterIndex, bitNumber, dataBit):
addressOffset = Mcp23008RegisterAddressOffsetArray[dataRegisterIndex + 11]
dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
bitMask = 0x01 << bitNumber
if (dataBit == 1):
dataByte = dataByte | bitMask
else:
dataByte = dataByte & (~bitMask)
smBus1.write_byte_data(registerBaseAddress, addressOffset, dataByte)
def ToggleGpMcp23008(registerBaseAddress, toggleTime, toggleCount):
SetupMcp23008PortAllOutput(registerBaseAddress)
for i in range(toggleCount):
WriteDataByteMcp23008(registerBaseAddress, OutputLatch, AllHighByte)
time.sleep(toggleTime)
WriteDataByteMcp23008(registerBaseAddress, OutputLatch, AllLowByte)
time.sleep(toggleTime)
def ReadGpMcp23008(registerBaseAddress, count):
SetupMcp23008PortAllInput(registerBaseAddress)
for i in range(count):
dataByte = ReadDataByteMcp23008(registerBaseAddress, PortStatus)
PrintEightBitPattern("Data byte read = ", dataByte)
time.sleep(1)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * Mcp23017 Functions *
def SetupMcp23017BothPortAllOutput(registerBaseAddress):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortA, AllOutputByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortB, AllOutputByte)
def SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortA, AllOutputByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortB, AllInputByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, PullUp, PortB, AllPullUpByte)
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 WriteDataBit(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType, bitNumber, dataBit):
if (portType == PortA) | (portType == PortA):
addressOffset = registerAddressArray[dataRegisterIndex]
if (portType == PortB):
addressOffset = registerAddressArray[dataRegisterIndex + 11]
dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
bitMask = 0x01 << bitNumber
if (dataBit == 1):
dataByte = dataByte | bitMask
else:
dataByte = dataByte & (~bitMask)
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
def ReadDataBit(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType, bitNumber):
if (portType == PortA):
addressOffset = registerAddressArray[dataRegisterIndex]
if (portType == PortB):
addressOffset = registerAddressArray[dataRegisterIndex + 11]
dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
bitMask = 0x01 << bitNumber
dataByte = dataByte & bitMask
if (dataByte == 0):
dataBit = 0
else:
dataBit = 1
return dataBit
def ReadUpperNibble(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType):
dataByte = ReadDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType)
upperNibble = dataByte >> 4
return upperNibble
def ReadLowerNibble(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType):
dataByte = ReadDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType)
lowerNibble = dataByte & 0x0f
return lowerNibble
# * Config interrupts *
def EnableInterruptOnChangeHighNibble(registerBaseAddress):
EnableInterruptHighNibble = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortA, EnableInterruptHighNibble)
def DisableInterruptOnChangeHighNibble(registerBaseAddress):
DisableInterruptHighNibble = 0x00
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortA, DisableInterruptHighNibble)
def SetInterruptOnChangeDefaultHighNibble(registerBaseAddress):
DefaultValueByte = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptOnChangeDefaultValue, PortA, DefaultValueByte)
def SetInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress):
InterruptOnChangeDefaultValueHighNibble = 0xf0 # GP4~7 change from default value will cause interrupt
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, CompareMode, PortA, InterruptOnChangeDefaultValueHighNibble)
def SetInterruptOutputPushPull(registerBaseAddress): # interrupt pin open drain, no auto add inc, no slew rate
PushPull = 0b00111010 # 0x32, seq/slew disabled, interrupt output drive drive (push pull) active High
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, PushPullOpenDrain, PortA, PushPull)
def SetInterruptOutputOpenDrain(registerBaseAddress): # interrupt pin open drain, no auto add inc, no slew rate
OpenDrain = 0b00111000 # 0x34, seq/slew disabled, interrupt output open drain (don't care active High or Low)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, PushPullOpenDrain, PortA, OpenDrain)
# * Poll interrupts *
def ReadInterruptFlagHighNibble(registerBaseAddress):
interruptFlagByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptFlag, PortA)
interruptFlagNbble = interruptFlagByte >> 4
return interruptFlagNibble
def ReadInterruptCaptureHighNibble(registerBaseAddress):
interruptCaptureByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptCapture, PortA)
interruptCaptureNibble = interruptCaptureByte >> 4
return interruptCaptureNibble
def ReadInterruptCaptureLowNibble(registerBaseAddress):
interruptCaptureByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptCapture, PortB)
interruptCaptureNibble = interruptCaptureByte & 0x0f
return interruptCaptureNibble
def DetectOneInterrupt(registerBaseAddress): # !!! NOT tested !!!
interruptFlagNibble = ReadInterruptFlagHighNibble(registerBaseAddress)
interruptCaptureNibble = ReadInterruptCaptureHighNibble(registerBaseAddress)
print "Interrupt capture high nibble = ", ConvertIntegerToFourBitPattern(interruptCaptureNibble)
print "Interrupt capture high nibble = ", ConvertIntegerToFourBitPattern(interruptCaptureNibble)
ClearInterruptOnChangeHighNibble(registerBaseAddress) # !!! clear interrupt !!!
time.sleep(2)
# * Test port toggling, poll interrupts *
def ToggleMcp23017GP(registerBaseAddress, toggleTime, toggleCount):
SetupMcp23017BothPortAllOutput(registerBaseAddress)
for i in range(toggleCount):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllHighByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortB, AllHighByte)
time.sleep(toggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllLowByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortB, AllLowByte)
time.sleep(toggleTime)
def ToggleMcp23017B1(registerBaseAddress, toggleTime, toggleCount):
SetupMcp23017BothPortAllOutput(registerBaseAddress)
for i in range(toggleCount):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllHighByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortB, AllHighByte)
time.sleep(toggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllLowByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortB, AllLowByte)
time.sleep(toggleTime)
def TestToggleMcp23017GP():
ToggleMcp23008GP(Mcp23017BaseAddress1, ToggleTime, ToggleCount)
def TestDetectInterrupt(count): # !!! NOT Tested !!!
RegisterBaseAddress = Mcp23008BaseAddress2
SetupKeypadInterruptHighNibbleCompareDefaultValueOpenDrainOutput(RegisterBaseAddress)
for i in range(count):
DetectOneInterrupt(RegisterBaseAddress)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * System B test functions *
def TestToggleMcp23017SystemB1(count):
ToggleTime = 0.5
ToggleCount = 4
registerBaseAddress = Mcp23017BaseAddressSystemB1
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(count):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllHighByte)
time.sleep(ToggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllLowByte)
time.sleep(ToggleTime)
def TestToggleMcp23017PortAoutput(registerBaseAddress, toggleTime, toggleCount):
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(toggleCount):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllHighByte)
time.sleep(toggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, AllLowByte)
time.sleep(toggleTime)
def TestReadMcp23017SystemB1(count):
registerBaseAddress = Mcp23017BaseAddressSystemB1
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(count):
dataByte = ReadDataByte(Mcp23017BaseAddressSystemB1, RegisterAddressOffsetArrayBank0, PortStatus, PortB)
PrintEightBitPattern("Data byte read = ", dataByte)
time.sleep(1)
def TestReadMcp23017PortBinput(registerBaseAddress, readTime, readCount):
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(readCount):
dataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, PortStatus, PortB)
PrintEightBitPattern("MCP23x17 Port B data byte read = ", dataByte)
time.sleep(1)
def TestBlinkMcp23017SystemB1GPIObit(bitNumber, onTime, offTime, count) :
registerBaseAddress = Mcp23017BaseAddressSystemB1
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(count):
WriteDataBit(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, bitNumber, High)
time.sleep(onTime)
WriteDataBit(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, bitNumber, Low)
time.sleep(offTime)
def TestReadMcp23017SystemB1GPIObit(bitNumber, count):
registerBaseAddress = Mcp23017BaseAddressSystemB1
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
for i in range(count):
dataBit = ReadDataBit(registerBaseAddress, RegisterAddressOffsetArrayBank0, PortStatus, PortB, bitNumber)
if (dataBit == High):
print "Data bit is High"
else:
print "Data bit is Low"
time.sleep(1)
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
# 8. Decimal keypad ***********************************************************
# * Decimal keypad using Mcp23017 v4.17 2013feb15 *
# * Configuration *
# Mcp23017 GPIO direction - Port A = output, Port B = input
# Keypad pin assignment - GPA0~A2 = Col0~2, GPB0~B3 = Row0~3
KeypadInterruptPinMcp23017 = RPiGPIOgen6
# * Local constants *
RegisterBaseAddress = 0x20
OutputLatchRegisterResetValue = 0x00
PortStatusRegisterResetValue = 0x00
InterruptCaptureRegisterResetValue = 0x00
InterruptFlagRegisterResetValue = 0x00
# * Polling modes *
NoPollJustGetKeyEverySecond = 0
PollRowStatusNibble = 1
PollMcp23017Interrupt = 2
# * Setup keypad *
def SetupKeypadMcp017(registerBaseAddress):
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
SetupKeypadInterruptMcp23017(registerBaseAddress) # buggy !!!!!!!!!!
ClearKeypadInterruptMcp23017(registerBaseAddress)
WriteKeypadColumnsAllLowMcp23017(registerBaseAddress)
# * Setup/Clear/Check keypad interrupt *
def SetupKeypadInterruptMcp23017(registerBaseAddress):
SetKeypadInterruptEnableMcp23017(registerBaseAddress)
SetKeypadDefaultValueMcp23017(registerBaseAddress)
SetKeypadEnableCompareDefaultValueMcp23017(registerBaseAddress)
SetKeypadBankInterruptDriverModeMcp23017(registerBaseAddress)
def SetKeypadInterruptEnableMcp23017(registerBaseAddress):
EnableInterruptLowNibble = 0x0f
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortB, EnableInterruptLowNibble)
def SetKeypadInterruptDisableMcp23017(registerBaseAddress):
DisableInterruptByte = 0x00
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortB, DisableInterruptByte)
def SetKeypadDefaultValueMcp23017(registerBaseAddress):
DefaultValueByte = 0x0f # row status nibble is all bits high if no key pressed
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, DefaultValue, PortB, DefaultValueByte)
def SetKeypadEnableCompareDefaultValueMcp23017(registerBaseAddress):
InterruptOnChangeDefaultValueLowNibble = 0x0f # GPB0~3 change from default value will cause interrupt
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, CompareMode, PortB, InterruptOnChangeDefaultValueLowNibble)
def SetKeypadBankInterruptDriverModeMcp23017(registerBaseAddress):
# bit 7 = 0 (Bank = 0, reg with each port are in the same bank (addresses are sequential))
# bit 6 = 0 (No mirror, INTA and INTB independent)
# bit 5 = 1 (Sequential operation disabled)
# bit 4 = 1 (Slew rate disabled)
# bit 3 = 0 (Disable MCP23S17 address pins, Don't care for Mcp23017)
# bit 2 = 0 (Interrupt driver push pull, no open drain)
# bit 1 = 1 (Interrrupt active high)
# bit 0 = 0 (Unimplemented, read as 0)
# 0b00110010 = 0x32
Bank0DriverPushPullHighActive = 0x32
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, BankInterruptPinMode, PortB, Bank0DriverPushPullHighActive)
def ClearKeypadInterruptMcp23017(registerBaseAddress):
WriteKeypadColumnsAllLowMcp23017(registerBaseAddress)
time.sleep(0.5)
dummyRead = ReadInterruptCaptureLowNibble(registerBaseAddress)
# * Write columns *
def WriteKeypadColumnsMcp23017(registerBaseAddress, columnDataByte):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, columnDataByte)
def WriteKeypadColumnsAllLowMcp23017(registerBaseAddress):
WriteKeypadColumnsMcp23017(registerBaseAddress, AllLowByte)
# * Read rows *
def GetKeypadRowDataNibbleMcp23017(registerBaseAddress):
rowDataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, PortStatus, PortB)
rowDataNibble = rowDataByte & 0x0f
return rowDataNibble
# * Get Row Number, Column Number, and Key Number *
def GetKeypadRowNumberMcp23017(registerBaseAddress):
RowDataNibbleTuple = 0b1110, 0b1101, 0b1011, 0b0111, 0b1111, 0b0000
rowDataNibble = GetKeypadRowDataNibbleMcp23017(registerBaseAddress)
# *** Begin debugging *****************************************************
PrintFourBitPattern("Row pattern = ", rowDataNibble)
rowNumber = RowDataNibbleTuple.index(rowDataNibble)
print ("Row number = ", rowNumber)
# *** End debugging *******************************************************
rowNumber = RowDataNibbleTuple.index(rowDataNibble)
return rowNumber
def GetKeypadColumnNumberMcp23017(registerBaseAddress):
ColumnNibbleTuple = 0b1110, 0b1101, 0b1011
NoKeyPressNibble = 0b1111
for columnNibble in (ColumnNibbleTuple):
WriteKeypadColumnsMcp23017(registerBaseAddress, columnNibble)
rowDataNibble = GetKeypadRowDataNibbleMcp23017(registerBaseAddress)
if rowDataNibble != NoKeyPressNibble:
break
columnNumber = ColumnNibbleTuple.index(columnNibble)
return columnNumber
def GetKeypadKeyNumberMcp23017(registerBaseAddress):
rowNumber = GetKeypadRowNumberMcp23017(registerBaseAddress)
columnNumber = GetKeypadColumnNumberMcp23017(registerBaseAddress)
keyNumber = (rowNumber * 3) + (columnNumber + 1)
return keyNumber
# * Get keys *
def GetKeypadKeyMcp23017(registerBaseAddress, checkPressingKeyMode):
if (checkPressingKeyMode == NoPollJustGetKeyEverySecond):
print "Read key every second"
time.sleep(1)
LoopUntilOneSecondEnded()
elif (checkPressingKeyMode == PollRowStatusNibble):
print "Polling Gpio"
LoopUntilKeypadRowDataNibbleChangeMcp23017(registerBaseAddress)
elif (checkPressingKeyMode == PollMcp23017Interrupt):
print "Polling Mcp23017 interrupt INTB"
LoopUntilKeypadInterruptPinMcp23017Active(registerBaseAddress)
keyNumber = GetKeypadKeyNumberMcp23017(registerBaseAddress)
return keyNumber
def GetKeypadKeySequenceMcp23017(registerBaseAddress, checkPressingKeyMode, count):
for i in range (count):
OneBeep()
keyNumber = GetKeypadKeyMcp23017(registerBaseAddress, checkPressingKeyMode)
print "Key", i + 1, " = ", keyNumber
time.sleep(0.25)
# * No polling, just read key at the end of each second *
def LoopUntilOneSecondEnded():
time.sleep(1)
# * Poll row status *
def LoopUntilKeypadRowDataNibbleChangeMcp23017(registerBaseAddress):
WriteKeypadColumnsMcp23017(registerBaseAddress, AllLowByte)
NoKeyPressedNibble = 0xf
rowDataNibble = NoKeyPressedNibble
while (rowDataNibble == NoKeyPressedNibble):
rowDataNibble = GetKeypadRowDataNibbleMcp23017(registerBaseAddress)
time.sleep(0.05) # debouncing time 50mS
# * Poll Mcp23017 interrupt pin *
def LoopUntilKeypadInterruptPinMcp23017Active(registerBaseAddress):
# Mcp23017 INTB shifted up to 5V) logical level, then connected to Mcp23017 GPB5
KeypadInterruptPinNumber = 5
ClearKeypadInterruptMcp23017(registerBaseAddress)
interruptDataBit = High # !!! ULN2803 inverts Mcp23017 INTB, so interrupt is now Low active !!!
while (interruptDataBit == High):
interruptDataBit = ReadDataBit(registerBaseAddress, RegisterAddressOffsetArrayBank0, PortStatus, PortB, KeypadInterruptPinNumber)
time.sleep(0.1) # debouncing time
# * Test Mcp23017 Decimal keypad *
def TestKeypadMcp23017(registerBaseAddress, checkPressingKeyMode, keyCount):
SetupKeypadMcp017(registerBaseAddress)
GetKeypadKeySequenceMcp23017(registerBaseAddress, checkPressingKeyMode, keyCount)
SetupKeypadMcp017(registerBaseAddress)
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
# * Decimal keypad using 2x Mcp23008 v4.19 2013feb17 *
RegisterBaseAddress1 = 0x21
RegisterBaseAddress1 = 0x22
# Mcp23008 #1 0x21 port = output, GP0~2 = Rows 0~2
# Mcp23008 #2 0x22 port = input, GP0~3 = Columns 0~3
KeypadInterruptPinMcp23008 = RPiGPIOgen6
# * Local constants *
OutputLatchRegisterResetValue = 0x00
PortStatusRegisterResetValue = 0x00
InterruptCaptureRegisterResetValue = 0x00
InterruptFlagRegisterResetValue = 0x00
# * Polling modes *
NoPollJustGetKeyEverySecond = 0
PollRowStatusNibble = 1
PollMcp23017Interrupt = 2
# * Setup keypad *
def SetupKeypadMcp23008(registerBaseAddress1, registerBaseAddress2):
SetupPortAllOutputMcp23008(registerBaseAddress1)
SetupPortAllInputMcp23008(registerBaseAddress2)
#SetupKeypadInterruptMcp23008(registerBaseAddress)
#ClearKeypadInterruptMcp23008(registerBaseAddress)
WriteKeypadColumnsAllLowMcp23008(registerBaseAddress1)
# * Setup/Clear/Check keypad interrupt *
#def SetupKeypadInterruptMcp23008(registerBaseAddress):
# SetKeypadInterruptEnableMcp23008(registerBaseAddress)
# SetKeypadDefaultValueMcp23008(registerBaseAddress)
# SetKeypadEnableCompareDefaultValueMcp23008(registerBaseAddress)
# SetKeypadBankInterruptDriverModeMcp23008(registerBaseAddress)
#def SetKeypadInterruptEnableMcp23008(registerBaseAddress):
# EnableInterruptLowNibble = 0x0f
# WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortB, EnableInterruptLowNibble)
#def SetKeypadInterruptDisableMcp23008(registerBaseAddress):
# DisableInterruptByte = 0x00
# WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InterruptEnable, PortB, DisableInterruptByte)
#def SetKeypadDefaultValueMcp23008(registerBaseAddress):
# DefaultValueByte = 0x0f # row status nibble is all bits high if no key pressed
# WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, DefaultValue, PortB, DefaultValueByte)
#def SetKeypadEnableCompareDefaultValueMcp23008(registerBaseAddress):
# InterruptOnChangeDefaultValueLowNibble = 0x0f # GPB0~3 change from default value will cause interrupt
# WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, CompareMode, PortB, InterruptOnChangeDefaultValueLowNibble)
#def SetKeypadBankInterruptDriverModeMcp23008(registerBaseAddress):
# bit 7 = 0 (Bank = 0, reg with each port are in the same bank (addresses are sequential))
# bit 6 = 0 (No mirror, INTA and INTB independent)
# bit 5 = 1 (Sequential operation disabled)
# bit 4 = 1 (Slew rate disabled)
# bit 3 = 0 (Disable MCP23S17 address pins, Don't care for Mcp23017)
# bit 2 = 0 (Interrupt driver push pull, no open drain)
# bit 1 = 1 (Interrrupt active high)
# bit 0 = 0 (Unimplemented, read as 0)
# 0b00110010 = 0x32
# Bank0DriverPushPullHighActive = 0x32
# WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, BankInterruptPinMode, PortB, Bank0DriverPushPullHighActive)
#def ClearKeypadInterruptMcp23008(registerBaseAddress):
# WriteKeypadColumnsAllLowMcp23008(registerBaseAddress)
# time.sleep(0.5)
# dummyRead = ReadInterruptCaptureLowNibble(registerBaseAddress)
# * Write columns *
def WriteKeypadColumnsMcp23008(registerBaseAddress, columnDataByte):
WriteDataByteMcp23008(registerBaseAddress, OutputLatch, columnDataByte)
def WriteKeypadColumnsAllLowMcp23008(registerBaseAddress):
WriteKeypadColumnsMcp23008(registerBaseAddress, AllLowByte)
# * Read rows *
def GetKeypadRowDataNibbleMcp23008(registerBaseAddress):
rowDataByte = ReadDataByteMcp23008(registerBaseAddress, PortStatus)
rowDataNibble = rowDataByte & 0x0f
return rowDataNibble
# * Get Row Number, Column Number, and Key Number *
def GetKeypadRowNumberMcp23008(registerBaseAddress):
RowDataNibbleTuple = 0b1110, 0b1101, 0b1011, 0b0111, 0b1111, 0b0000
rowDataNibble = GetKeypadRowDataNibbleMcp23008(registerBaseAddress)
# *** Begin debugging *****************************************************
PrintFourBitPattern("Row pattern = ", rowDataNibble)
rowNumber = RowDataNibbleTuple.index(rowDataNibble)
print ("Row number = ", rowNumber)
# *** End debugging *******************************************************
rowNumber = RowDataNibbleTuple.index(rowDataNibble)
return rowNumber
def GetKeypadColumnNumberMcp23008(registerBaseAddress1, registerBaseAddress2):
ColumnNibbleTuple = 0b1110, 0b1101, 0b1011
NoKeyPressNibble = 0b1111
for columnNibble in (ColumnNibbleTuple):
WriteKeypadColumnsMcp23008(registerBaseAddress1, columnNibble)
rowDataNibble = GetKeypadRowDataNibbleMcp23008(registerBaseAddress2)
if rowDataNibble != NoKeyPressNibble:
break
columnNumber = ColumnNibbleTuple.index(columnNibble)
return columnNumber
def GetKeypadKeyNumberMcp23008(registerBaseAddress1, registerBaseAddress2):
rowNumber = GetKeypadRowNumberMcp23008(registerBaseAddress2)
columnNumber = GetKeypadColumnNumberMcp23008(registerBaseAddress1, registerBaseAddress2)
keyNumber = (rowNumber * 3) + (columnNumber + 1)
return keyNumber
# * Get keys *
def GetKeypadKeyMcp23008(registerBaseAddress1, registerBaseAddress2, checkPressingKeyMode):
if (checkPressingKeyMode == NoPollJustGetKeyEverySecond):
print "Read key every second"
time.sleep(1)
LoopUntilOneSecondEnded()
elif (checkPressingKeyMode == PollRowStatusNibble):
print "Polling Gpio"
LoopUntilKeypadRowDataNibbleChangeMcp23008(registerBaseAddress1, registerBaseAddress2)
elif (checkPressingKeyMode == PollMcp23017Interrupt):
print "Polling Mcp23017 interrupt INTB"
LoopUntilKeypadInterruptPinMcp23008Active(registerBaseAddress2)
keyNumber = GetKeypadKeyNumberMcp23008(registerBaseAddress1, registerBaseAddress2)
return keyNumber
def GetKeypadKeySequenceMcp23008(registerBaseAddress1, registerBaseAddress2, checkPressingKeyMode, count):
for i in range (count):
OneBeep()
keyNumber = GetKeypadKeyMcp23008(registerBaseAddress1, registerBaseAddress2, checkPressingKeyMode)
print "Key", i + 1, " = ", keyNumber
time.sleep(0.25)
# * No polling, just read key at the end of each second *
def LoopUntilOneSecondEnded():
time.sleep(1)
# * Poll row status *
def LoopUntilKeypadRowDataNibbleChangeMcp23008(registerBaseAddress1, registerBaseAddress2):
WriteKeypadColumnsMcp23008(registerBaseAddress1, AllLowByte)
NoKeyPressedNibble = 0xf
rowDataNibble = NoKeyPressedNibble
while (rowDataNibble == NoKeyPressedNibble):
rowDataNibble = GetKeypadRowDataNibbleMcp23008(registerBaseAddress2)
time.sleep(0.05) # debouncing time 50mS
# * Poll interrupt pin *
def LoopUntilKeypadInterruptPinMcp23008Active(registerBaseAddress):
# Mcp23017 INTB shifted up to 5V) logical level, then connected to Mcp23017 GPB5
KeypadInterruptPinNumber = 5
ClearKeypadInterrupt(registerBaseAddress)
interruptDataBit = High # !!! ULN2803 inverts Mcp23017 INTB, so interrupt is now Low active !!!
while (interruptDataBit == High):
interruptDataBit = ReadDataBit(registerBaseAddress, RegisterAddressOffsetArrayBank0, PortStatus, PortB, KeypadInterruptPinNumber)
time.sleep(0.1) # debouncing time
# * Test Decimal keypad Mcp23008 *
def TestKeypadMcp23008(registerBaseAddress1, registerBaseAddress2, checkPressingKeyMode, keyCount):
SetupKeypadMcp23008(registerBaseAddress1, registerBaseAddress2)
GetKeypadKeySequenceMcp23008(registerBaseAddress1, registerBaseAddress2, checkPressingKeyMode, keyCount)
SetupKeypadMcp23008(registerBaseAddress1, registerBaseAddress2)
def TestKeypadMcp23017PollingMode(i2cRegisterBaseAddress):
TestKeypadMcp23017(i2cRegisterBaseAddress, checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * LCD1602 *******************************************************************
LcdRegisterBaseAddress = Mcp23008BaseAddress3 # 0x26
# * LCD1602A-1 16-pin connector (Mcp23008 GPIO 6-pin connector) Pin numbering *
# Pin 04 (Pin 1) RegisterSelect
# Pin 06 (Pin 2) WriteEnable
# Pin 11 (Pin 3) DataBit4 = 2
# Pin 12 (Pin 4) DataBit5 = 3
# Pin 13 (Pin 5) DataBit6 = 4
# Pin 14 (Pin 6) DataBit7 = 5
# LCD1602 software initialization procedure
# Part 1 - Pseudo 8 bit instructions to config 4 bit instruction mode (0x30, 0x30, 0x30, 0x20)
# 1. Power on, wait 20mS (> 15mS)
# 2. Write 0x3, wait 5mS (> 4.1mS) # set 8 bit interface
# 3. Write 0x3, wait 1mS (> 100uS) # set 8 bit interface
# 4. Write 0x3, wait 1mS (> 37uS) # set 8 bit interface
# 5. Write 0x2, wait 1mS (> 37uS) # set 4 bit interface
# Part 2- 4 bit instructions to config display characteristics (0x28, 0x08, 0x01, 0x06, 0x02)
# 6. Write 0x2, wait 1mS (> 37uS) 0x8 wait 1mS (> 37uS) (2 lines, 5x8 dot)
# 7. Write 0x0, wait 1mS (> 37uS) 0x8 wait 1mS (> 37uS) (cursor on, no blinking, blank screen)
# 8. Write 0x0, wait 1mS (> 37uS) 0x1 wait 2mS (> 1.52mS)(clear display)
# 9. Write 0x0, wait 1mS (> 37uS) 0xe (DisplayOnCursorOnCursorBlinkOff)
# a. Write 0x0, wait 1mS (> 37uS) 0x2 wait 2mS (cursor home)
# * LCD1602A-1 16-pin connector pin numbering *
RegisterSelect = 0 # 0 = instruction register, 1 = data register
WriteEnable = 1 # 1 = enable, 0 = disable
DataBit4 = 2
DataBit5 = 3
DataBit6 = 4
DataBit7 = 5
# * Constant data bytes *
AllZeroDataByte = 0x00
AllOneDataByte = 0xff
# * Write Enable/Disable, Select Data/Instruction masks *
EnableWriteMask = 0x02 # 0b 0000 0010
DisableWriteMask = 0xfd # 0b 1111 1101
SelectDataRegisterMask = 0x01 # 0b 0000 0001
SelectInstructionRegisterMask = 0xfe # 0b 1111 1110
# Register selection constant *
InstructionRegister = 0
DataRegister = 1
# * LCD1602A-1 control instructions *
# * Instruction codes *
EightBitInstructionMode = 0x3
FourBitInstructionMode = 0x2
TwoLineFiveTimesEightDot1 = 0x2
TwoLineFiveTimesEightDot2 = 0x8
DisplayOnCursorOnCursorBlinkOff1 = 0x0
DisplayOnCursorOnCursorBlinkOff2 = 0xe
ClearDisplay1 = 0x0
ClearDisplay2 = 0x1
CursorIncrementDisplayNoShift1 = 0x0
CursorIncrementDisplayNoShift2 = 0x6
CursorHome1 = 0x0
CursorHome2 = 0x2
# * Instruction timing *
PowerOnResetDelay = 0.05 # 50mS
VeryLongOperationDelay = 0.005 # 5mS
LongOperationDelay = 0.002 # 2mS
ShortOperationDelay = 0.00005 # 50uS
WritePulseLength = 0.00005 # 50uS
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * LCD functions Mcp23008 v4.15 2013feb15 *
def LcdGpioSetupMcp23008(registerBaseAddress):
SetupPortAllOutputMcp23008(registerBaseAddress)
def LcdConfigurationMcp23008(registerBaseAddress):
dataControlByte = AllZeroDataByte
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
LcdDisableWriteMcp23008(registerBaseAddress, dataControlByte)
time.sleep(PowerOnResetDelay)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, VeryLongOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte03 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte04 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, FourBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte05 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte06 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte07 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte08 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte09 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, ClearDisplay1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte10 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, ClearDisplay2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte11 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte12 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte13 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, CursorHome1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte14 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, CursorHome2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte15 = ", dataControlByte)
return dataControlByte
def LcdSelectDataRegisterMcp23008(registerBaseAddress, dataByte):
dataByte = dataByte | SelectDataRegisterMask
LcdWriteDataByteMcp23008(registerBaseAddress, dataByte)
return dataByte
def LcdSelectInstructionRegisterMcp23008(registerBaseAddress, dataByte):
dataByte = dataByte & SelectInstructionRegisterMask
LcdWriteDataByteMcp23008(registerBaseAddress, dataByte)
return dataByte
def LcdEnableWriteMcp23008(registerBaseAddress, dataByte):
dataByte = dataByte | EnableWriteMask
LcdWriteDataByteMcp23008(registerBaseAddress, dataByte)
return dataByte
def LcdDisableWriteMcp23008(registerBaseAddress, dataByte):
dataByte = dataByte & DisableWriteMask
LcdWriteDataByteMcp23008(registerBaseAddress, dataByte)
return dataByte
def LcdWritePulseMcp23008(registerBaseAddress, dataByte):
LcdEnableWriteMcp23008(registerBaseAddress, dataByte)
time.sleep(WritePulseLength)
LcdDisableWriteMcp23008(registerBaseAddress, dataByte)
return dataByte
def LcdWriteDataByteMcp23008(registerBaseAddress, dataByte):
WriteDataByteMcp23008(registerBaseAddress, OutputLatch, dataByte)
return dataByte
def LcdWriteDataNibbleMcp23008(registerBaseAddress, dataByte, dataNibble, registerType, operationDelay):
dataNibble = dataNibble << 2
dataByte = dataByte & 0b11000011
dataByte = dataByte | dataNibble
if (registerType == InstructionRegister):
dataByte = LcdSelectInstructionRegisterMcp23008(registerBaseAddress, dataByte)
elif (registerType == DataRegister):
dataByte = LcdSelectDataRegisterMcp23008(registerBaseAddress, dataByte)
LcdDisableWriteMcp23008(registerBaseAddress, dataByte)
dataByte = LcdWriteDataByteMcp23008(registerBaseAddress, dataByte)
LcdWritePulseMcp23008(registerBaseAddress, dataByte)
time.sleep(operationDelay)
return dataByte
def LcdWriteCharFourBitModeMcp23008(registerBaseAddress, dataControlByte, asciiChar, registerType):
charUpperNibble = ord(asciiChar) >> 4
charLowerNibble = ord(asciiChar) & 0x0f
LcdWriteCharTwoNibblesMcp23008(registerBaseAddress, dataControlByte, charUpperNibble, charLowerNibble, registerType)
return dataControlByte
def LcdWriteDataByteFourBitModeMcp23008(registerBaseAddress, dataControlByte, dataByte, registerType):
upperNibble = dataByte >> 4
lowerNibble = dataByte & 0x0f
LcdWriteCharTwoNibblesMcp23008(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType)
return dataControlByte
def LcdWriteCharTwoNibblesMcp23008(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType):
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, upperNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23008(registerBaseAddress, dataControlByte, lowerNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
return dataControlByte
def LcdWriteCharStringMcp23008(registerBaseAddress, dataControlByte, string):
for asciiChar in (string):
LcdWriteCharFourBitModeMcp23008(registerBaseAddress, dataControlByte, asciiChar, DataRegister)
return dataControlByte
def LcdMoveCursorMcp23008(registerBaseAddress, dataControlByte, rowNumber, columnNumber):
if (rowNumber == 1):
cursorByte = 0x80 | (0x00 + (columnNumber - 1)) # command = 0x80, row 1 DDRAM start address = 0x10
elif (rowNumber == 2):
cursorByte = 0x80 | (0x40 + (columnNumber - 1)) # row 2 DDRAM start address = 0x40
LcdWriteDataByteFourBitModeMcp23008(registerBaseAddress, dataControlByte, cursorByte, InstructionRegister)
# charUpperNibble = cursorByte >> 4
# charLowerNibble = cursorByte & 0x0f
# dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, charUpperNibble, InstructionRegister, ShortOperationDelay)
# dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, charLowerNibble, InstructionRegister, ShortOperationDelay)
return dataControlByte
# * Test LCD1602 Mcp23008 *
def TestLcdMcp23008(registerBaseAddress):
LcdGpioSetupMcp23008(registerBaseAddress)
dataControlByte = LcdConfigurationMcp23008(registerBaseAddress)
dataControlByte = LcdMoveCursorMcp23008(registerBaseAddress, dataControlByte, 1, 1)
dataControlByte = LcdWriteCharStringMcp23008(registerBaseAddress, dataControlByte, ProgramTitle1)
dataControlByte = LcdMoveCursorMcp23008(registerBaseAddress, dataControlByte, 2, 1)
dataControlByte = LcdWriteCharStringMcp23008(registerBaseAddress, dataControlByte, ProgramTitle2)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * LCD functions Mcp23017 v4.15 2013feb15 *
def LcdGpioSetupMcp23017(registerBaseAddress):
#registerBaseAddress = Mcp23017BaseAddressSystemB1
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
def LcdConfigurationMcp23017(registerBaseAddress):
dataControlByte = AllZeroDataByte
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
LcdDisableWriteMcp23017(registerBaseAddress, dataControlByte)
time.sleep(PowerOnResetDelay)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, VeryLongOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte03 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte04 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, FourBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte05 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte06 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte07 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte08 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte09 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, ClearDisplay1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte10 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, ClearDisplay2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte11 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte12 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte13 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, CursorHome1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte14 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, CursorHome2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte15 = ", dataControlByte)
return dataControlByte
def LcdSelectDataRegisterMcp23017(registerBaseAddress, dataByte):
dataByte = dataByte | SelectDataRegisterMask
LcdWriteDataByteMcp23017(registerBaseAddress, dataByte)
return dataByte
def LcdSelectInstructionRegisterMcp23017(registerBaseAddress, dataByte):
dataByte = dataByte & SelectInstructionRegisterMask
LcdWriteDataByteMcp23017(registerBaseAddress, dataByte)
return dataByte
def LcdEnableWriteMcp23017(registerBaseAddress, dataByte):
dataByte = dataByte | EnableWriteMask
LcdWriteDataByteMcp23017(registerBaseAddress, dataByte)
return dataByte
def LcdDisableWriteMcp23017(registerBaseAddress, dataByte):
dataByte = dataByte & DisableWriteMask
LcdWriteDataByteMcp23017(registerBaseAddress, dataByte)
return dataByte
def LcdWritePulseMcp23017(registerBaseAddress, dataByte):
LcdEnableWriteMcp23017(registerBaseAddress, dataByte)
time.sleep(WritePulseLength)
LcdDisableWriteMcp23017(registerBaseAddress, dataByte)
return dataByte
def LcdWriteDataByteMcp23017(registerBaseAddress, dataByte):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, dataByte)
return dataByte
def LcdWriteDataNibbleMcp23017(registerBaseAddress, dataByte, dataNibble, registerType, operationDelay):
dataNibble = dataNibble << 2
dataByte = dataByte & 0b11000011
dataByte = dataByte | dataNibble
if (registerType == InstructionRegister):
dataByte = LcdSelectInstructionRegisterMcp23017(registerBaseAddress, dataByte)
elif (registerType == DataRegister):
dataByte = LcdSelectDataRegisterMcp23017(registerBaseAddress, dataByte)
LcdDisableWriteMcp23017(registerBaseAddress, dataByte)
dataByte = LcdWriteDataByteMcp23017(registerBaseAddress, dataByte)
LcdWritePulseMcp23017(registerBaseAddress, dataByte)
time.sleep(operationDelay)
return dataByte
def LcdWriteCharFourBitModeMcp23017(registerBaseAddress, dataControlByte, asciiChar, registerType):
charUpperNibble = ord(asciiChar) >> 4
charLowerNibble = ord(asciiChar) & 0x0f
LcdWriteCharTwoNibblesMcp23017(registerBaseAddress, dataControlByte, charUpperNibble, charLowerNibble, registerType)
return dataControlByte
def LcdWriteDataByteFourBitModeMcp23017(registerBaseAddress, dataControlByte, dataByte, registerType):
upperNibble = dataByte >> 4
lowerNibble = dataByte & 0x0f
LcdWriteCharTwoNibblesMcp23017(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType)
return dataControlByte
def LcdWriteCharTwoNibblesMcp23017(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType):
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, upperNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, lowerNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
return dataControlByte
def LcdWriteCharStringMcp23017(registerBaseAddress, dataControlByte, string):
for asciiChar in (string):
LcdWriteCharFourBitModeMcp23017(registerBaseAddress, dataControlByte, asciiChar, DataRegister)
return dataControlByte
def LcdMoveCursorMcp23017(registerBaseAddress, dataControlByte, rowNumber, columnNumber):
if (rowNumber == 1):
cursorByte = 0x80 | (0x00 + (columnNumber - 1)) # command = 0x80, row 1 DDRAM start address = 0x10
elif (rowNumber == 2):
cursorByte = 0x80 | (0x40 + (columnNumber - 1)) # row 2 DDRAM start address = 0x40
LcdWriteDataByteFourBitModeMcp23017(registerBaseAddress, dataControlByte, cursorByte, InstructionRegister)
# charUpperNibble = cursorByte >> 4
# charLowerNibble = cursorByte & 0x0f
# dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, charUpperNibble, InstructionRegister, ShortOperationDelay)
# dataControlByte = LcdWriteDataNibbleMcp23017(registerBaseAddress, dataControlByte, charLowerNibble, InstructionRegister, ShortOperationDelay)
return dataControlByte
# * Test LCD1602 functions *
def TestLcdMcp23017(i2cRegisterBaseAddress):
LcdGpioSetupMcp23017(i2cRegisterBaseAddress)
dataControlByte = LcdConfigurationMcp23017(i2cRegisterBaseAddress)
dataControlByte = LcdMoveCursorMcp23017(i2cRegisterBaseAddress, dataControlByte, 1, 1)
dataControlByte = LcdWriteCharStringMcp23017(i2cRegisterBaseAddress, dataControlByte, ProgramTitle1)
dataControlByte = LcdMoveCursorMcp23017(i2cRegisterBaseAddress, dataControlByte, 2, 1)
dataControlByte = LcdWriteCharStringMcp23017(i2cRegisterBaseAddress, dataControlByte, ProgramTitle2)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# 8. 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 Pink Orange Blue Yellow Red
# PX245 Black Green Blue Red Yelow/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, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortA, AllOutputByte)
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, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, hexString1)
time.sleep(StepTime)
WriteDataByte(Mcp23008BaseAddress1, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, hexString2)
time.sleep(StepTime)
def WriteMotorWindingFullStepSequence13232414(RegisterBaseAddress, NibbleType, StepCount, StepTime): #move motor using 13-23-24-14 sequence
# Set port all output
WriteDataByte(Mcp23008BaseAddress1, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortA, AllOutputByte)
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, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, pattern)
time.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 MoveTwoMotors(RegisterBaseAddress):
OneBeep()
WriteMotorWindingWaveSequence1324(Mcp23008BaseAddress1, LowNibble, TwentyTimes, FiftyMilliSeconds)
OneBeep()
WriteMotorWindingWaveSequence1324(Mcp23008BaseAddress1, HighNibble, TwentyTimes, FiftyMilliSeconds)
OneBeep()
WriteMotorWindingFullStepSequence13232414(Mcp23008BaseAddress1, LowNibble, TwentyTimes, OneHundredMilliSeconds)
OneBeep()
WriteMotorWindingFullStepSequence13232414(Mcp23008BaseAddress1, HighNibble, TwentyTimes, OneHundredMilliSeconds)
def TestMotor():
MotorRegisterBaseAddress = Mcp23008BaseAddress1
MoveTwoMotors(MotorRegisterBaseAddress)
def MoveUnipolarSteppingMotor(registerBaseAddress, NibbleType, StepCount, StepTime):
SetupPortAoutputPortBinputPullUpMcp23017(registerBaseAddress)
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(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, hexString1)
time.sleep(StepTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, hexString2)
time.sleep(StepTime)
def TestMoveMotor():
registerBaseAddress = Mcp23017BaseAddressSystemB1
nibbleType = LowNibble
stepCount = OneHundredTimes
stepTime = OneHundredMilliSeconds
MoveUnipolarSteppingMotor(registerBaseAddress, nibbleType, 500, 0.05)
# * Demultiplexer *************************************************************
DemuxRegisterBaseAddress = 0x20
def DemuxGpioSetup(registerBaseAddress):
UpperNibbleInputLowerNibbleOutput = 0xf0 # Input (GP4~7, Row0~3), Output (GP0~3, Column0~2, 3 reserved)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, InputOutputDirection, PortA, UpperNibbleInputLowerNibbleOutput)
InitialControlDateByte = 0x00
return InitialControlDateByte
def DemuxAddressLatch(controlDataByte, latchAction):
DemuxAddressLatchMask = 0b00001000
Enable = 1
Disable = 0
if (latchAction == Enable):
controlDataByte = controlDataByte | DemuxAddressLatchMask
elif (latchAction == Disable):
controlDataByte = controlDataByte & ~(DemuxAddressLatchMask)
return controlDataByte
def SetDemuxChannel(registerBaseAddress, controlDataByte, addressNibble):
Enable = 1
Disable = 0
controlDataByte = controlDataByte & 0b11110000
addressNibble = addressNibble & 0b00000111
controlDataByte = controlDataByte | addressNibble
controlDataByte = DemuxAddressLatch(controlDataByte, Disable)
PrintEightBitPattern("demuxDataByte = ", controlDataByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, controlDataByte)
controlDataByte = DemuxAddressLatch(controlDataByte, Enable)
PrintEightBitPattern("demuxDataByte = ", controlDataByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArrayBank0, OutputLatch, PortA, controlDataByte)
return controlDataByte
def TestDemux(demuxRegisterBaseAddress, channelNumber):
controlDataByte = DemuxGpioSetup(demuxRegisterBaseAddress)
controlDataByte = SetDemuxChannel(demuxRegisterBaseAddress, controlDataByte, channelNumber)
def TestDemuxLcd(demuxRegisterBaseAddress, lcdRegisterBaseAddress, channelNumber1, channelNumber2):
Row1 = 1
Row2 = 2
Row3 = 3
Row4 = 4
Column1 = 1
# Setup one Mcp23008 for Demultiplexor, another Mcp23008 for LCD1602/LCD2004
controlDataByte = DemuxGpioSetup(demuxRegisterBaseAddress)
LcdGpioSetup(lcdRegisterBaseAddress)
# Select demux channelNumber1
controlDataByte = SetDemuxChannel(demuxRegisterBaseAddress, controlDataByte, channelNumber1)
# Display two lines in the LCD at this channel
dataControlByte = LcdConfiguration(lcdRegisterBaseAddress)
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row1, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "Channel 1 01")
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row2, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "2013-01-28 v201")
time.sleep(2)
# Select demux channelNumber2
controlDataByte = SetDemuxChannel(demuxRegisterBaseAddress, controlDataByte, channelNumber2)
# Display two lines in the LCD at this channel
dataControlByte = LcdConfiguration(lcdRegisterBaseAddress)
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row1, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "Channel 2 01")
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row2, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "2013-01-30 v204")
time.sleep(2)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * SPI using bit banging *
# SpiClockPin = RPiGpioGen11
# SpiMosiPin = RPiGpioGen10
# SpiMisoPin = RPiGpioGen9
# SpiSelect0Pin = RPiGpioGen8
# SpiSelect1Pin = RPiGpioGen7
def TestRfm12b(registerBaseAddress):
SetupGPIOpins(OutputPinList, InputPinWithNoPullUpList, InputPinWithPullUpList )
def SpiSelectDevice(deviceNumber):
if (deviceNumber == 0):
writeOutputPin(SpiSelect0Pin, Low)
else:
writeOutputPin(SpiSelect1Pin, Low)
def SpiDisSelectDevice(deviceNumber):
if (deviceNumber == 0):
writeOutputPin(SpiSelect0Pin, High)
else:
writeOutputPin(SpiSelect1Pin, High)
def SpiClockPulse():
writeOutputPin(SpiClockPin, High)
time.sleep(1)
writeOutputPin(SpiClockPin, Low)
time.sleep(1)
def SpiWriteBit(dataBit):
if (dataBit == 1):
writeOutputPin(SpiMosiPin, High)
else:
writeOutputPin(SpiMosiPin, Low)
def SpiReadBit(inputPin):
dataBit = readInputPin(inputPin)
# print dataBit
return dataBit
# * Test Spi functions *
def TestSpiSelectDevice(deviceNumber, count):
print "Now testing SPI device select pin", deviceNumber, ",..."
for i in range (count):
SpiSelectDevice(deviceNumber)
time.sleep(1)
SpiDisSelectDevice(deviceNumber)
time.sleep(1)
def TestSpiClockPulse(count):
for i in range (count):
SpiClockPulse()
def TestSpiWriteBit(count):
for i in range (count):
SpiWriteBit(1)
time.sleep(1)
SpiWriteBit(0)
time.sleep(1)
def TestSpiReadBit(inputPin, count):
for i in range (count):
dataBit = SpiReadBit(inputPin)
if (dataBit == True):
dataLevel = "High"
else:
dataLevel = "Low"
print "dataBitRead at pin number ", inputPin, " = ", dataLevel
time.sleep(1)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * SPI using wiringPi with Python wrapping 2013feb22 *
def TestWiringPiSpi():
print "\n" + "*** Start testing wiringPi SPI, ... ***" + "\n"
spi = spidev.SpiDev() # create spidev object
spi.open(0,0) # open SPI0, CE0_N
SendByteList = [0x55, 0xaa, 0xAA]
ReadByteList = spi.xfer2(SendByteList)
print "Bytes read = " + hex(ReadByteList[0]) + " " + hex(ReadByteList[1]) + " " + hex(ReadByteList[2])
print "\n" + "*** Stop testing wiringPi SPI, ... ***" + "\n"
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * RFM12b 434Mhz Wireless Transceiver testing v1.0 tlfong01 2013feb23 *
# * Arduino C++ functions *
# define wkupOn 0x820E // turn on wake up timer (also xtl, lvd)
# define wkupOff 0x820C // turn off wake up timer (xtl, lvd still on)
# define wkup2ms 0XE002 // wake up every 2mS
# define config01 0x80D7
# define power01 0x8239
# define freq01 0xA640
# define drate01 0xC647
# define rxctrl01 0x94A0
# define fifors01 0xCA81
# define syncpt01 0xCED4
# define afc01 0xC483
# define txctrl01 0x9850
# define pll01 0xCC77
# define wkup01 0xE000
# define ldc01 0xC800
# define lbdclk01 0xC400
# define lvdOn 0x820C // turn on low voltage detection (also xtal, mcu clk)
# define lvd27 0xC064 // set low voltage threshold 2.7V (2.2 + 0.1 * 4) 2MHz,
# define status 0x0000 // read status to execute command and clear interrupt
#void RFM12B01::setupRfm12b()
# {
# putWord(0x80D7); //enable tx, rx fifo, 433MHz, 12.0pF
# // putWord(0x8239); //enable xmitt, syn, xtal, disable clk
# putWord(0xA640); //operation frequency ???
# putWord(0xC647); //data rate 4.8kbps
# putWord(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
# putWord(0xC2AC); //clk rec auto, digi fltr,DQD4
# putWord(0xCA81); //fifo8,sync 1, sync, no fifo fill
# putWord(0xCED4); //sync pattern d4
# putWord(0xC483); //offset VDI hi, no restrict, afc, afc out
# putWord(0x9850); //90kHz, max o/p pwr (odBm)
# putWord(0xCC17); //10MHz, 620uA, disable pll dit, 256kbps
# putWord(0xE000); //wake up timer not used
# putWord(0xC800); //low duty cycle not used
# putWord(0xC040); //1.66MHz,2.2V low battery
# }
#void RFM12B01::testSetupClock2Mhz()
# {
# putWord(0xC064);
# }
def PrintDoubleSpaceLine(line):
print "\n" + line + "\n"
def WaitSeconds(count):
time.sleep(count)
# * Rfm12b 2 byte commands *
SetExternalMpuClockFrequency1Mhz = [0xc0, 0x04] # 1 MHz, 2.7V (2.2 + 0.1 * 4)
SetExternalMpuClockFrequency2Mhz = [0xc0, 0x64] # 2 MHz, 2.7V (2.2 + 0.1 * 4)
SetExternalMpuClockFrequency5Mhz = [0xc0, 0xc4] # 5 MHz, 2.7V (2.2 + 0.1 * 4)
SetExternalMpuClockFrequency10Mhz = [0xc0, 0xe4] # 10 MHz, 2.7V (2.2 + 0.1 * 4)
EnableWakeupTimerEnableXtlLvd = [0x82, 0x0e]
DisableWakeupTimerEnableXtlLvd = [0x82, 0x0c]
SetWakeUpTimer2Ms = [0xe0, 0x02]
ClearInterrupt = [0x00, 0x00]
def TestRfm12bSet2Mhz():
PrintDoubleSpaceLine("*** Start testing RFM12B 2 MHz ***")
rfm12bSpi = spidev.SpiDev() # create spi object to entertain RFM12B
rfm12bSpi.open(0,0) # open sci channel 0 and select slave device 0
ExternalMpuClockFrequency2Mhz = [0xC0, 0x64]
receiveByteList = rfm12bSpi.xfer2(ExternalMpuClockFrequency2Mhz)
print "Bytes read = " + hex(receiveByteList[0]) + " " + hex(receiveByteList[1])
PrintDoubleSpaceLine("*** Stop testing RFM12B ***")
def TestRfm12bSet1Mhz():
PrintDoubleSpaceLine("*** Start testing RFM12B 1 MHz ***")
rfm12bSpi = spidev.SpiDev() # create spi object to entertain RFM12B
rfm12bSpi.open(0,0) # open sci channel 0 and select slave device 0
ExternalMpuClockFrequency2Mhz = [0xc0, 0x04]
receiveByteList = rfm12bSpi.xfer2(ExternalMpuClockFrequency2Mhz)
print "Bytes read = " + hex(receiveByteList[0]) + " " + hex(receiveByteList[1])
PrintDoubleSpaceLine("*** Stop testing RFM12B ***")
def OpenSpiChannel(spiObject, spiChannelNumber, spiDeviceNumber):
spiObject.open(spiChannelNumber, spiDeviceNumber)
def Rfm12bSendCommand1(spiChannelNumber, spiDeviceNumber, sendByteList):
rfm12bSpi = spidev.SpiDev()
rfm12bSpi.open(spiChannelNumber, spiDeviceNumber)
receiveByteList = rfm12bSpi.xfer2(sendByteList)
def Rfm12bSendCommand2(rfm12bSpi, sendByteList):
receiveByteList = rfm12bSpi.xfer2(sendByteList)
def Rfm12bTest1(spiChannelNumber, spiDeviceNumber):
PrintDoubleSpaceLine("*** Start Test 1 ***")
rfm12bSpi = spidev.SpiDev() # create spi object to entertain RFM12B
rfm12bSpi.open(0,0) # open sci channel 0 and select slave device 0
Rfm12bSendCommand1(spiChannelNumber, spiDeviceNumber, SetExternalMpuClockFrequency2Mhz)
WaitSeconds(2)
Rfm12bSendCommand1(spiChannelNumber, spiDeviceNumber, SetExternalMpuClockFrequency5Mhz)
WaitSeconds(2)
Rfm12bSendCommand1(spiChannelNumber, spiDeviceNumber, SetExternalMpuClockFrequency10Mhz)
WaitSeconds(2)
Rfm12bSendCommand1(spiChannelNumber, spiDeviceNumber, SetExternalMpuClockFrequency1Mhz)
WaitSeconds(2)
PrintDoubleSpaceLine("*** Stop Test 1 ***")
def Rfm12bTest2(spiChannelNumber, spiDeviceNumber):
PrintDoubleSpaceLine("*** Start Test 2 ***")
rfm12bSpi = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi, spiChannelNumber, spiDeviceNumber)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency2Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency5Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency10Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency1Mhz)
WaitSeconds(2)
PrintDoubleSpaceLine("*** Stop Test 2 ***")
def Rfm12bTest3a(spiChannelNumber, spiDeviceNumber):
PrintDoubleSpaceLine("*** Start Test 3a ***")
rfm12bSpi = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi, spiChannelNumber, spiDeviceNumber)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency2Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency5Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency1Mhz)
WaitSeconds(2)
Rfm12bSendCommand2(rfm12bSpi, TurnOnWakeupXtlLvd)
Rfm12bSendCommand2(rfm12bSpi, WakeUpEvery2Ms)
# WaitSeconds(2)
# Rfm12bSendCommand2(rfm12bSpi, TurnOffWakeupTurnOnXtlLvd)
PrintDoubleSpaceLine("*** Stop Test 3a ***")
def Rfm12bTest3b(spiChannelNumber, spiDeviceNumber):
PrintDoubleSpaceLine("*** Start Test 3b 2013feb2601 ***")
rfm12bSpi = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi, spiChannelNumber, spiDeviceNumber)
Rfm12bSendCommand2(rfm12bSpi, SetExternalMpuClockFrequency2Mhz)
Rfm12bSendCommand2(rfm12bSpi, TurnOnWakeupXtlLvd)
for i in range (100000):
Rfm12bSendCommand2(rfm12bSpi, WakeUpEvery2Ms)
time.sleep(0.005)
Rfm12bSendCommand2(rfm12bSpi, ClearInterrupt)
time.sleep(0.010)
Rfm12bSendCommand2(rfm12bSpi, TurnOffWakeupTurnOnXtlLvd)
PrintDoubleSpaceLine("*** Stop Test 3b ***")
def Rfm12bTest3c(spiChannelNumber, spiDeviceNumber0, spiDeviceNumber1):
PrintDoubleSpaceLine("*** Start Test 3c 2013feb2602 ***")
rfm12bSpi00 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi00, spiChannelNumber, spiDeviceNumber0)
Rfm12bSendCommand2(rfm12bSpi00, SetExternalMpuClockFrequency5Mhz)
rfm12bSpi01 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi01, spiChannelNumber, spiDeviceNumber1)
Rfm12bSendCommand2(rfm12bSpi01, SetExternalMpuClockFrequency10Mhz)
PrintDoubleSpaceLine("*** Stop Test 3c ***")
def Rfm12bTest3d(spiChannelNumber, spiDeviceNumber0, spiDeviceNumber1):
PrintDoubleSpaceLine("*** Start Test 3d 2013feb2603 ***")
rfm12bSpi00 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi00, spiChannelNumber, spiDeviceNumber0)
Rfm12bSendCommand2(rfm12bSpi00, SetExternalMpuClockFrequency2Mhz)
rfm12bSpi01 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi01, spiChannelNumber, spiDeviceNumber1)
Rfm12bSendCommand2(rfm12bSpi01, SetExternalMpuClockFrequency5Mhz)
for i in range(4):
Beep(1)
Rfm12bSendCommand2(rfm12bSpi00, DisableWakeupTimerEnableXtlLvd)
Rfm12bSendCommand2(rfm12bSpi00, ClearInterrupt)
time.sleep(2)
Beep(2)
Rfm12bSendCommand2(rfm12bSpi00, EnableWakeupTimerEnableXtlLvd)
Rfm12bSendCommand2(rfm12bSpi00, SetWakeUpTimer2Ms)
time.sleep(2)
Beep(3)
Rfm12bSendCommand2(rfm12bSpi01, DisableWakeupTimerEnableXtlLvd)
Rfm12bSendCommand2(rfm12bSpi01, ClearInterrupt)
time.sleep(2)
Beep(4)
Rfm12bSendCommand2(rfm12bSpi01, EnableWakeupTimerEnableXtlLvd)
Rfm12bSendCommand2(rfm12bSpi01, SetWakeUpTimer2Ms)
time.sleep(2)
PrintDoubleSpaceLine("*** Stop Test 3d ***")
def TestRfm12bExtMpuClock(spiChannelNumber, Rfm12bSpiDeviceNumber0, Rfm12bSpiDeviceNumber1):
PrintDoubleSpaceLine("*** Start RFM12B Test ***")
rfm12bSpi00 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi00, spiChannelNumber, Rfm12bSpiDeviceNumber0)
Rfm12bSendCommand2(rfm12bSpi00, SetExternalMpuClockFrequency5Mhz)
rfm12bSpi01 = spidev.SpiDev()
OpenSpiChannel(rfm12bSpi01, spiChannelNumber, Rfm12bSpiDeviceNumber1)
Rfm12bSendCommand2(rfm12bSpi01, SetExternalMpuClockFrequency2Mhz)
PrintDoubleSpaceLine("*** Stop Test ***")
def TestDualRfm12bExtMpuClock(spiChannelNumber):
TestRfm12bExtMpuClock(spiChannelNumber, Rfm12bSpiDeviceNumber0 = 0, Rfm12bSpiDeviceNumber1 = 1)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * Test RPIO.PWM v1.0 tlfong01 2013mar13 *
# RPIO.PWM, PWM via DMA for the Raspberry Pi
# http://pythonhosted.org/RPIO/pwm_py.html
# PCA9685 16-channel, 12-bit PWM Fm+ I2 C-bus LED controller
# http://www.nxp.com/documents/data_sheet/PCA9685.pdf
# TSSOP28\SSOP28\DIP28 Adapter
# http://item.taobao.com/item.htm?spm=a230r.1.14.108.UHRZYa&id=12717853271
# Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685
# http://www.adafruit.com/products/815
# http://learn.adafruit.com/adafruits-raspberry-pi-lesson-8-using-a-servo-motor/servo-motors
# http://learn.adafruit.com/adafruits-raspberry-pi-lesson-8-using-a-servo-motor/the-pwm-and-servo-kernel-module
# *** Seeeduino & Towerpro SG90 Test Program - TL Fong 2009jan08
# http://www.todopic.com.ar/foros/index.php?topic=24768.5;wap2
# /******************************************************************************
# * Hello Servo - Turn TowerPro SG90 servo to middle position
# * Created - 2009jan07, Last update - 2008jan07
# * Function - Turn servo to middle position
# * MPU/Programming language - Seeeduino v1.1/Arduino v12.0
# * Author - TL Fong (tlfong01, TaoBao)
# * Copyright - Creative Commons Attribution - ShareAlike 3.0 Licence
# *
# * Test procedure
# * (1) FIRST run the program, [!!! DO NOT POWER ON YET !!! tlfong01 2013mar13]
# * (2) Manually turn servo clockwise or counterclock to limit,
# * (3) Connect 5V power and MPU signal to servo,
# * (4) WARNING - Disconnect 5V power before stopping program,
# *
# * TowerPro SG90 Spec
# * CCW end 900uS, CW end 2100uS, middle 1500uS, 3.0 to 6.0V,
# * 9g, 22 * 11.5 * 27mm, 0.12sec/60 degrees (4.8V no load),
# * stall torque 17.5ozin/1.2 kgcm) (4.8V), dead band 7usec,
# * coreless motor, all nylon gear, RMB30 (TaoBao).
# *
# * Notes
# * 1. To turn counter clockwise limit, change pulse width from 1500 to 900.
# * 2. To turn clockwise limit, change pulse width from to 2100.
# RPiGPIOgen1 = 18 # (P1-12, BCM GPIO 18) PCM_CLK
# RPiGPIOGclk = 04 # (P1-07, BCM GPIO 04) GPIO_GCLK
# RPiPcm = RPiGPIOgen1
# RPiGpclk0 = RPiGPIOGclk
def TestRpioServo():
CounterClockwiseLimitPulseWidth = 900 # CCW limit = 900 uS = 0.9 mS
ClockwiseLimitPulseWidth = 2100 # CW limit = 2100 uS = 2.1 mS
MiddlePositionPulseWidth = 1500 # Middle position = 1500 uS = 1.5 mS
PrintDoubleSpaceLine("*** Testing RPIO.PCM tlfong01 2013mar13 ***")
RpioServoController = PWM.Servo() # default 20ms subcycle
RpioServoController.set_servo(RPiPcm, CounterClockwiseLimitPulseWidth)
RpioServoController.set_servo(RPiGpclk0, MiddlePositionPulseWidth)
time.sleep(60)
def TestRpioClock01():
PrintDoubleSpaceLine("*** Testing RPIO.PCM tlfong01 2013mar13 ***")
TenMilliSeconds = 10000
RpioServoController = PWM.Servo() # default 20ms subcycle
RpioServoController.set_servo(RPiGpclk0, TenMilliSeconds)
time.sleep(60)
def SetClock(channelNumber, frequency, rpiPin, timeSeconds): # maximum frequency = 100 Hz
cycleTime = 1000000 / frequency
startTime = (cycleTime / 2) / 10
pulseWidth = ((cycleTime / 2) / 10) - 1
PWM.setup()
PWM.init_channel(channelNumber, cycleTime)
PWM.add_channel_pulse(channelNumber, rpiPin, startTime, pulseWidth)
time.sleep(timeSeconds)
PWM.clear_channel_gpio(channelNumber, rpiPin)
PWM.cleanup()
def SetRpiGpClk0(frequencyHz, waitTime):
SetClock(channelNumber = 0, frequency = frequencyHz, rpiPin = RPiGpclk0, timeSeconds = waitTime)
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# * Guzunty Pi test functions v1.0 tlfong01 2013mar16 *
# XC9572XL-5-PC44 gz_16o8i Fitter Report 2013-01-05
# https://raw.github.com/Guzunty/Pi/master/src/gz_16o8i/gz_16o8i.rpt
#** 17 Outputs **
# Signal Name Loc Pin
# outputs<0> FB1_2 1
# outputs<1> FB1_5 2
# outputs<2> FB1_6 3
# outputs<3> FB1_8 4
# outputs<4> FB1_15 8
# outputs<5> FB1_17 9
# outputs<6> FB2_2 35
# outputs<7> FB2_5 36
# outputs<8> FB2_6 37
# outputs<9> FB2_8 38
# outputs<10> FB2_15 43
# outputs<11> FB2_17 44
# outputs<12> FB3_2 11
# outputs<13> FB3_5 12
# outputs<14> FB3_8 13
# outputs<15> FB3_9 14
# miso FB4_17 34
# ** 11 Inputs **
# Signal Name Loc Pin Type
# inputs<6> FB1_11 6~ GCK/I/O [GCK2]
# inputs<7> FB1_14 7~ GCK/I/O [GCK3]
# inputs<0> FB3_14 19 I/O
# inputs<1> FB3_15 20 I/O
# inputs<2> FB3_16 24 I/O
# inputs<3> FB3_17 22 I/O
# inputs<4> FB4_2 25 I/O
# inputs<5> FB4_5 26 I/O
# sclk FB4_11 28 I/O
# mosi FB4_14 29 I/O
# sel FB4_15 33 I/O
# ** Device Pin Out **
# --------------------------------
# /6 5 4 3 2 1 44 43 42 41 40 \
# | 7 39 |
# | 8 38 |
# | 9 37 |
# | 10 36 |
# | 11 XC9572XL-5-PC44 35 |
# | 12 34 |
# | 13 33 |
# | 14 32 |
# | 15 31 |
# | 16 30 |
# | 17 29 |
# \ 18 19 20 21 22 23 24 25 26 27 28 /
# --------------------------------
# Pin Signal Pin Signal
# No. Name No. Name
# 1 outputs<0> 23 GND
# 2 outputs<1> 24 inputs<2>
# 3 outputs<2> 25 inputs<4>
# 4 outputs<3> 26 inputs<5>
# 5 KPR 27 KPR
# 6 inputs<6> 28 sclk
# 7 inputs<7> 29 mosi
# 8 outputs<4> 30 TDO
# 9 outputs<5> 31 GND
# 10 GND 32 VCC
# 11 outputs<12> 33 sel
# 12 outputs<13> 34 miso
# 13 outputs<14> 35 outputs<6>
# 14 outputs<15> 36 outputs<7>
# 15 TDI 37 outputs<8>
# 16 TMS 38 outputs<9>
# 17 TCK 39 KPR
# 18 KPR 40 KPR
# 19 inputs<0> 41 VCC
# 20 inputs<1> 42 KPR
# 21 VCC 43 outputs<10>
# 22 inputs<3> 44 outputs<11>
# Legend :
# NC = Not Connected, unbonded pin
# PGND = Unused I/O configured as additional Ground pin
# TIE = Unused I/O floating -- must tie to VCC, GND or other signal
# KPR = Unused I/O with weak keeper (leave unconnected)
# VCC = Dedicated Power Pin
# GND = Dedicated Ground Pin
# TDI = Test Data In, JTAG pin
# TDO = Test Data Out, JTAG pin
# TCK = Test Clock, JTAG pin
# TMS = Test Mode Select, JTAG pin
# PROHIBITED = User reserved pin
#def SpiWriteTwoByteArray(spiChannel, outputTwoByteArray):
# inputTwoByteArray = spiChannel.xfer2(outputTwoByteArray)
# print "Input Two Byte Array = " + hex(inputTwoByteArray[0]) + " " + hex(inputTwoByteArray[1])
# time.sleep(2)
# return inputTwoByteArray
def TestGuzuntyPi16o8iCoreOutputTwoBytes():
PrintDoubleSpaceLine("*** Start testing Guzunty Pi Core 16o8i ***")
AllHighTwoByteArray = [0xff, 0xff]
AllLowTwoByteArray = [0x00, 0x00]
AlternateTwoByteArray = [0x55, 0xaa]
TestTwoByteArrayList = (AllHighTwoByteArray, AlternateTwoByteArray, AllLowTwoByteArray)
guzuntypiSpi = spidev.SpiDev() #create spi object for quzuntypi
guzuntypiSpi.open(0, 0) # open spi channel 0 and select slave device 0
Beep(1)
for i in range(2):
guzuntypiSpi.xfer2([0x00, 0x00])
time.sleep(1)
guzuntypiSpi.xfer2([0xff, 0xff])
time.sleep(1)
guzuntypiSpi.xfer2([0x55, 0x55])
time.sleep(1)
Beep(2)
for i in range(2):
guzuntypiSpi.xfer2(AllLowTwoByteArray)
time.sleep(1)
guzuntypiSpi.xfer2(AllHighTwoByteArray)
time.sleep(1)
guzuntypiSpi.xfer2(AlternateTwoByteArray)
time.sleep(1)
Beep(3)
for outputTwoByteArray in (TestTwoByteArrayList):
guzuntypiSpi.xfer2(outputTwoByteArray)
time.sleep(1)
PrintDoubleSpaceLine("*** Stop testing GuzuntyPi ***")
def TestGuzuntyPiSteppingMotor():
PrintDoubleSpaceLine("*** Start testing Guzunty Pi Stepping Motor ***")
guzuntypiSpi = spidev.SpiDev()
guzuntypiSpi.open(0, 0)
Beep(2)
# !!! OK IF PASSING LIST BY VALUE !!!
for i in range(10):
guzuntypiSpi.xfer2([0x05, 0x00])
time.sleep(0.05)
guzuntypiSpi.xfer2([0x0a, 0x00])
time.sleep(0.05)
Beep(4)
# !!! NOT WORKING IF PASSING LIST BY REFERENCE !!!
# Winding13 = [0x05, 0x00]
# Winding24 = [0x0a, 0x00]
# for i in range(10):
# guzuntypiSpi.xfer2(Winding13)
# time.sleep(2)
# guzuntypiSpi.xfer2(Winding24)
# time.sleep(2)
# guzuntypiSpi.xfer2(Winding13) # !!! BUG !!! all windings on !!!
# time.sleep(2)
# guzuntypiSpi.xfer2(Winding24)
# time.sleep(2)
# !!! NOT WORKING IF PASSING LIST BY REFERENCE !!!
# Winding13 = [0x05, 0x00]
# Winding24 = [0x0a, 0x00]
# for i in range(10):
# guzuntypiSpi.xfer2(Winding13)
# time.sleep(2)
# guzuntypiSpi.xfer2(Winding24)
# time.sleep(2)
# !!! NOT WORKING IF PASSING LIST BY REFERENCE !!!
# Winding13 = [0x05, 0x00]
# Winding24 = [0x0a, 0x00]
# for i in range(10):
# guzuntypiSpi.open(0, 0) # open close each loop
# guzuntypiSpi.xfer2(Winding13)
# time.sleep(2)
# guzuntypiSpi.xfer2(Winding24)
# time.sleep(2)
# guzuntypiSpi.close()
guzuntypiSpi.close()
PrintDoubleSpaceLine("*** Stop testing GuzuntyPi ***")
def TestGuzuntyPiReadByte():
PrintDoubleSpaceLine("*** Start testing Guzunty Pi Read Byte ***")
guzuntypiSpi = spidev.SpiDev()
guzuntypiSpi.open(0, 0)
Beep(4)
dummyDataByteList = [0x55]
for i in range(10):
inputDataByteList = guzuntypiSpi.xfer2(dummyDataByteList)
PrintEightBitPattern("guzuntypi byte read = ", inputDataByteList[0])
time.sleep(1)
guzuntypiSpi.close()
PrintDoubleSpaceLine("*** Stop testing GuzuntyPi ***")
# 12. Old test functions *****************************************************
# * Old tests *
# RPi System A Tests *
# TestBuzzer() # beep buzzer 4 times
# TestLED() # blink LED 4 tmes
# TestButtonEchoBuzzer() # echo buton with buzzer 4 times
# TestButtonEchoLED() # echo button with LED 4 times
# TestToggleMcp23017GP() # toggle Mcp23017 #1 output ports (connected to only 1 LED)
# TestToggleMcp23008GP() # toggle Mcp23008 #1 output port (connected to stepping motors)
# TestMotor() # move two stepping motors
# TestPollingKeypad() # read 4 keys by polling IO Expander GPIO port of rows (Mcp23008 #2)
# TestInterruptKeypad() # read 4 keys by polling IO Expander INT pin # !!! not tested !!!
# TestLcd(LcdRegisterBaseAddress)
# TestDemux(DemuxRegisterBaseAddress, 4)
# TestDemuxLcd(DemuxRegisterBaseAddress, LcdRegisterBaseAddress, channelNumber1 = 0, channelNumber2 = 1)
# RPi System B Tests *
# TestBuzzer() # beep buzzer 4 times
# TestLED() # blink LED 4 tmes
# TestButtonEchoBuzzer() # echo buton with buzzer 4 times
# TestButtonEchoLED() # echo button with LED 4 times
# TestToggleMcp23017SystemB1() # toggle Mcp23017 System B1
# TestReadMcp23017SystemB1()
# * Rpi Mcp23017 tests *
# TestButtonEchoBuzzer()
# TestTxdPin()
# TestRxdPin() # if set as output
# TestTxdPin()
# TestTxdPinRxdPin1()
# TestTxdPinRxdPin2()
# TestButtonEchoTxD()
# TestButtonEchoRxD()
# TestRxdEchoTxD() !!! not working !!!
# TestToggleMcp23017SystemB1(count = 4)
# TestReadMcp23017SystemB1(count = 4)
# TestKeypad017(checkPressingKeyMode = NoPollJustGetKeyEverySecond, keyCount = 4)
# TestKeypad017(checkPressingKeyMode = PollMcp23017Interrupt, keyCount = 4)
# TestKeypad017(checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
#TestLED() # blink LED 4 tmes
#TestBuzzer() # beep buzzer 4 times
#TestButtonEchoBuzzer() # echo buton with buzzer 4 times
#TestButtonEchoLED() # echo button with LED 4 times
#TestToggleMcp23017SystemB1(count = 4)
#TestBlinkMcp23017SystemB1GPIObit(bitNumber = 3, onTime = 0.1, offTime = 0.3, count = 4)
#TestReadMcp23017SystemB1GPIObit(bitNumber = 4, count = 10)
#TestKeypad017(checkPressingKeyMode = PollRowStatusNibble, keyCount = 20)
#TestKeypad017(checkPressingKeyMode = PollMcp23017Interrupt, keyCount = 20)
#TestKeypad017(checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
#TestToggleMcp23017SystemB1(count = 4)
#TestBlinkMcp23017SystemB1GPIObit(bitNumber = 3, onTime = 0.1, offTime = 0.3, count = 4)
#TestMoveMotor()
#TestLcd(Mcp23017BaseAddressSystemB1)
#ToggleGpMcp23008(registerBaseAddress = 0x21, toggleTime = 0.25, toggleCount = 4)
#ReadGpMcp23008(registerBaseAddress = 0x22, count = 100)
#TestKeypadMcp23017(registerBaseAddress = 0x20, checkPressingKeyMode = NoPollJustGetKeyEverySecond, keyCount = 4)
#TestKeypadMcp23017(registerBaseAddress = 0x20, checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
#TestKeypadMcp23017(registerBaseAddress = 0x20, checkPressingKeyMode = PollMcp23017Interrupt, keyCount = 4)
#TestKeypadMcp23008(registerBaseAddress1 = 0x21, registerBaseAddress2 = 0x22, checkPressingKeyMode = NoPollJustGetKeyEverySecond, keyCount = 4)
#TestKeypadMcp23008(registerBaseAddress1 = 0x21, registerBaseAddress2 = 0x22, checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
#TestSpiSelectDevice(deviceNumber = 0, count = 4)
#TestSpiSelectDevice(deviceNumber = 1, count = 4)
#TestSpiClockPulse(count = 10)
#TestSpiWriteBit(count = 100)
#TestSpiClockPulse(count = 10)
#TestSpiWriteBit(count = 10)
#TestSpiSelectDevice(deviceNumber = 0, count = 10)
#TestSpiSelectDevice(deviceNumber = 1, count = 4)
#TestSpiReadBit(ButtonPin, count = 10) *** OK ***
#TestSpiReadBit(SpiMisoPin, count = 10) !!! Not working !!!
#TestSpiReadBit(RxdPin, count = 10) !!! Not working !!!
#TestSpiReadBit(ButtonPin, count = 4) # *** OK ***
#TestSpiReadBit(SpiMisoPin, count = 4) # !!! Not working !!!
#TestSpiReadBit(RxdPin, count = 4) # !!! Not working !!
#PrintDoubleSpaceLine("*** Start Test x ***")
#TestRfm12bSet2Mhz()
#WaitSeconds(2)
#TestRfm12bSet1Mhz()
#WaitSeconds(2)
#PrintDoubleSpaceLine("*** Stop Test x ***")
# Rfm12bTest2(spiChannelNumber = 0, spiDeviceNumber = 0)
# Rfm12bTest3b(spiChannelNumber = 0, spiDeviceNumber = 0)
# Rfm12bTest3d(spiChannelNumber = 0, spiDeviceNumber0 = 0, spiDeviceNumber1 = 1)
#TestLcdMcp23017(registerBaseAddress = 0x20)
#TestLcdMcp23008(registerBaseAddress = 0x21)
# TestToggleMcp23017PortAoutput(registerBaseAddress = 0x20, toggleTime = 0.5, toggleCount = 100)
# TestReadMcp23017PortBinput(registerBaseAddress = 0x20, readTime = 2, readCount = 100)
# TestKeypadMcp23017(registerBaseAddress = 0x20, checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
# TestLcdMcp23017(registerBaseAddress = 0x20)
# TestBuzzer() # beep system buzzer 4 times
# TestLED() # blink system LED 4 tmes
# TestButtonEchoBuzzer() # echo system buton with system buzzer 4 times
# TestButtonEchoLED() # echo system button with system LED 4 times
# TestGpioPin(oPin = TxdPin, toggleTime = 0.5, toggleCount = 10)
# TestLcdMcp23017(registerBaseAddress = 0x21)
# TestKeypadMcp23017(registerBaseAddress = 0x21, checkPressingKeyMode = PollRowStatusNibble, keyCount = 4)
# TestRfm12bExtMpuClock(spiChannelNumber = 0, Rfm12bSpiDeviceNumber0 = 0, Rfm12bSpiDeviceNumber1 = 1)
# TestJtagPins(toggleTime = 1, testCount = 2)
# TestLcdMcp23017(i2cRegisterBaseAddress = 0x21) #I2C1
# TestKeypadMcp23017PollingMode(i2cRegisterBaseAddress = 0x21) #I2C1
# TestDualRfm12bExtMpuClock(spiChannelNumber = 0) # SPI0
# TestRpioServo()
# SetClock(channelNumber = 0, frequency = 100, rpiPin = RPiGpclk00, timeSeconds = 4)
# SetClock(channelNumber = 0, frequency = 100, rpiPin = RPiPcm)
# SetRpiGpClk0Frequency64Hz()
# SetRpiGpClk0(frequencyHz = 100, waitTime = 60)
# TestLcdMcp23017(i2cRegisterBaseAddress = 0x21) #I2C1
# TestKeypadMcp23017PollingMode(i2cRegisterBaseAddress = 0x21) #I2C1
# TestDualRfm12bExtMpuClock(spiChannelNumber = 0) # SPI0
# TestRpioServo()
# 13. Main program ************************************************************
StartProgram()
TestLcdMcp23017(i2cRegisterBaseAddress = 0x21) #I2C1
#TestGuzuntyPi16o8iCoreOutputTwoBytes()
#TestGuzuntyPiSteppingMotor()
TestGuzuntyPiReadByte()
StopProgram()
# *****************************************************************************
# End of Program
# *****************************************************************************
pi@raspberrypi ~/python_programs/test_guzuntypi $ sudo python fpl709.py
*** Start Program - GuzuntyPi Test01 ***
*** Start testing Guzunty Pi Read Byte ***
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
guzuntypi byte read = 11110110
*** Stop testing GuzuntyPi ***
*** Stop Program ***
pi@raspberrypi ~/python_programs/test_guzuntypi $ date
Sun Mar 17 07:52:57 UTC 2013
pi@raspberrypi ~/python_programs/test_guzuntypi $
.END
No comments:
Post a Comment