Beginner’s Guide to the PI LCD Part 4: Graphics , W8BH 1) INTRODUCTION In the first three parts of this series, we learned how to display text and simple graphics on the LCD board (available from mypishop.com). It’s time to kick it up a notch, and create a suite of useful graphics functions. We’ll even create a large-digit clock. You may have purchased either a 16x2 or a 20x4 display with your kit. In this write-up I’ll be using the 20x4 display.
def HorizBar(row,startCol,length): GotoXY(row,startCol) for count in range(length): SendByte(0xFF,True) #go to starting position #display bar of desired length This simple code works, and is surprisingly useful. You aren’t limited to small ranges: just scale the desired range to 0-15 by the appropriate conversion factor. But your graph will always look a little coarse and chunky, since there are a limited number of possible data values/lengths.
by a combination of ‘full characters’ which contain 5 bars each, followed by a terminal character containing less than 5 bars. For example, a bar graph of length 27 will be 5 full characters (5*5=25), followed by a character containing the last 2 bars: Bar of 27 units = 5 Filled Characters + 1 Partially Filled Character We can calculate the number of full characters by integer division: length/5. And the number of bars in the final, partially filled character is just the remainder: length % 5.
time.sleep(ANIMATIONDELAY) If the new length is greater than the old length, we increment until the new length is reached. Similarly, if the new length is less than the old length, we decrement. Each time, wait a fraction of a second for the animation effect. Incrementing is incredibly simple: just add one bar and display it. The process of setting the cursor position and displaying a character comes up several times, so I refactored it into a little helper-function called ShowBars.
) VERTICAL BAR GRAPHS You can create vertical bar graphs in exactly the same way we did the horizontal ones: - Create a series of vertical bar symbols - Write routines for drawing the bar, breaking it down into full characters with a final, partially filled character - Write an animation routine, calling on IncrementVBar and DecrementVBar See the script listing at the end for all of the details. The code is almost exactly the same.
[ 0x00, 0x06, 0x01, 0x06, 0x20, 0x06, 0x06, 0x05, 0x06, 0x02, 0x06, 0x03], #8 [ 0x00, 0x06, 0x01, 0x02, 0x04, 0x06, 0x20, 0x20, 0x06, 0x20, 0x20, 0x06] #9 ] 0x00 indicates the first symbol (a lower-right triangle), 0x01 indicates the second (a lowerleft triangle), and so on. 0x20 is a blank. The 12 symbols in each digit are ordered from top-left to lower-right.
) PYTHON SCRIPT for PI LCD, PART 4: ######################################################################## # # LCD4: Learning how to control an LCD module from Pi # # # # # See w8bh.net for more information. # ######################################################################## import time import RPi.
] verticalBars = [ [ 0x00, 0x00, 0x00, [ 0x00, 0x00, 0x00, [ 0x00, 0x00, 0x00, [ 0x00, 0x00, 0x00, [ 0x00, 0x00, 0x00, [ 0x00, 0x00, 0x1F, [ 0x00, 0x1F, 0x1F, [ 0x1F, 0x1F, 0x1F, ] 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F ], ], ], ], ], ], ], ], #1 #2 #3 #4 #5 #6 #7 #8 bar bars bars bars bars bars bars bars hor
#Check status of all four switches on the LCD board #Returns four boolean values as a tuple. val1 = not GPIO.input(SW1) val2 = not GPIO.input(SW2) val3 = not GPIO.input(SW3) val4 = not GPIO.input(SW4) return (val4,val1,val2,val3) def PulseEnableLine(): #Pulse the LCD Enable line; used for clocking in data GPIO.output(LCD_E, GPIO.HIGH) #pulse E high GPIO.output(LCD_E, GPIO.LOW) #return E low def SendNibble(data): #sends upper 4 bits GPIO.output(LCD_D4, GPIO.output(LCD_D5, GPIO.output(LCD_D6, GPIO.
def SendChar(ch): SendByte(ord(ch),True) def ShowMessage(string): #Send string of characters to display at current cursor position for character in string: SendChar(character) def GotoLine(row): #Moves cursor to the given row #Expects row values 0-1 for 16x2 display; 0-3 for 20x4 display addr = LINE[row] SendByte(SETCURSOR+addr) def GotoXY(row,col): #Moves cursor to the given row & column #Expects col values 0-19 and row values 0-3 for a 20x4 display addr = LINE[row] + col SendByte(SETCURSOR + addr) #######
LoadSymbolBlock(digits) posn = [0,3,7,10,14,17] ClearDisplay() ShowColon(6) ShowColon(13) for count in range(seconds): tStr = time.strftime("%I%M%S") for i in range(len(tStr)): value = int(tStr[i]) symbols = bigDigit[value] ShowBigDigit(symbols,posn[i]) time.sleep(1) ######################################################################## # # Basic HD44780 Test Routines # Code here is used in higher-level testing routines # ANIMATIONDELAY = 0.
# def UpdateCursor(count): WIDTH = 15 if count==0: GotoLine(0) elif count==WIDTH: GotoLine(1) elif count==WIDTH*2: GotoLine(2) elif count==WIDTH*3: GotoLine(3) def GetNextCharacter(code): #for a given CODE, returns the next displayable ASCII character #for example, calling with 'A' will return 'B' #removes nondisplayable characters in HD44780 character set if (code<0x20) or (code>=0xFF): code = 0x20 elif (code>=0x7F) and (code<0xA0): code = 0xA0 else: code += 1 return code def FillScreen(code,delay=0): #fil
LabelTest('Time') for count in range(numCycles): startTime = time.time() NumberTest(pause) elapsedTime = time.time()-startTime elapsedTime -= pause*10 print " elapsed time (sec): %.
if diff>0: IncrementHBar(row,startCol,oldLength) oldLength +=1 else: DecrementHBar(row,startCol,oldLength) oldLength -=1 time.sleep(ANIMATIONDELAY) def AnimatedHBarTest(numCycles=8): LoadSymbolBlock(horizontalBars) LabelTest('HBar') graph = [0,0,0,0] for count in range(numCycles): for row in range(4): length = random.
for count in range(numCycles): for step in range(15): for col in range(15): x = col+step VBar(sine[x%15],col) time.sleep(0.