http://www.blogger.com/blogger.g?blogID=1840459474737789074#editor/target=post;postID=4426126429310199744
Now I have mounted the last three boards, demux, LCD1, and LCD2 and tested the LCDs demuxed. Everything went smoothly - both LCD1 on demux channel 0 and LCD2 on channel 1 display OK.
So there are two problems unsolved.
1. The buzzer sound is feeble. But this morning it did once in a long while sounds loud. I guest there might be some wiring, or worse, RPi trace that got damaged and has intermittent failures. Or that the power supply is not stable.
2. The step motors is not working. I guess the problem might also be PSU related. So I think I would try to use an external power for the motors and see if problem solved.
.END
# *****************************************************************************
# !/usr/bin/python2.7
#
# Program
# tdemux1151.py - 2013jan25
# Author
# tlfong01 <http://tlfong01.blogspot.hk/>
# Configuration
# Raspberry Pi Bv2 512MB, Raspbian Wheezy, Python 2.7.3, GPIO 0.4.1a
# License
# GNU GPLv3
# Warranty
# For hobbist only. Use at your own risk. There is not any warranty,
# not even implied warranty of merchantability or fitness for any
# particular purpose
# 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. Python imports
# 2. RPi GPIO pin assignment
# 3. Global constants
# 4. GPIO Functions
# 5. Debugging and documentation functions (beep, print bit/byte, message)
# 6. IO Expander MCP23008, MCP23017
# 7. Unipolar Stepping Motor 28BYJ48/NPM-PF35/PX245
# 8. Decimal keypad
# 9. LCD1602
# 10. Demultiplexor
# 11. Main test functions
# 1. Python imports ***********************************************************
import smbus
import sys
import RPi.GPIO as GPIO
from time import sleep
import select # interrupt module, not tested yet
# from __future__ import print_function # import Python 3 print function so it can be used
# 2. RPi GPIO pin assignment **************************************************
#
GPIO.setmode(GPIO.BOARD) # Use RPi GPIO numbering, Not BCM numbering
GPIO.setwarnings(False) # Disable linux's "pin already in use warning"
# * 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-12 RPi GPIO_GEN1 (BCM18) LED (P1-12 > LED > 330R > Gnd)
# P1-14 Gnd
# P1-16 GPIO_GEN4 - Buzzer, 3V3 5mA (P1-16 > Buzzer > Gnd)
# P1-18 GPIO_GEN5 Button (3V3 > 10K > Contact 1/2 > 330R > Gnd)
# P1-20 Gnd
# P1-22 GPIO_GEN6 - MCP23008 INT / MCP23017 INTA
RPiGPIOgen1 = 12 # Brown (P1-12, BCM GPIO 18) LED
RPiGPIOgen4 = 16 # Yellow (P1-16, BCM GPIO 23) Buzzer
RPiGPIOgen5 = 18 # Green (P1-18, BCM GPIO 24) Button
RPiGPIOgen6 = 22 # Blue (P1-22, BCM GPIO 25) IOx/keypad interrupt
RPiTxD = 8 # Orange (P1-08) UART TxD
RPiRxD = 10 # Yellow (P1-10) UART RxD
# * peripherals pins assignment *
LEDpin = RPiGPIOgen1
BuzzerPin = RPiGPIOgen4
ButtonPin = RPiGPIOgen5
TxDpin = RPiTxD
RxDpin = RPiRxD
KeypadInterruptPin = ButtonPin
# * GPIO input/output pins list *
OutputPinList = [LEDpin, BuzzerPin, TxDpin]
InputPinWithNoPullUpList = [ButtonPin, KeypadInterruptPin, RPiGPIOgen6]
InputPinWithPullUpList = []
# 3. Global constants *********************************************************
# * Loop counters *
TwoTimes = 2
FourTimes = 4
EightTimes = 8
TenTimes = 10
TwentyTimes = 20
FiftyTimes = 50
OneHundredTimes = 100
TwoHundredTimess = 200
FourHundredTimes = 400
# * Elapse times *
TwentyMilliSeconds = 0.02
FiftyMilliSeconds = 0.05
TenthSecond = 0.1
QuarterSecond = 0.25
HalfSecond = 0.5
OneSecond = 1
OneAndHalfSeconds = 1.5
TwoSeconds = 2
# * On/Off times *
OnTime = TenthSecond
OffTime = QuarterSecond
ButtonDebouncingTime = QuarterSecond
TestTime = FiftyMilliSeconds
# * Nibble naming *
LowNibble = 0
HighNibble = 1
BothNibble = 2 # full byte of 8 bits
# * Nibble constants *
HighNibble1LowNibble0 = 0xf0
HighNibble0LowNibble1 = 0x0f
# * LED and buzzer states *
Off = False
On = True
# * Button states *
ButtonPressed = False
ButonReleased = True
# * Interrupt states *
Low = False
High = True
# 4. GPIO Functions ***********************************************************
#
# * Setup, read/write GPIO pins *
setupOutputPin = lambda oPin: GPIO.setup(oPin, GPIO.OUT) # set GPIO pin as output
setupInputPinWithNoPullUp = lambda iPin: GPIO.setup(iPin, GPIO.IN, pull_up_down=GPIO.PUD_OFF) # set GPIO pin as input, no pull up
setupInputPinWithPullUp = lambda iPin: GPIO.setup(iPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set GPIO pin as input, with pull up
writeOutputPin = lambda oPin, oValue: GPIO.output(oPin, oValue) # write value to output pin
setupWriteOutputPin = lambda oPin, oValue: (setupOutputPin(oPin), writeOutputPin(oPin, oValue)) # set and write
readInputPin = lambda iPin: GPIO.input(ButtonPin) # read value from input pin
def SetupGPIOpins(outputPinList, inputPinWithNoPullUpList, inputPinWithPullUpList): # set up GPIO pins in InputPinList and OutputPinList
for oPin in outputPinList:
setupWriteOutputPin(oPin, Off)
for iPin in inputPinWithNoPullUpList:
setupInputPinWithPullUp(iPin)
for iPin in inputPinWithPullUpList:
setupInputPinWithPullUp(iPin)
def SetupGPIO(): # set up GPIO pins
SetupGPIOpins(OutputPinList, InputPinWithNoPullUpList, InputPinWithPullUpList )
# * pulse/echo/toggle functions *
def pulsePin(oPin, onTime, offTime): # blink LED or beep buzzer
writeOutputPin(oPin, On)
sleep(onTime)
writeOutputPin(oPin, Off)
sleep(offTime)
def echoPin(iPin, oPin): # echo input pin to output pin, e.g. button to LED or buzzer
while True:
if readInputPin(iPin) == ButonReleased:
pass
else:
pulsePin(oPin, OnTime, OffTime)
break
continue
def togglePin(oPin, toggleTime): # toggle pin
writeOutputPin(oPin, On)
sleep(toggleTime)
writeOutputPin(oPin, Off)
sleep(toggleTime)
# * Test Buzzer, LED, Button *
def TestBuzzer(): # beep 4 times
SetupGPIO()
for i in range (FourTimes):
pulsePin(BuzzerPin, OnTime, OffTime)
def TestLED(): # blink 8 times
SetupGPIO()
for i in range (EightTimes):
pulsePin(LEDpin, OnTime, OffTime)
def TestButtonEchoBuzzer(): #
SetupGPIO()
for i in range (TenTimes):
echoPin(ButtonPin, BuzzerPin)
def TestButtonEchoLED(): #
SetupGPIO()
for i in range (TenTimes):
echoPin(ButtonPin, LEDpin)
# 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
sleep(1)
continue
GPIO.set_low_event(InterruptPin, enable = False) # disable detection
print "End of test, or interrupt detected"
# 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
OnTime = 0.1
OffTime = 0.25
def Beep(count):
for i in range(count):
pulsePin(BuzzerPin, OnTime, OffTime)
def StartBeep():
Beep(4)
sleep(1)
def EndBeep():
Beep(4)
def OneBeep():
Beep(1)
def FourBeeps():
Beep(4)
def StartProgram(message):
SetupGPIO()
StartBeep()
print "\n", message, "\n"
def EndProgram():
EndBeep()
endMessage = "*** End of program.***"
print "\n", endMessage, "\n"
# 6. IO Expander MCP23008, MCP23017 *******************************************
# * Setup SMBus *
I2C_BUS_NUMBER = 1 # P1-03 = SDA1, P1-05 = SCL1
smBus1 = smbus.SMBus(I2C_BUS_NUMBER) # global variable, cannot be set by a function
# * Register base addresses *
MCP23017BaseAddress1 = 0x22 # LED, button
MCP23008BaseAddress1 = 0x24 # stepping motors
MCP23008BaseAddress2 = 0x25 # keypad
MCP23008BaseAddress3 = 0x26 # LCD1602
# * i2cdetect/i2cset commands *
# To detect I2C device base addresses
# sudo i2cdetect -y 1
# * To toggle GPIO pin *
# !/bin/bash
# i2cset -y 1 0x20 0x00 0x00
# count=0
# while [ $count -lt 10 ];
# do
# i2cset -y 1 0x20 0x0a 0x00
# sleep 0.5
# i2cset -y 1 0x20 0x0a 0xff
# sleep 0.5
# let count++
# done
# * Port type *
PortA = 0
PortB = 1
# * Data constant bytes *
AllOutput = 0x00
AllHigh = 0xff
AllLow = 0x00
AlternateHighLow = 0xaa
AlternateLowHigh = 0x55
# * Direction setting bytes *
HalfHighHalfLow = 0xf0
HalfLowHalfHigh = 0x0f
Nibble1HighNibble2Low = 0xf0
Nibble1LowNibble2High = 0x0f
HighNibbleInputLowNibbleOutput = 0xf0
# * MCP23008/MCP23017 register address offsets *
InputOutputDirection = 0
InputPolarity = 1
InterruptOnChangeEnable = 2
InterruptOnChangeDefaultValue = 3
InterruptOnChangeMode = 4
Configuration = 5
PushPullOpenDrain = 6
InterruptFlag = 7
InterruptCapture = 8
PortStatus = 9
OutputLatch = 10
# * MCP23008/MCP23017 Band0/Band1 register address offset arrays *
RegisterAddressOffsetArray0 = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a]
RegisterAddressOffsetArray1 = [0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x11, 0x13, 0x15, 0x17, 0x19,
0x01, 0x03, 0x05, 0x07, 0x09, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a]
# * Setup input/output ports *
def SetupMCP23008PortAllOutput(registerBaseAddress):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
def SetupMCP23017BothPortAllOutput(registerBaseAddress):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortB, AllOutput)
# * Read/write registers *
def WriteDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType, dataByte):
if (portType == PortA) | (portType == PortA):
addressOffset = registerAddressArray[dataRegisterIndex]
if (portType == PortB):
addressOffset = registerAddressArray[dataRegisterIndex + 11]
smBus1.write_byte_data(registerBaseAddress, addressOffset, dataByte)
def ReadDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType):
if (portType == PortA):
addressOffset = registerAddressArray[dataRegisterIndex]
if (portType == PortB):
addressOffset = registerAddressArray[dataRegisterIndex + 11]
dataByte = smBus1.read_byte_data(registerBaseAddress, addressOffset)
return dataByte
def ReadUpperDataNibble(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType):
dataByte = ReadDataByte(registerBaseAddress, registerAddressArray, dataRegisterIndex, portType)
upperDataNibble = dataByte >> 4
return upperDataNibble
# * Config interrupts *
def EnableInterruptOnChangeHighNibble(registerBaseAddress):
EnableInterruptHighNibble = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeEnable, PortA, EnableInterruptHighNibble)
def DisableInterruptOnChangeHighNibble(registerBaseAddress):
DisableInterruptHighNibble = 0x00
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeEnable, PortA, DisableInterruptHighNibble)
def SetInterruptOnChangeDefaultHighNibble(registerBaseAddress):
DefaultValueByte = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeDefaultValue, PortA, DefaultValueByte)
def SetInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress):
InterruptOnChangeDefaultValueHighNibble = 0xf0 # GP4~7 change from default value will cause interrupt
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeMode, 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, RegisterAddressOffsetArray0, 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, RegisterAddressOffsetArray0, PushPullOpenDrain, PortA, OpenDrain)
# * Poll interrupts *
def ReadInterruptFlagHighNibble(registerBaseAddress):
interruptFlagByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptFlag, PortA)
interruptFlagNibble = interruptFlagByte >> 4
return interruptFlagNibble
def ReadInterruptCaptureHighNibble(registerBaseAddress):
interruptCaptureByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptCapture, PortA)
interruptCaptureNibble = interruptCaptureByte >> 4
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 !!!
sleep(2)
# * Test port toggling, poll interrupts *
def ToggleMCP23008GP(registerBaseAddress, toggleTime, toggleCount):
SetupMCP23008PortAllOutput(registerBaseAddress)
for i in range(toggleCount):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllHigh)
sleep(toggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllLow)
sleep(toggleTime)
def ToggleMCP23017GP(registerBaseAddress, toggleTime, toggleCount):
SetupMCP23017BothPortAllOutput(registerBaseAddress)
for i in range(toggleCount):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllHigh)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortB, AllHigh)
sleep(toggleTime)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, AllLow)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortB, AllLow)
sleep(toggleTime)
def TestToggleMCP23008GP():
ToggleTime = 0.5
ToggleCount = 4
ToggleMCP23008GP(MCP23008BaseAddress1, ToggleTime, ToggleCount)
def TestToggleMCP23017GP():
ToggleTime = 0.5
ToggleCount = 4
ToggleMCP23008GP(MCP23017BaseAddress1, ToggleTime, ToggleCount)
def TestDetectInterrupt(count): # !!! NOT Tested !!!
RegisterBaseAddress = MCP23008BaseAddress2
SetupKeypadInterruptHighNibbleCompareDefaultValueOpenDrainOutput(RegisterBaseAddress)
for i in range(count):
DetectOneInterrupt(RegisterBaseAddress)
# 7. Unipolar Stepping Motor 28BYJ48/NPM-PF35/PX245 ***************************
# Unipolar Stepping Motor Switching Sequence
# 1. Wave sequence = 1 - 3 - 2 - 4 (A-, B-, A+, B+)
# 2. Full step sequence = 13 - 14 - 24 - 23 (A-B-, A-B+, A+B+, A+B-)
# 3. Half step sequence = 13 - 1 - 14 - 4 - 24 - 2 - 23 - 3
# 4. One step swing = 1 - 3 - 1 - 3 (A-, B-, A-, B-)
# Winding A-(1) A+(2) B-(3) B+(4) COM
# NPM PF35 Black Yellow Brown Orange Red
# 28BYJ48 Blue Pink Yellow Orange Red
# PX245 Black Green Blue Red 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, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
if NibbleType == LowNibble:
hexString1 = convert2PinToHex(1, 3)
hexString2 = convert2PinToHex(2, 4)
else:
hexString1 = convert2PinToHighNibble(1, 3)
hexString2 = convert2PinToHighNibble(2, 4)
for i in range(StepCount):
WriteDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, OutputLatch, PortA, hexString1)
sleep(StepTime)
WriteDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, OutputLatch, PortA, hexString2)
sleep(StepTime)
def WriteMotorWindingFullStepSequence13232414(RegisterBaseAddress, NibbleType, StepCount, StepTime): #move motor using 13-23-24-14 sequence
# Set port all output
WriteDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, InputOutputDirection, PortA, AllOutput)
if NibbleType == LowNibble:
motorWindingActivationPatternArray = (0x05, 0x06, 0x0a, 0x09)
else:
motorWindingActivationPatternArray = (0x50, 0x60, 0xa0, 0x90)
for i in range(StepCount):
for pattern in motorWindingActivationPatternArray:
WriteDataByte(MCP23008BaseAddress1, RegisterAddressOffsetArray0, OutputLatch, PortA, pattern)
sleep(StepTime)
def TestConvert1PinToHex(): # test convert 1 high pin to hex
print "*** Testing 1 pin number decimal 0 ~ 7 converted to hexdecimal 0x01 ~ 0x80"
for d in range(8):
print hex(convert1PinToHex(d))
def TestConvert2PinToHex(p1, p2): # test convert 2 high pins to hex
print "*** Testing 2 pin numbers decimal 0 ~ 7 converted to hexdecimal"
print "Pin 1 = ", p1, "Pin 2 = ", p2
print "Hex = ", hex(convert2PinToHex(p1, p2))
def TestConvert2PinToHighNibble(p1, p2): # test convert 2 of 8 high pins to high nibble
print "*** Testing 2 pin numbers decimal 0 ~ 7 converted to high nibble"
print "Pin 1 = ", p1, "Pin 2 = ", p2
print "HighNibble = ", hex(convert2PinToHighNibble(p1, p2))
def MoveTwoMotors(RegisterBaseAddress):
OneBeep()
WriteMotorWindingWaveSequence1324(MCP23008BaseAddress1, LowNibble, TwentyTimes, FiftyMilliSeconds)
OneBeep()
WriteMotorWindingWaveSequence1324(MCP23008BaseAddress1, HighNibble, TwentyTimes, FiftyMilliSeconds)
# OneBeep()
# WriteMotorWindingFullStepSequence13232414(MCP23008BaseAddress1, LowNibble, TwentyTimes, FiftyMilliSeconds)
# OneBeep()
# WriteMotorWindingFullStepSequence13232414(MCP23008BaseAddress1, HighNibble, TwentyTimes, FiftyMilliSeconds)
def TestMotor():
MotorRegisterBaseAddress = MCP23008BaseAddress1
MoveTwoMotors(MotorRegisterBaseAddress)
# 8. Decimal keypad ***********************************************************
# * Function descriptions *
# SetupKeypad(registerBaseAddress)
# Assign GP0~3 as output (Col0~2, Col3 n.c), GP4~7 input (Row0~3)
# WriteAllColumnsLow(registerBaseAddress)
# Set all column outputs (GP0~2 actually, GP3 dummy)
# LoopUntilGpioPortHighNibbleChange(registerBaseAddress)
# Loop until GPIO register's GP4~7 not all High (some key pressed)
# LoopUntilInterruptCaptureHighNibbleChange(registerBaseAddress)
# Loop until INTCAP register's ICP4~7 not all High (some key pressed)
# Keypad scanning procedure version 1.0
# 1. Set 3 column ports GP0, GP1, GP2 as output (GP3 don't care)
# 2. Set 4 row ports GP4, GP5, GP6, GP7 as input
# 3. Write Low to all column ports
# 4. Wait until any key pressed (pooling or interrupt)
# 5. Find rowNumber and column number
# 6. Calculate key number
# * keypad base address and smBus setting *
KeypadRegisterBaseAddress = MCP23008BaseAddress2
KeypadSmBus = smBus1
PollGpioRegister = 0
PollKeypadInterruptPin = 1
# * Set up keypad matrix GPIO and interrupts *
def SetupKeypad(registerBaseAddress):
SetupKeypadGPIO(registerBaseAddress)
SetupKeypadInterrupt(registerBaseAddress)
ClearKeypadInterrupt(registerBaseAddress)
def SetupKeypadGPIO(registerBaseAddress):
UpperNibbleInputLowerNibbleOutput = 0xf0 # (GP4~7, Row0~3) = input, lower nibble (GP0~3, Column0~2, 3 = no coonect) = output
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InputOutputDirection, PortA, UpperNibbleInputLowerNibbleOutput)
WriteAllColumnsLow(registerBaseAddress)
def SetupKeypadInterrupt(registerBaseAddress):
EnableInterruptOnChangeHighNibble(registerBaseAddress) # Enable interrupt on upper nibble (GP4~7)
SetInterruptOnChangeDefaultHighNibble(registerBaseAddress) # Interrupt default values = all high (GP4~7 0b1111)
SetInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress) # select compare default value interrutpt
SetInterruptOutputOpenDrain(registerBaseAddress) # set interrupt output (INT) open drain
def EnableInterruptOnChangeHighNibble(registerBaseAddress):
EnableInterruptHighNibble = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeEnable, PortA, EnableInterruptHighNibble)
def SetInterruptOnChangeDefaultHighNibble(registerBaseAddress):
DefaultValueByte = 0xf0
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeDefaultValue, PortA, DefaultValueByte)
def SetInterruptOnChangeCompareDefaultHighNibble(registerBaseAddress):
InterruptOnChangeDefaultValueHighNibble = 0xf0 # GP4~7 change from default value will cause interrupt
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, InterruptOnChangeMode, 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, RegisterAddressOffsetArray0, 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, RegisterAddressOffsetArray0, PushPullOpenDrain, PortA, OpenDrain)
# * Clear and poll interrupts *
def ClearKeypadInterrupt(registerBaseAddress):
WriteAllColumnsLow(registerBaseAddress)
sleep(0.5)
dummyRead = ReadInterruptCaptureHighNibble(registerBaseAddress)
def ReadKeypadInterruptPin(interruptPin):
interruptStatus = readInputPin(interruptPin)
return interruptStatus
# * Write columns *
def WriteColumns(registerBaseAddress, columnDataNibble):
columnDataByte = columnDataNibble | 0x00
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, columnDataByte)
def WriteAllColumnsLow(registerBaseAddress):
AllColumnsLowNibble = 0x0
WriteColumns(registerBaseAddress, AllColumnsLowNibble)
def WriteColumn0Low(registerBaseAddress):
Column0LowNibble = 0xe
WriteColumns(registerBaseAddress, Column0LowNibble)
def WriteColumn1Low(registerBaseAddress):
Column1LowNibble = 0xd
WriteColumns(registerBaseAddress, Column1LowNibble)
def WriteColumn2Low(registerBaseAddress):
Column2LowNibble = 0xb
WriteColumns(registerBaseAddress, Column2LowNibble)
# * Read rows *
def GetRowDataByte(registerBaseAddress):
rowDataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
return rowDataByte
def GetRowDataNibble(registerBaseAddress):
rowDataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
rowDataNibble = rowDataByte >> 4
return rowDataNibble
# * Get row number, column number, and key number *
def GetRowNumber(registerBaseAddress):
rowDataByte = ReadDataByte(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
rowDataNibble = rowDataByte >> 4
if rowDataNibble == 0b1110:
rowNumber = 0
return rowNumber
elif rowDataNibble == 0b1101:
rowNumber = 1
return rowNumber
elif rowDataNibble == 0b1011:
rowNumber = 2
return rowNumber
elif rowDataNibble == 0b0111:
rowNumber = 3
return rowNumber
else:
rowNumber = 99
return rowNumber
def GetColumnNumber(registerBaseAddress):
RowsAllHigh = 0xf
WriteColumn0Low(registerBaseAddress)
rowDataNibble = ReadUpperDataNibble(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
if rowDataNibble != RowsAllHigh:
columnNumber = 0
return columnNumber
WriteColumn1Low(registerBaseAddress)
rowDataNibble = ReadUpperDataNibble(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
if rowDataNibble != RowsAllHigh:
columnNumber = 1
return columnNumber
WriteColumn2Low(registerBaseAddress)
rowDataNibble = ReadUpperDataNibble(registerBaseAddress, RegisterAddressOffsetArray0, PortStatus, PortA)
if rowDataNibble != RowsAllHigh:
columnNumber = 2
return columnNumber
def GetKeyNumber(rowNumber, columnNumber):
# print "Row Number = ", rowNumber
# print "Column Number = ", columnNumber
keyNumber = (rowNumber * 3) + (columnNumber + 1)
return keyNumber
# * Get one key and a sequence of keys *
def GetKey(registerBaseAddress, pollType):
PollGpioRegister = 0
PollKeypadInterruptPin = 1
if (pollType == PollGpioRegister):
# print "Polling GpioRegister"
LoopUntilGpioPortHighNibbleChange(registerBaseAddress)
elif (pollType == PollKeypadInterruptPin):
# print "Polling Interrupt Pin"
LoopUntilKeypadInterruptPinLow(registerBaseAddress, KeypadInterruptPin)
rowNumber = GetRowNumber(registerBaseAddress)
columnNumber = GetColumnNumber(registerBaseAddress)
keyNumber = GetKeyNumber(rowNumber, columnNumber)
return keyNumber
def GetKeyString(registerBaseAddress, pollType, count):
for i in range (count):
OneBeep()
keyNumber = GetKey(registerBaseAddress, pollType)
print "Key", i + 1, " = ", keyNumber
# * Loop until row data changes *
def LoopUntilGpioPortHighNibbleChange(registerBaseAddress):
WriteAllColumnsLow(registerBaseAddress)
NoKeyPressedNibble = 0xf
rowDataNibble = NoKeyPressedNibble
while (rowDataNibble == NoKeyPressedNibble):
rowDataNibble = GetRowDataNibble(registerBaseAddress)
sleep(0.05) # debouncing time 50mS
# * Loop until interrupt key low *
def LoopUntilKeypadInterruptPinLow(registerBaseAddress, interruptPin):
ClearKeypadInterrupt(registerBaseAddress)
interruptPinState = readInputPin(interruptPin)
#print "interruptPinState = ", interruptPinState
while (interruptPinState == True):
interruptPinState = readInputPin(interruptPin)
#print "interruptPinState = ", interruptPinState
#sleep(1)
#print "interruptPinState = ", interruptPinState
sleep(0.05) # debouncing time 50mS
# * Test keypad *
def TestKeypad(registerBaseAddress, pollType, count):
SetupKeypad(registerBaseAddress)
if (pollType == PollKeypadInterruptPin):
SetupKeypadInterrupt(registerBaseAddress)
ClearKeypadInterrupt(registerBaseAddress)
print "*** Start testing keypad. ***"
print "Press keypad ", count, "times."
GetKeyString(registerBaseAddress, pollType, count)
ClearKeypadInterrupt(registerBaseAddress)
print "*** Stop testing keypad. ***\n"
def TestPollingKeypad():
TestKeypad(KeypadRegisterBaseAddress, PollGpioRegister, count = 4)
def TestInterruptKeypad():
TestKeypad(KeypadRegisterBaseAddress, PollKeypadInterruptPin, count = 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
# * RPi/MCP23008 Python functions *
def LcdGpioSetup(registerBaseAddress):
SetupMCP23008PortAllOutput(registerBaseAddress)
def LcdConfiguration(registerBaseAddress):
dataControlByte = AllZeroDataByte
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
LcdDisableWrite(registerBaseAddress, dataControlByte)
sleep(PowerOnResetDelay)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, VeryLongOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte03 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, EightBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte04 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, FourBitInstructionMode, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte05 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte06 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, TwoLineFiveTimesEightDot2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte07 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte08 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, DisplayOnCursorOnCursorBlinkOff2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte09 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, ClearDisplay1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte10 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, ClearDisplay2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte11 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte12 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, CursorIncrementDisplayNoShift2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte13 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, CursorHome1, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte14 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, CursorHome2, InstructionRegister, LongOperationDelay)
# PrintEightBitPattern("dataControlByte15 = ", dataControlByte)
return dataControlByte
def LcdSelectDataRegister(registerBaseAddress, dataByte):
dataByte = dataByte | SelectDataRegisterMask
LcdWriteDataByte(registerBaseAddress, dataByte)
return dataByte
def LcdSelectInstructionRegister(registerBaseAddress, dataByte):
dataByte = dataByte & SelectInstructionRegisterMask
LcdWriteDataByte(registerBaseAddress, dataByte)
return dataByte
def LcdEnableWrite(registerBaseAddress, dataByte):
dataByte = dataByte | EnableWriteMask
LcdWriteDataByte(registerBaseAddress, dataByte)
return dataByte
def LcdDisableWrite(registerBaseAddress, dataByte):
dataByte = dataByte & DisableWriteMask
LcdWriteDataByte(registerBaseAddress, dataByte)
return dataByte
def LcdWritePulse(registerBaseAddress, dataByte):
LcdEnableWrite(registerBaseAddress, dataByte)
sleep(WritePulseLength)
LcdDisableWrite(registerBaseAddress, dataByte)
return dataByte
def LcdWriteDataByte(registerBaseAddress, dataByte):
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, OutputLatch, PortA, dataByte)
return dataByte
def LcdWriteDataNibble(registerBaseAddress, dataByte, dataNibble, registerType, operationDelay):
dataNibble = dataNibble << 2
dataByte = dataByte & 0b11000011
dataByte = dataByte | dataNibble
if (registerType == InstructionRegister):
dataByte = LcdSelectInstructionRegister(registerBaseAddress, dataByte)
elif (registerType == DataRegister):
dataByte = LcdSelectDataRegister(registerBaseAddress, dataByte)
LcdDisableWrite(registerBaseAddress, dataByte)
dataByte = LcdWriteDataByte(registerBaseAddress, dataByte)
LcdWritePulse(registerBaseAddress, dataByte)
sleep(operationDelay)
return dataByte
def LcdWriteCharFourBitMode(registerBaseAddress, dataControlByte, asciiChar, registerType):
charUpperNibble = ord(asciiChar) >> 4
charLowerNibble = ord(asciiChar) & 0x0f
LcdWriteCharTwoNibbles(registerBaseAddress, dataControlByte, charUpperNibble, charLowerNibble, registerType)
return dataControlByte
def LcdWriteDataByteFourBitMode(registerBaseAddress, dataControlByte, dataByte, registerType):
upperNibble = dataByte >> 4
lowerNibble = dataByte & 0x0f
LcdWriteCharTwoNibbles(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType)
return dataControlByte
def LcdWriteCharTwoNibbles(registerBaseAddress, dataControlByte, upperNibble, lowerNibble, registerType):
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, upperNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte01 = ", dataControlByte)
dataControlByte = LcdWriteDataNibble(registerBaseAddress, dataControlByte, lowerNibble, registerType, ShortOperationDelay)
# PrintEightBitPattern("dataControlByte02 = ", dataControlByte)
return dataControlByte
def LcdWriteCharString(registerBaseAddress, dataControlByte, string):
for asciiChar in (string):
LcdWriteCharFourBitMode(registerBaseAddress, dataControlByte, asciiChar, DataRegister)
return dataControlByte
def LcdMoveCursor(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
LcdWriteDataByteFourBitMode(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 functions *
def TestLcd(registerBaseAddress):
LcdGpioSetup(registerBaseAddress)
dataControlByte = LcdConfiguration(registerBaseAddress)
dataControlByte = LcdMoveCursor(registerBaseAddress, dataControlByte, 1, 2)
dataControlByte = LcdWriteCharString(registerBaseAddress, dataControlByte, "Raspberry Pi")
dataControlByte = LcdMoveCursor(registerBaseAddress, dataControlByte, 2, 1)
dataControlByte = LcdWriteCharString(registerBaseAddress, dataControlByte, "2013-01-25 v1141")
# * Demultiplexer *************************************************************
DemuxRegisterBaseAddress = KeypadRegisterBaseAddress
def DemuxGpioSetup(registerBaseAddress):
UpperNibbleInputLowerNibbleOutput = 0xf0 # Input (GP4~7, Row0~3), Output (GP0~3, Column0~2, 3 reserved)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, 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, RegisterAddressOffsetArray0, OutputLatch, PortA, controlDataByte)
controlDataByte = DemuxAddressLatch(controlDataByte, Enable)
PrintEightBitPattern("demuxDataByte = ", controlDataByte)
WriteDataByte(registerBaseAddress, RegisterAddressOffsetArray0, 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 11111111")
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row2, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "2013-01-25 v1151")
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 22222222")
dataControlByte = LcdMoveCursor(lcdRegisterBaseAddress, dataControlByte, Row2, Column1)
dataControlByte = LcdWriteCharString(lcdRegisterBaseAddress, dataControlByte, "2013-01-25 v1151")
sleep(2)
# 11. Main test functions *****************************************************
StartProgram("*** Test Demultiplexer v110 TL Fong 2013jan22hkt2501 ***")
#TestBuzzer() # beep buzzer 4 times
#TestLED() # blink LED 8 tmes
#TestButtonEchoBuzzer() # echo buton with buzzer 10 times
#TestButtonEchoLED() # echo button with LED 10 times
# TestToggleMCP23017GP() # toggle MCP23017 output ports
# TestToggleMCP23008GP() # toggle MCP23008 output port
# TestMotor() # move two stepping motors
# TestPollingKeypad() # read 4 keys by polling IO Expander GPIO port of rows
# TestInterruptKeypad() # read 4 keys by polling IO Expander INT pin
# ToggleMCP23008GP(MCP23008BaseAddress1, toggleTime = 0.25, toggleCount = 4)
# ToggleMCP23008GP(MCP23008BaseAddress3, toggleTime = 2.0, toggleCount = 20)
# TestLcd(LcdRegisterBaseAddress)
# TestDemux(DemuxRegisterBaseAddress, 4)
TestDemuxLcd(DemuxRegisterBaseAddress, LcdRegisterBaseAddress, channelNumber1 = 0, channelNumber2 = 1)
EndProgram()
# *****************************************************************************
# End of Program
# *****************************************************************************
.END
No comments:
Post a Comment