Code: Select all
sudo pip install spidev

Code: Select all
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# code improvements
# 9/10/12
######
# WGG - picked up from Raspberry Pi forums and modified with a heavy hand
# -- added spidev support
# -- testing with PIL
import time
import wiringpi
import spidev
from PIL import Image,ImageDraw,ImageFont
# White backlight
CONTRAST = 0xa4
# Blue backlight
#CONTRAST = 0xb4
ROWS = 6
COLUMNS = 14
PIXELS_PER_ROW = 6
ON = 1
OFF = 0
#gpio's :
DC = 3 # gpio pin 15 = wiringpi no. 3 (BCM 22)
RST = 0 # gpio pin 11 = wiringpi no. 0 (BCM 17)
LED = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18)
# SPI connection
SCE = 10 # gpio pin 24 = wiringpi no. 10 (CE0 BCM 8)
SCLK = 14 # gpio pin 23 = wiringpi no. 14 (SCLK BCM 11)
DIN = 12 # gpio pin 19 = wiringpi no. 12 (MOSI BCM 10)
CLSBUF=[0]*(ROWS * COLUMNS * PIXELS_PER_ROW)
FONT = {
' ': [0x00, 0x00, 0x00, 0x00, 0x00],
'!': [0x00, 0x00, 0x5f, 0x00, 0x00],
'"': [0x00, 0x07, 0x00, 0x07, 0x00],
'#': [0x14, 0x7f, 0x14, 0x7f, 0x14],
'$': [0x24, 0x2a, 0x7f, 0x2a, 0x12],
'%': [0x23, 0x13, 0x08, 0x64, 0x62],
'&': [0x36, 0x49, 0x55, 0x22, 0x50],
"'": [0x00, 0x05, 0x03, 0x00, 0x00],
'(': [0x00, 0x1c, 0x22, 0x41, 0x00],
')': [0x00, 0x41, 0x22, 0x1c, 0x00],
'*': [0x14, 0x08, 0x3e, 0x08, 0x14],
'+': [0x08, 0x08, 0x3e, 0x08, 0x08],
',': [0x00, 0x50, 0x30, 0x00, 0x00],
'-': [0x08, 0x08, 0x08, 0x08, 0x08],
'.': [0x00, 0x60, 0x60, 0x00, 0x00],
'/': [0x20, 0x10, 0x08, 0x04, 0x02],
'0': [0x3e, 0x51, 0x49, 0x45, 0x3e],
'1': [0x00, 0x42, 0x7f, 0x40, 0x00],
'2': [0x42, 0x61, 0x51, 0x49, 0x46],
'3': [0x21, 0x41, 0x45, 0x4b, 0x31],
'4': [0x18, 0x14, 0x12, 0x7f, 0x10],
'5': [0x27, 0x45, 0x45, 0x45, 0x39],
'6': [0x3c, 0x4a, 0x49, 0x49, 0x30],
'7': [0x01, 0x71, 0x09, 0x05, 0x03],
'8': [0x36, 0x49, 0x49, 0x49, 0x36],
'9': [0x06, 0x49, 0x49, 0x29, 0x1e],
':': [0x00, 0x36, 0x36, 0x00, 0x00],
';': [0x00, 0x56, 0x36, 0x00, 0x00],
'<': [0x08, 0x14, 0x22, 0x41, 0x00],
'=': [0x14, 0x14, 0x14, 0x14, 0x14],
'>': [0x00, 0x41, 0x22, 0x14, 0x08],
'?': [0x02, 0x01, 0x51, 0x09, 0x06],
'@': [0x32, 0x49, 0x79, 0x41, 0x3e],
'A': [0x7e, 0x11, 0x11, 0x11, 0x7e],
'B': [0x7f, 0x49, 0x49, 0x49, 0x36],
'C': [0x3e, 0x41, 0x41, 0x41, 0x22],
'D': [0x7f, 0x41, 0x41, 0x22, 0x1c],
'E': [0x7f, 0x49, 0x49, 0x49, 0x41],
'F': [0x7f, 0x09, 0x09, 0x09, 0x01],
'G': [0x3e, 0x41, 0x49, 0x49, 0x7a],
'H': [0x7f, 0x08, 0x08, 0x08, 0x7f],
'I': [0x00, 0x41, 0x7f, 0x41, 0x00],
'J': [0x20, 0x40, 0x41, 0x3f, 0x01],
'K': [0x7f, 0x08, 0x14, 0x22, 0x41],
'L': [0x7f, 0x40, 0x40, 0x40, 0x40],
'M': [0x7f, 0x02, 0x0c, 0x02, 0x7f],
'N': [0x7f, 0x04, 0x08, 0x10, 0x7f],
'O': [0x3e, 0x41, 0x41, 0x41, 0x3e],
'P': [0x7f, 0x09, 0x09, 0x09, 0x06],
'Q': [0x3e, 0x41, 0x51, 0x21, 0x5e],
'R': [0x7f, 0x09, 0x19, 0x29, 0x46],
'S': [0x46, 0x49, 0x49, 0x49, 0x31],
'T': [0x01, 0x01, 0x7f, 0x01, 0x01],
'U': [0x3f, 0x40, 0x40, 0x40, 0x3f],
'V': [0x1f, 0x20, 0x40, 0x20, 0x1f],
'W': [0x3f, 0x40, 0x38, 0x40, 0x3f],
'X': [0x63, 0x14, 0x08, 0x14, 0x63],
'Y': [0x07, 0x08, 0x70, 0x08, 0x07],
'Z': [0x61, 0x51, 0x49, 0x45, 0x43],
'[': [0x00, 0x7f, 0x41, 0x41, 0x00],
'\\': [0x02, 0x04, 0x08, 0x10, 0x20],
']': [0x00, 0x41, 0x41, 0x7f, 0x00],
'^': [0x04, 0x02, 0x01, 0x02, 0x04],
'_': [0x40, 0x40, 0x40, 0x40, 0x40],
'`': [0x00, 0x01, 0x02, 0x04, 0x00],
'a': [0x20, 0x54, 0x54, 0x54, 0x78],
'b': [0x7f, 0x48, 0x44, 0x44, 0x38],
'c': [0x38, 0x44, 0x44, 0x44, 0x20],
'd': [0x38, 0x44, 0x44, 0x48, 0x7f],
'e': [0x38, 0x54, 0x54, 0x54, 0x18],
'f': [0x08, 0x7e, 0x09, 0x01, 0x02],
'g': [0x0c, 0x52, 0x52, 0x52, 0x3e],
'h': [0x7f, 0x08, 0x04, 0x04, 0x78],
'i': [0x00, 0x44, 0x7d, 0x40, 0x00],
'j': [0x20, 0x40, 0x44, 0x3d, 0x00],
'k': [0x7f, 0x10, 0x28, 0x44, 0x00],
'l': [0x00, 0x41, 0x7f, 0x40, 0x00],
'm': [0x7c, 0x04, 0x18, 0x04, 0x78],
'n': [0x7c, 0x08, 0x04, 0x04, 0x78],
'o': [0x38, 0x44, 0x44, 0x44, 0x38],
'p': [0x7c, 0x14, 0x14, 0x14, 0x08],
'q': [0x08, 0x14, 0x14, 0x18, 0x7c],
'r': [0x7c, 0x08, 0x04, 0x04, 0x08],
's': [0x48, 0x54, 0x54, 0x54, 0x20],
't': [0x04, 0x3f, 0x44, 0x40, 0x20],
'u': [0x3c, 0x40, 0x40, 0x20, 0x7c],
'v': [0x1c, 0x20, 0x40, 0x20, 0x1c],
'w': [0x3c, 0x40, 0x30, 0x40, 0x3c],
'x': [0x44, 0x28, 0x10, 0x28, 0x44],
'y': [0x0c, 0x50, 0x50, 0x50, 0x3c],
'z': [0x44, 0x64, 0x54, 0x4c, 0x44],
'{': [0x00, 0x08, 0x36, 0x41, 0x00],
'|': [0x00, 0x00, 0x7f, 0x00, 0x00],
'}': [0x00, 0x41, 0x36, 0x08, 0x00],
'~': [0x10, 0x08, 0x08, 0x10, 0x08],
'\x7f': [0x00, 0x7e, 0x42, 0x42, 0x7e],
}
ORIGINAL_CUSTOM = FONT['\x7f']
def bit_reverse(value, width=8):
result = 0
for _ in xrange(width):
result = (result << 1) | (value & 1)
value >>= 1
return result
BITREVERSE = map(bit_reverse, xrange(256))
spi = spidev.SpiDev()
def setup():
# Set pin directions.
wiringpi.wiringPiSetup()
for pin in [DC, RST]:
wiringpi.pinMode(pin, ON)
wiringpi.pinMode(LED,2)
wiringpi.pwmWrite(LED,128)
spi.open(0,0)
spi.max_speed_hz=5000000
def lcd_cmd(value):
wiringpi.digitalWrite(DC, OFF)
spi.writebytes([value])
def lcd_data(value):
wiringpi.digitalWrite(DC, ON)
spi.writebytes([value])
def gotoxy(x, y):
wiringpi.digitalWrite(DC, OFF)
spi.writebytes([x+128,y+64])
def cls():
gotoxy(0, 0)
wiringpi.digitalWrite(DC, ON)
spi.writebytes(CLSBUF)
def begin(contrast):
setup()
# Toggle RST low to reset.
wiringpi.digitalWrite(RST, OFF)
wiringpi.digitalWrite(LED, ON)
time.sleep(0.100)
wiringpi.digitalWrite(RST, ON)
# Extended mode, bias, vop, basic mode, non-inverted display.
wiringpi.digitalWrite(DC, OFF)
spi.writebytes([0x21, 0x14, contrast, 0x20, 0x0c])
# cls()
def init():
begin(CONTRAST)
def led(led_value):
wiringpi.pwmWrite(LED,led_value)
def load_bitmap(filename, reverse=False):
mask = 0xff if reverse else 0x00
gotoxy(0, 0)
with open(filename, 'rb') as bitmap_file:
for x in xrange(6):
for y in xrange(84):
bitmap_file.seek(0x3e + y * 8 + x)
lcd_data(BITREVERSE[ord(bitmap_file.read(1))] ^ mask)
def show_custom(font=FONT):
display_char('\x7f', font)
def define_custom(values):
FONT['\x7f'] = values
def restore_custom():
define_custom(ORIGINAL_CUSTOM)
def alt_custom():
define_custom([0x00, 0x50, 0x3C, 0x52, 0x44])
def pi_custom():
define_custom([0x19, 0x25, 0x5A, 0x25, 0x19])
def display_char(char, font=FONT):
try:
wiringpi.digitalWrite(DC, ON)
spi.writebytes(font[char]+[0])
except KeyError:
pass # Ignore undefined characters.
def text(string, font=FONT):
for char in string:
display_char(char, font)
def gotorc(r, c):
lcd_cmd(c * 6 + 128)
lcd_cmd(r + 64)
def centre_word(r, word):
gotorc(r, max(0, (COLUMNS - len(word)) // 2))
text(word)
def put_image(im):
# Rotate and mirror the image
rim = im.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
# Change display to vertical write mode for graphics
wiringpi.digitalWrite(DC, OFF)
spi.writebytes([0x22])
# Start at upper left corner
gotoxy(0, 0)
# Put on display with reversed bit order
wiringpi.digitalWrite(DC, ON)
spi.writebytes( [ BITREVERSE[ord(x)] for x in list(rim.tostring()) ] )
# Switch back to horizontal write mode for text
wiringpi.digitalWrite(DC, OFF)
spi.writebytes([0x20])
def main():
start, end = 32, 116
print 'LCD Display Test: ASCII %d to %d' % (start, end)
# do not include init() in the timing tests
init()
while 1:
start_time = time.time()
cls()
led(768)
for i in xrange(start, end):
display_char(chr(i))
finish_time = time.time()
print 'Cls, LED on, %d chars, total time = %.3f' % (
end - start, finish_time - start_time
)
print
time.sleep(1)
# Test a custom character for 0x7f (supposed to be a bell)
# . . . - - - - -
# . . . - - X - -
# . . . - X X X -
# . . . - X - X -
# . . . X - - - X
# . . . X X X X X
# . . . - - X X -
# . . . - - - - -
define_custom([0x30,0x2c,0x66,0x6c,0x30])
cls()
text("\x7f \x7f \x7f \x7f \x7f \x7f \x7f ")
text(" Hello ")
text(" Raspberry Pi")
# Backlight PWM testing -- off -> 25% -> off
#for i in range(0,255):
# led(i)
# time.sleep(0.025)
#for i in range(255,0,-1):
# led(i)
# time.sleep(0.025)
time.sleep(1)
## Generate an image with PIL and put on the display
## First time through is slow as the fonts are not cached
##
start_time = time.time()
# load an available True Type font
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 14)
# New b-w image
im = Image.new('1', (84,48))
# New drawable on image
draw = ImageDraw.Draw(im)
# Full screen and half-screen ellipses
draw.ellipse((0,0,im.size[0]-1,im.size[1]-1), outline=1)
draw.ellipse((im.size[0]/4,im.size[1]/4,im.size[0]/4*3-1,im.size[1]/4*3-1), outline=1)
# Some simple text for a test (first with TT font, second with default
draw.text((10,10), "hello", font=font, fill=1)
draw.text((10,24), "world", fill=1)
# Check what happens when text exceeds width (clipped)
draw.text((0,0), "ABCabcDEFdefGHIghi", fill=1)
# Copy it to the display
put_image(im)
# clean up
del draw
del im
finish_time = time.time()
print 'PIL Drawing, total time = %.3f' % (
finish_time - start_time
)
print
time.sleep(1)
# Dim the LED...
#led(64)
# To loop continuously, remove the break
#break
if __name__ == '__main__':
main()
Maybe it will be of some use...
Enjoy!
Bill