I just got one of these LCDs today so I have a few tips, i.e. these things tripped me up! Noob answers probably but you all seem friendly
First, do the usual apt-get update etc. and make sure you have
.
from Gadgetoid's git has I think Gordon as tweaked the wiringPi on his site enough to break wiringPi-Python
The associated instructions are simple enough although I needed to move the compiled wiringPi into the wiringPi-Python directory.
Although no one mentioned it the device select / device address / SCE / whatever it is on your board needs to be jumpered to ground. You could set up an extra GPIO line I guess, maybe if you wanted two or three of these running (dunno how many lines we have left!)
BTW... we are
SPI via the GPIO lines on the RPi. Is this stuff easier or harder using the RPi's own SPI outputs?
Onto the fun times! I erm... couldn't be bothered to walk from one side of the room to the other where my RPi is plugged directly into my Internet router so I... um... hooked a web cam up to the RPi and used guvcview to watch the LCD from my main machine (running PuTTY + Xming.) Total abuse of technology
So I tried the new wiringPi code above and I'm still wondering what the "from grafix" is about otherwise it worked. Time for some mods! I extended the font definitions to do full ASCII (32 to 127) and added some convenience functions:
) - as this display is geared towards 6 rows by 14 columns I added this.
) - if the word(s) are under 14 characters, a quick and dirty centred message.
() - as an alternative to begin(0xBC) as I will forget that value by tomorrow.
) - overwrite ASCII code 127 with your own character.
() - shortcut to display_char(chr(127)) as I have no idea if this 127 is on my keyboard.
() - to get back the "undefined" box character.
() - I have this set to '£' but predefine this to your favourite currency.
) - load a standard (almost!) Windoze bitmap. Some slight caveats of course!
To keep it simple on the RPi you do need to help out a little. As the display is 84x48 that's a horrible width for a bitmap (needs to be on a byte boundary like 92.) Also the LCD memory is stored as vertical bytes, a bit like a dot matrix printer; left to right bands of vertical bytes. So, I suggest you create your 84x48 bitmap, save it as monochrome bitmap and then rotate it 90 degrees
to get a 48x84 portrait bitmap. I then fired up a hex editor to find the data offset (0x3E, YMMV) which is probably in the header somewhere anyway but I didn't get round to checking. Anyway, 48
on a byte boundary and the piccy is now almost stored like the LCD's memory. Two problems solved for the price of one
Well, it couldn't be that simple now we have to jump though the LSB to MSB swapping hoop
I thought about an algorithm to do this and felt that thinking by this time was a no-no. I copied over a code snippet from some 'C' website which just used a lookup table and formatted it for Python. Bada-bing!
) - simple XOR as I never looked up the LCD command for reverse display.
Code: Select all
#!/usr/bin/python
# -*- coding: utf-8 -*-
# using wiringPI GPIO method
import wiringpi
import time
import sys
ROWS = 6
COLUMNS = 14
ON = 1
OFF = 0
#gpio's :
SCLK = 24 # gpio pin 18
DIN = 23 # gpio pin 16
DC = 22 # gpio pin 15
RST = 18 # gpio pin 12
LED = 17 # gpio pin 11
font =[
0x00, 0x00, 0x00, 0x00, 0x00, # 20
0x00, 0x00, 0x5f, 0x00, 0x00, # 21 !
0x00, 0x07, 0x00, 0x07, 0x00, # 22 "
0x14, 0x7f, 0x14, 0x7f, 0x14, # 23 #
0x24, 0x2a, 0x7f, 0x2a, 0x12, # 24 $
0x23, 0x13, 0x08, 0x64, 0x62, # 25 %
0x36, 0x49, 0x55, 0x22, 0x50, # 26 &
0x00, 0x05, 0x03, 0x00, 0x00, # 27 '
0x00, 0x1c, 0x22, 0x41, 0x00, # 28 (
0x00, 0x41, 0x22, 0x1c, 0x00, # 29 )
0x14, 0x08, 0x3e, 0x08, 0x14, # 2a *
0x08, 0x08, 0x3e, 0x08, 0x08, # 2b +
0x00, 0x50, 0x30, 0x00, 0x00, # 2c ,
0x08, 0x08, 0x08, 0x08, 0x08, # 2d -
0x00, 0x60, 0x60, 0x00, 0x00, # 2e .
0x20, 0x10, 0x08, 0x04, 0x02, # 2f /
0x3e, 0x51, 0x49, 0x45, 0x3e, # 30 0
0x00, 0x42, 0x7f, 0x40, 0x00, # 31 1
0x42, 0x61, 0x51, 0x49, 0x46, # 32 2
0x21, 0x41, 0x45, 0x4b, 0x31, # 33 3
0x18, 0x14, 0x12, 0x7f, 0x10, # 34 4
0x27, 0x45, 0x45, 0x45, 0x39, # 35 5
0x3c, 0x4a, 0x49, 0x49, 0x30, # 36 6
0x01, 0x71, 0x09, 0x05, 0x03, # 37 7
0x36, 0x49, 0x49, 0x49, 0x36, # 38 8
0x06, 0x49, 0x49, 0x29, 0x1e, # 39 9
0x00, 0x36, 0x36, 0x00, 0x00, # 3a :
0x00, 0x56, 0x36, 0x00, 0x00, # 3b ;
0x08, 0x14, 0x22, 0x41, 0x00, # 3c <
0x14, 0x14, 0x14, 0x14, 0x14, # 3d =
0x00, 0x41, 0x22, 0x14, 0x08, # 3e >
0x02, 0x01, 0x51, 0x09, 0x06, # 3f ?
0x32, 0x49, 0x79, 0x41, 0x3e, # 40 @
0x7e, 0x11, 0x11, 0x11, 0x7e, # 41 A
0x7f, 0x49, 0x49, 0x49, 0x36, # 42 B
0x3e, 0x41, 0x41, 0x41, 0x22, # 43 C
0x7f, 0x41, 0x41, 0x22, 0x1c, # 44 D
0x7f, 0x49, 0x49, 0x49, 0x41, # 45 E
0x7f, 0x09, 0x09, 0x09, 0x01, # 46 F
0x3e, 0x41, 0x49, 0x49, 0x7a, # 47 G
0x7f, 0x08, 0x08, 0x08, 0x7f, # 48 H
0x00, 0x41, 0x7f, 0x41, 0x00, # 49 I
0x20, 0x40, 0x41, 0x3f, 0x01, # 4a J
0x7f, 0x08, 0x14, 0x22, 0x41, # 4b K
0x7f, 0x40, 0x40, 0x40, 0x40, # 4c L
0x7f, 0x02, 0x0c, 0x02, 0x7f, # 4d M
0x7f, 0x04, 0x08, 0x10, 0x7f, # 4e N
0x3e, 0x41, 0x41, 0x41, 0x3e, # 4f O
0x7f, 0x09, 0x09, 0x09, 0x06, # 50 P
0x3e, 0x41, 0x51, 0x21, 0x5e, # 51 Q
0x7f, 0x09, 0x19, 0x29, 0x46, # 52 R
0x46, 0x49, 0x49, 0x49, 0x31, # 53 S
0x01, 0x01, 0x7f, 0x01, 0x01, # 54 T
0x3f, 0x40, 0x40, 0x40, 0x3f, # 55 U
0x1f, 0x20, 0x40, 0x20, 0x1f, # 56 V
0x3f, 0x40, 0x38, 0x40, 0x3f, # 57 W
0x63, 0x14, 0x08, 0x14, 0x63, # 58 X
0x07, 0x08, 0x70, 0x08, 0x07, # 59 Y
0x61, 0x51, 0x49, 0x45, 0x43, # 5a Z
0x00, 0x7f, 0x41, 0x41, 0x00, # 5b [
0x02, 0x04, 0x08, 0x10, 0x20, # 5c \
0x00, 0x41, 0x41, 0x7f, 0x00, # 5d ]
0x04, 0x02, 0x01, 0x02, 0x04, # 5e ^
0x40, 0x40, 0x40, 0x40, 0x40, # 5f _
0x00, 0x01, 0x02, 0x04, 0x00, # 60 `
0x20, 0x54, 0x54, 0x54, 0x78, # 61 a
0x7f, 0x48, 0x44, 0x44, 0x38, # 62 b
0x38, 0x44, 0x44, 0x44, 0x20, # 63 c
0x38, 0x44, 0x44, 0x48, 0x7f, # 64 d
0x38, 0x54, 0x54, 0x54, 0x18, # 65 e
0x08, 0x7e, 0x09, 0x01, 0x02, # 66 f
0x0c, 0x52, 0x52, 0x52, 0x3e, # 67 g
0x7f, 0x08, 0x04, 0x04, 0x78, # 68 h
0x00, 0x44, 0x7d, 0x40, 0x00, # 69 i
0x20, 0x40, 0x44, 0x3d, 0x00, # 6a j
0x7f, 0x10, 0x28, 0x44, 0x00, # 6b k
0x00, 0x41, 0x7f, 0x40, 0x00, # 6c l
0x7c, 0x04, 0x18, 0x04, 0x78, # 6d m
0x7c, 0x08, 0x04, 0x04, 0x78, # 6e n
0x38, 0x44, 0x44, 0x44, 0x38, # 6f o
0x7c, 0x14, 0x14, 0x14, 0x08, # 70 p
0x08, 0x14, 0x14, 0x18, 0x7c, # 71 q
0x7c, 0x08, 0x04, 0x04, 0x08, # 72 r
0x48, 0x54, 0x54, 0x54, 0x20, # 73 s
0x04, 0x3f, 0x44, 0x40, 0x20, # 74 t
0x3c, 0x40, 0x40, 0x20, 0x7c, # 75 u
0x1c, 0x20, 0x40, 0x20, 0x1c, # 76 v
0x3c, 0x40, 0x30, 0x40, 0x3c, # 77 w
0x44, 0x28, 0x10, 0x28, 0x44, # 78 x
0x0c, 0x50, 0x50, 0x50, 0x3c, # 79 y
0x44, 0x64, 0x54, 0x4c, 0x44, # 7a z
0x00, 0x08, 0x36, 0x41, 0x00, # 7b {
0x00, 0x00, 0x7f, 0x00, 0x00, # 7c |
0x00, 0x41, 0x36, 0x08, 0x00, # 7d }
0x10, 0x08, 0x08, 0x10, 0x08, # 7e ~
0x00, 0x7E, 0x42, 0x42, 0x7E, # 7f CUSTOM
]
bitreverse =[
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
]
def main():
print ("LCD Display Test: ASCII 32 to 116")
start = time.time()
init()
led(1)
for i in range(32,116):
display_char(chr(i))
finish = time.time()
print ("Init, LED on, 84 chars, total time = ", finish - start)
print
def init():
begin(0xbc)
def load_bitmap(file):
gotoxy(0,0)
f = open(file,'r')
for x in range(6):
for y in range(84):
f.seek(0x3e + y*8 + x)
b = ord(f.read(1))
rev = bitreverse[b]
lcd_data(rev)
f.close()
def load_bitmap_reverse(file):
gotoxy(0,0)
f = open(file,'r')
for x in range(6):
for y in range(84):
f.seek(0x3e + y*8 + x)
b = ord(f.read(1))
rev = bitreverse[b]
rev = rev ^ 0xFF
lcd_data(rev)
f.close()
def show_custom():
display_char(chr(127))
def define_custom(b0,b1,b2,b3,b4):
font[475] = b0
font[476] = b1
font[477] = b2
font[478] = b3
font[479] = b4
def restore_custom():
font[475] = 0x00
font[476] = 0x7E
font[477] = 0x42
font[478] = 0x42
font[479] = 0x7E
def alt_custom():
font[475] = 0x00
font[476] = 0x50
font[477] = 0x3C
font[478] = 0x52
font[479] = 0x44
def pi_custom():
font[475] = 0x19
font[476] = 0x25
font[477] = 0x5A
font[478] = 0x25
font[479] = 0x19
def centre_word(r, word):
l = len(word)
c = (COLUMNS - l) / 2
if c <= 0:
c = 0
gotorc(r,c)
text(word)
def gotorc(r,c):
lcd_cmd(c*6+128)
lcd_cmd(r+64)
def gotoxy(x,y):
lcd_cmd(x+128)
lcd_cmd(y+64)
def text(words):
for i in range(len(words)):
display_char(words[i])
def display_char(char):
index=(ord(char)-32)*5
if ord(char) >=32 and ord(char) <=127:
for i in range(5):
lcd_data(font[index+i])
lcd_data(0) # space inbetween characters
def cls():
gotoxy(0,0)
for i in range(84):
for j in range(6):
lcd_data(0)
def setup():
# set pin directions
wiringpi.wiringPiSetup()
wiringpi.wiringPiGpioMode(ON)
# GPIO.setmode(GPIO.BCM)
wiringpi.pinMode(DIN, ON)
wiringpi.pinMode(SCLK, ON)
wiringpi.pinMode(DC, ON)
wiringpi.pinMode(RST, ON)
wiringpi.pinMode(LED, ON)
def begin(contrast):
setup()
# toggle RST low to reset
wiringpi.digitalWrite(RST, OFF)
wiringpi.digitalWrite(LED, OFF)
time.sleep(0.100)
wiringpi.digitalWrite(RST, ON)
lcd_cmd(0x21) # extended mode
lcd_cmd(0x14) # bias
lcd_cmd(contrast) # vop
lcd_cmd(0x20) # basic mode
lcd_cmd(0xc) # non-inverted display
cls()
def led(led_value):
wiringpi.digitalWrite(LED, led_value)
def SPI(c):
# data = DIN
# clock = SCLK
# MSB first
# value = c
for i in xrange(8):
wiringpi.digitalWrite(DIN,((c & (1 << (7-i))) > 0))
wiringpi.digitalWrite(SCLK, ON)
wiringpi.digitalWrite(SCLK, OFF)
def lcd_cmd(c):
wiringpi.digitalWrite(DC, OFF)
SPI(c)
def lcd_data(c):
wiringpi.digitalWrite(DC, ON)
SPI(c)
if __name__ == "__main__":
main()
Huh... I would attach the bitmap too but whatever I call it "The extension is not allowed" comes up