Skip to content

Commit c48fe0d

Browse files
committed
No Tabs only spaces
1 parent 26795f4 commit c48fe0d

File tree

1 file changed

+389
-0
lines changed

1 file changed

+389
-0
lines changed
Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
#!/usr/bin/pythonhttp://raspberrypi.local/editor
2+
3+
#
4+
# based on code from lrvick and LiquidCrystal
5+
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
6+
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
7+
8+
9+
from time import sleep
10+
from Adafruit_I2C import Adafruit_I2C
11+
from Adafruit_MCP230xx import Adafruit_MCP230XX
12+
import smbus
13+
14+
15+
class Adafruit_CharLCDPlate:
16+
17+
OUTPUT = 0
18+
INPUT = 1
19+
20+
# LED colors
21+
RED = 0x01
22+
GREEN = 0x02
23+
BLUE = 0x04
24+
YELLOW = 0x03
25+
TEAL = 0x06
26+
VIOLET = 0x05
27+
ON = 0x07
28+
OFF = 0x0
29+
30+
# buttons
31+
SELECT = 0
32+
RIGHT = 1
33+
DOWN = 2
34+
UP = 3
35+
LEFT = 4
36+
37+
# commands
38+
LCD_CLEARDISPLAY = 0x01
39+
LCD_RETURNHOME = 0x02
40+
LCD_ENTRYMODESET = 0x04
41+
LCD_DISPLAYCONTROL = 0x08
42+
LCD_CURSORSHIFT = 0x10
43+
LCD_FUNCTIONSET = 0x20
44+
LCD_SETCGRAMADDR = 0x40
45+
LCD_SETDDRAMADDR = 0x80
46+
47+
# flags for display entry mode
48+
LCD_ENTRYRIGHT = 0x00
49+
LCD_ENTRYLEFT = 0x02
50+
LCD_ENTRYSHIFTINCREMENT = 0x01
51+
LCD_ENTRYSHIFTDECREMENT = 0x00
52+
53+
# flags for display on/off control
54+
LCD_DISPLAYON = 0x04
55+
LCD_DISPLAYOFF = 0x00
56+
LCD_CURSORON = 0x02
57+
LCD_CURSOROFF = 0x00
58+
LCD_BLINKON = 0x01
59+
LCD_BLINKOFF = 0x00
60+
61+
# flags for display/cursor shift
62+
LCD_DISPLAYMOVE = 0x08
63+
LCD_CURSORMOVE = 0x00
64+
65+
# flags for display/cursor shift
66+
LCD_DISPLAYMOVE = 0x08
67+
LCD_CURSORMOVE = 0x00
68+
LCD_MOVERIGHT = 0x04
69+
LCD_MOVELEFT = 0x00
70+
71+
# flags for function set
72+
LCD_8BITMODE = 0x10
73+
LCD_4BITMODE = 0x00
74+
LCD_2LINE = 0x08
75+
LCD_1LINE = 0x00
76+
LCD_5x10DOTS = 0x04
77+
LCD_5x8DOTS = 0x00
78+
79+
80+
81+
82+
def __init__(self, busnum=1, pin_rs=15, pin_e=13, pins_db=[12, 11, 10, 9], pin_rw=14):
83+
self.pin_rs = pin_rs
84+
self.pin_e = pin_e
85+
self.pin_rw = pin_rw
86+
self.pins_db = pins_db
87+
88+
self.mcp = Adafruit_MCP230XX(busnum = busnum, address = 0x20, num_gpios = 16)
89+
90+
self.mcp.config(self.pin_e, self.OUTPUT)
91+
self.mcp.config(self.pin_rs, self.OUTPUT)
92+
self.mcp.config(self.pin_rw, self.OUTPUT)
93+
self.mcp.output(self.pin_rw, 0)
94+
self.mcp.output(self.pin_e, 0)
95+
96+
for pin in self.pins_db:
97+
self.mcp.config(pin, self.OUTPUT)
98+
99+
self.write4bits(0x33) # initialization
100+
self.write4bits(0x32) # initialization
101+
self.write4bits(0x28) # 2 line 5x8 matrix
102+
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
103+
self.write4bits(0x06) # set cursor incrementing and no shift of display
104+
105+
self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
106+
107+
self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
108+
self.displayfunction |= self.LCD_2LINE
109+
110+
""" Initialize to default text direction (for romance languages) """
111+
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
112+
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode
113+
114+
# turn on backlights!
115+
self.mcp.config(6, self.mcp.OUTPUT)
116+
self.mcp.config(7, self.mcp.OUTPUT)
117+
self.mcp.config(8, self.mcp.OUTPUT)
118+
self.mcp.output(6, 0) # red
119+
self.mcp.output(7, 0) # green
120+
self.mcp.output(8, 0) # blue
121+
122+
# turn on pullups
123+
self.mcp.pullup(self.SELECT, True)
124+
self.mcp.pullup(self.LEFT, True)
125+
self.mcp.pullup(self.RIGHT, True)
126+
self.mcp.pullup(self.UP, True)
127+
self.mcp.pullup(self.DOWN, True)
128+
self.mcp.config(self.SELECT, self.mcp.INPUT)
129+
self.mcp.config(self.LEFT, self.mcp.INPUT)
130+
self.mcp.config(self.RIGHT, self.mcp.INPUT)
131+
self.mcp.config(self.DOWN, self.mcp.INPUT)
132+
self.mcp.config(self.UP, self.mcp.INPUT)
133+
134+
def begin(self, cols, lines):
135+
if (lines > 1):
136+
self.numlines = lines
137+
self.displayfunction |= self.LCD_2LINE
138+
self.currline = 0
139+
self.clear()
140+
141+
def home(self):
142+
self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
143+
self.waitBFlow() #wait for Busy flag low
144+
145+
146+
def clear(self):
147+
self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
148+
self.waitBFlow() #wait for Busy flag low
149+
150+
def setCursor(self, col, row):
151+
self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]
152+
if ( row > self.numlines ):
153+
row = self.numlines - 1 # we count rows starting w/0
154+
self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
155+
156+
def noDisplay(self):
157+
""" Turn the display off (quickly) """
158+
self.displaycontrol &= ~self.LCD_DISPLAYON
159+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
160+
161+
def display(self):
162+
""" Turn the display on (quickly) """
163+
self.displaycontrol |= self.LCD_DISPLAYON
164+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
165+
166+
def noCursor(self):
167+
""" underline cursor off """
168+
self.displaycontrol &= ~self.LCD_CURSORON
169+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
170+
171+
172+
def cursor(self):
173+
""" underline Cursor On """
174+
self.displaycontrol |= self.LCD_CURSORON
175+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
176+
177+
def ToggleCursor(self):
178+
""" Toggles the underline cursor On/Off bb"""
179+
self.displaycontrol ^= self.LCD_CURSORON
180+
self.delayMicroseconds(200000)
181+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
182+
183+
def noBlink(self):
184+
""" Turn off the blinking cursor """
185+
self.displaycontrol &= ~self.LCD_BLINKON
186+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
187+
188+
def blink(self):
189+
""" Turn on the blinking cursor"""
190+
self.displaycontrol |= self.LCD_BLINKON
191+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
192+
193+
def ToggleBlink(self):
194+
""" Toggles the blinking cursor"""
195+
self.displaycontrol ^= self.LCD_BLINKON
196+
self.delayMicroseconds(200000)
197+
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
198+
199+
200+
def DisplayLeft(self):
201+
""" These commands scroll the display without changing the RAM """
202+
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
203+
204+
def scrollDisplayRight(self):
205+
""" These commands scroll the display without changing the RAM """
206+
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);
207+
208+
def leftToRight(self):
209+
""" This is for text that flows Left to Right """
210+
self.displaymode |= self.LCD_ENTRYLEFT
211+
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);
212+
213+
def rightToLeft(self):
214+
""" This is for text that flows Right to Left """
215+
self.displaymode &= ~self.LCD_ENTRYLEFT
216+
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
217+
218+
def autoscroll(self):
219+
""" This will 'right justify' text from the cursor """
220+
self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
221+
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
222+
223+
def noAutoscroll(self):
224+
""" This will 'left justify' text from the cursor """
225+
self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
226+
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
227+
228+
def write4bits(self, bits, char_mode=False):
229+
""" Send command to LCD """
230+
#self.delayMicroseconds(1000) # 1000 microsecond sleep
231+
bits=bin(bits)[2:].zfill(8)
232+
self.mcp.output(self.pin_rs, char_mode)
233+
234+
for i in range(4):
235+
if bits[i] == "1":
236+
self.mcp.output(self.pins_db[::-1][i], True)
237+
else:
238+
self.mcp.output(self.pins_db[::-1][i], False)
239+
self.pulseEnable()
240+
241+
for i in range(4,8):
242+
if bits[i] == "1":
243+
self.mcp.output(self.pins_db[::-1][i-4], True)
244+
else:
245+
self.mcp.output(self.pins_db[::-1][i-4], False)
246+
self.pulseEnable()
247+
248+
#See pg. 24 and 58 HD44780.pdf and http://www.avrbeginners.net/ Standard LCD bit mode
249+
def read4bits(self, char_mode=False):
250+
""" Get Data from LCD, when char_mode = 0 get Busy Flag and Address Counter, else get RAM data """
251+
# print "First:", bin(self.mcp.direction)[2:].zfill(16)
252+
self.mcp.output(self.pin_rs, char_mode) # when char_mode = 0 get Busy Flag and Address Counter, else get RAM data
253+
self.mcp.output(self.pin_rw, 1) #set rw to 1
254+
# Configure pins for input
255+
makeinput=True
256+
if makeinput:
257+
for pin in self.pins_db:
258+
self.mcp.config(pin, self.INPUT)
259+
self.mcp.output(self.pin_e, True) # set Enable high and keep while read first nibble
260+
bits = range(8)
261+
# get the pins values
262+
for i in range(4):
263+
bt = self.mcp.input(self.pins_db[::-1][i], makeinput) # if makeinput is False, pin direction checking is supressed in input
264+
bits[i]=bt
265+
#print i,bt,bits[i]
266+
self.mcp.output(self.pin_e, False) # set Enable low to finish first nibble
267+
self.mcp.output(self.pin_e, True) # set Enable high and keep while read 2nd nibble
268+
# get the pins values
269+
for i in range(4,8):
270+
bt = self.mcp.input(self.pins_db[::-1][i-4],makeinput)
271+
bits[i]=bt
272+
#print i,bt,bits[i]
273+
self.mcp.output(self.pin_e, False) # set Enable low to finish 2nd nibble
274+
# restore to pins to output and rw to 0
275+
for pin in self.pins_db:
276+
self.mcp.config(pin, self.OUTPUT)
277+
self.mcp.output(self.pin_rw, 0) # return rw to 0
278+
# print "Last :", bin(self.mcp.direction)[2:].zfill(16)
279+
return bits;
280+
281+
def readBF(self):
282+
""" Get Data from LCD, when char_mode = 0 get Busy Flag and Address Counter, else get RAM data """
283+
# print "First:", bin(self.mcp.direction)[2:].zfill(16)
284+
self.mcp.output(self.pin_rs, 0) # when char_mode = 0 get Busy Flag and Address Counter, else get RAM data
285+
self.mcp.output(self.pin_rw, 1) #set rw to 1
286+
# Configure pins for input
287+
makeinput=True
288+
self.mcp.config(self.pins_db[::-1][1], self.INPUT)
289+
self.mcp.output(self.pin_e, True) # set Enable high and keep while read first nibble
290+
# get the pins values
291+
bt = self.mcp.input(self.pins_db[::-1][1], makeinput) # if makeinput is False, pin direction checking is supressed in input
292+
self.mcp.output(self.pin_e, False) # set Enable low to finish first nibble
293+
self.pulseEnable() # one more pulse to get (but ingore the 2nd nibble)
294+
# restore to pins to output and rw to 0
295+
self.mcp.config(self.pins_db[::-1][1], self.OUTPUT)
296+
self.mcp.output(self.pin_rw, 0) # return rw to 0
297+
return bt==1
298+
299+
def waitBFlow(self):
300+
for cnt in range(100000):
301+
if not self.readBF():
302+
#print cnt
303+
return
304+
print "timed out of waitBFlow"
305+
306+
def delayMicroseconds(self, microseconds):
307+
seconds = microseconds / 1000000 # divide microseconds by 1 million for seconds
308+
sleep(seconds)
309+
310+
def pulseEnable(self):
311+
self.mcp.output(self.pin_e, True)
312+
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
313+
self.mcp.output(self.pin_e, False)
314+
#self.delayMicroseconds(1) # commands need > 37us to settle
315+
316+
def message(self, text):
317+
""" Send string to LCD. Newline wraps to second line"""
318+
for char in text:
319+
if char == '\n':
320+
self.write4bits(0xC0) # set DDRAM address 0x40 start of second line
321+
else:
322+
self.write4bits(ord(char),True)
323+
324+
def backlight(self, color):
325+
self.mcp.output(6, not color & 0x01)
326+
self.mcp.output(7, not color & 0x02)
327+
self.mcp.output(8, not color & 0x04)
328+
329+
def buttonPressed(self, buttonname):
330+
if (buttonname > self.LEFT):
331+
return false
332+
333+
return not self.mcp.input(buttonname)
334+
335+
336+
if __name__ == '__main__':
337+
338+
lcd = Adafruit_CharLCDPlate(busnum = 1)
339+
lcd.clear()
340+
lcd.message("Adafruit RGB LCD\nPlate w/Keypad!")
341+
sleep(1)
342+
343+
print " Cycle thru backlight colors 3 times "
344+
345+
for i in range(3):
346+
print "red"
347+
lcd.backlight(lcd.RED)
348+
sleep(1)
349+
print "yellow"
350+
lcd.backlight(lcd.YELLOW)
351+
sleep(1)
352+
print "green"
353+
lcd.backlight(lcd.GREEN)
354+
sleep(1)
355+
print "teal"
356+
lcd.backlight(lcd.TEAL)
357+
sleep(1)
358+
print "blue"
359+
lcd.backlight(lcd.BLUE)
360+
sleep(1)
361+
print "violet"
362+
lcd.backlight(lcd.VIOLET)
363+
sleep(1)
364+
print "off"
365+
lcd.backlight(lcd.OFF)
366+
sleep(1)
367+
print "on"
368+
lcd.backlight(lcd.ON)
369+
sleep(1)
370+
371+
print " Try buttons on plate"
372+
373+
while 1:
374+
if (lcd.buttonPressed(lcd.LEFT)):
375+
lcd.backlight(lcd.RED)
376+
377+
if (lcd.buttonPressed(lcd.UP)):
378+
lcd.backlight(lcd.BLUE)
379+
380+
if (lcd.buttonPressed(lcd.DOWN)):
381+
lcd.backlight(lcd.GREEN)
382+
383+
if (lcd.buttonPressed(lcd.RIGHT)):
384+
lcd.backlight(lcd.VIOLET)
385+
386+
if (lcd.buttonPressed(lcd.SELECT)):
387+
lcd.backlight(lcd.ON)
388+
389+

0 commit comments

Comments
 (0)