1
- #!/usr/bin/pythonhttp://raspberrypi.local/editor
1
+ #!/usr/bin/pythonhttp://raspberrypi.local/editor
2
2
3
3
#
4
4
# based on code from lrvick and LiquidCrystal
5
5
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
6
6
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
7
- #
7
+
8
8
9
9
from time import sleep
10
10
from Adafruit_I2C import Adafruit_I2C
@@ -35,71 +35,75 @@ class Adafruit_CharLCDPlate:
35
35
LEFT = 4
36
36
37
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
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
46
47
47
# flags for display entry mode
48
- LCD_ENTRYRIGHT = 0x00
49
- LCD_ENTRYLEFT = 0x02
50
- LCD_ENTRYSHIFTINCREMENT = 0x01
51
- LCD_ENTRYSHIFTDECREMENT = 0x00
48
+ LCD_ENTRYRIGHT = 0x00
49
+ LCD_ENTRYLEFT = 0x02
50
+ LCD_ENTRYSHIFTINCREMENT = 0x01
51
+ LCD_ENTRYSHIFTDECREMENT = 0x00
52
52
53
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
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
60
61
61
# flags for display/cursor shift
62
- LCD_DISPLAYMOVE = 0x08
63
- LCD_CURSORMOVE = 0x00
62
+ LCD_DISPLAYMOVE = 0x08
63
+ LCD_CURSORMOVE = 0x00
64
64
65
65
# flags for display/cursor shift
66
- LCD_DISPLAYMOVE = 0x08
67
- LCD_CURSORMOVE = 0x00
68
- LCD_MOVERIGHT = 0x04
69
- LCD_MOVELEFT = 0x00
66
+ LCD_DISPLAYMOVE = 0x08
67
+ LCD_CURSORMOVE = 0x00
68
+ LCD_MOVERIGHT = 0x04
69
+ LCD_MOVELEFT = 0x00
70
70
71
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
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
78
79
79
80
80
81
81
82
- def __init__ (self , busnum = 0 , pin_rs = 15 , pin_e = 13 , pins_db = [12 , 11 , 10 , 9 ], pin_rw = 14 ):
82
+ def __init__ (self , busnum = 1 , pin_rs = 15 , pin_e = 13 , pins_db = [12 , 11 , 10 , 9 ], pin_rw = 14 ):
83
83
self .pin_rs = pin_rs
84
84
self .pin_e = pin_e
85
85
self .pin_rw = pin_rw
86
86
self .pins_db = pins_db
87
87
88
88
self .mcp = Adafruit_MCP230XX (busnum = busnum , address = 0x20 , num_gpios = 16 )
89
+
89
90
self .mcp .config (self .pin_e , self .OUTPUT )
90
91
self .mcp .config (self .pin_rs , self .OUTPUT )
91
92
self .mcp .config (self .pin_rw , self .OUTPUT )
92
93
self .mcp .output (self .pin_rw , 0 )
93
- self .mcp .output (self .pin_e , 0 )
94
+ self .mcp .output (self .pin_e , 0 )
95
+
94
96
for pin in self .pins_db :
95
97
self .mcp .config (pin , self .OUTPUT )
98
+
96
99
self .write4bits (0x33 ) # initialization
97
100
self .write4bits (0x32 ) # initialization
98
- self .write4bits (0x28 ) # 2 line 5x7 matrix
101
+ self .write4bits (0x28 ) # 2 line 5x8 matrix
99
102
self .write4bits (0x0C ) # turn cursor off 0x0E to enable cursor
100
- self .write4bits (0x06 ) # shift cursor right
103
+ self .write4bits (0x06 ) # set cursor incrementing and no shift of display
101
104
102
105
self .displaycontrol = self .LCD_DISPLAYON | self .LCD_CURSOROFF | self .LCD_BLINKOFF
106
+
103
107
self .displayfunction = self .LCD_4BITMODE | self .LCD_1LINE | self .LCD_5x8DOTS
104
108
self .displayfunction |= self .LCD_2LINE
105
109
@@ -136,12 +140,13 @@ def begin(self, cols, lines):
136
140
137
141
def home (self ):
138
142
self .write4bits (self .LCD_RETURNHOME ) # set cursor position to zero
139
- self .delayMicroseconds (2000 ) # this command takes a long time!
143
+ self .waitBFlow () #wait for Busy flag low
144
+
140
145
141
146
def clear (self ):
142
147
self .write4bits (self .LCD_CLEARDISPLAY ) # command to clear display
143
- self .delayMicroseconds ( 2000 ) # 2000 microsecond sleep, clearing the display takes a long time
144
-
148
+ self .waitBFlow () #wait for Busy flag low
149
+
145
150
def setCursor (self , col , row ):
146
151
self .row_offsets = [ 0x00 , 0x40 , 0x14 , 0x54 ]
147
152
if ( row > self .numlines ):
@@ -159,26 +164,39 @@ def display(self):
159
164
self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
160
165
161
166
def noCursor (self ):
162
- """ Turns the underline cursor off """
167
+ """ underline cursor off """
163
168
self .displaycontrol &= ~ self .LCD_CURSORON
164
169
self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
165
170
166
171
167
172
def cursor (self ):
168
- """ Turns the underline cursor On """
173
+ """ underline Cursor On """
169
174
self .displaycontrol |= self .LCD_CURSORON
170
175
self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
171
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
+
172
183
def noBlink (self ):
173
- """ Turn on and off the blinking cursor """
184
+ """ Turn off the blinking cursor """
174
185
self .displaycontrol &= ~ self .LCD_BLINKON
175
186
self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
176
187
177
188
def blink (self ):
178
- """ Turn on and off the blinking cursor """
189
+ """ Turn on the blinking cursor"""
179
190
self .displaycontrol |= self .LCD_BLINKON
180
191
self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
181
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
+
182
200
def DisplayLeft (self ):
183
201
""" These commands scroll the display without changing the RAM """
184
202
self .write4bits (self .LCD_CURSORSHIFT | self .LCD_DISPLAYMOVE | self .LCD_MOVELEFT )
@@ -212,18 +230,78 @@ def write4bits(self, bits, char_mode=False):
212
230
#self.delayMicroseconds(1000) # 1000 microsecond sleep
213
231
bits = bin (bits )[2 :].zfill (8 )
214
232
self .mcp .output (self .pin_rs , char_mode )
233
+
215
234
for i in range (4 ):
216
235
if bits [i ] == "1" :
217
236
self .mcp .output (self .pins_db [::- 1 ][i ], True )
218
237
else :
219
238
self .mcp .output (self .pins_db [::- 1 ][i ], False )
220
239
self .pulseEnable ()
240
+
221
241
for i in range (4 ,8 ):
222
242
if bits [i ] == "1" :
223
243
self .mcp .output (self .pins_db [::- 1 ][i - 4 ], True )
224
244
else :
225
245
self .mcp .output (self .pins_db [::- 1 ][i - 4 ], False )
226
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 the 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 the 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"
227
305
228
306
def delayMicroseconds (self , microseconds ):
229
307
seconds = microseconds / 1000000 # divide microseconds by 1 million for seconds
@@ -239,7 +317,7 @@ def message(self, text):
239
317
""" Send string to LCD. Newline wraps to second line"""
240
318
for char in text :
241
319
if char == '\n ' :
242
- self .write4bits (0xC0 ) # next line
320
+ self .write4bits (0xC0 ) # set DDRAM address 0x40 start of second line
243
321
else :
244
322
self .write4bits (ord (char ),True )
245
323
@@ -251,42 +329,60 @@ def backlight(self, color):
251
329
def buttonPressed (self , buttonname ):
252
330
if (buttonname > self .LEFT ):
253
331
return false
332
+
254
333
return not self .mcp .input (buttonname )
255
334
256
335
257
336
if __name__ == '__main__' :
258
337
259
- lcd = Adafruit_CharLCDPlate (busnum = 0 )
338
+ lcd = Adafruit_CharLCDPlate (busnum = 1 )
260
339
lcd .clear ()
261
340
lcd .message ("Adafruit RGB LCD\n Plate w/Keypad!" )
262
341
sleep (1 )
263
- while 1 :
264
- if (lcd .buttonPressed (lcd .LEFT )):
265
- lcd .backlight (lcd .RED )
266
- if (lcd .buttonPressed (lcd .UP )):
267
- lcd .backlight (lcd .BLUE )
268
- if (lcd .buttonPressed (lcd .DOWN )):
269
- lcd .backlight (lcd .GREEN )
270
- if (lcd .buttonPressed (lcd .RIGHT )):
271
- lcd .backlight (lcd .VIOLET )
272
- if (lcd .buttonPressed (lcd .SELECT )):
273
- lcd .backlight (lcd .ON )
274
342
343
+ print " Cycle thru backlight colors 3 times "
275
344
276
- while 1 :
345
+ for i in range (3 ):
346
+ print "red"
277
347
lcd .backlight (lcd .RED )
278
348
sleep (1 )
349
+ print "yellow"
279
350
lcd .backlight (lcd .YELLOW )
280
351
sleep (1 )
352
+ print "green"
281
353
lcd .backlight (lcd .GREEN )
282
354
sleep (1 )
355
+ print "teal"
283
356
lcd .backlight (lcd .TEAL )
284
357
sleep (1 )
358
+ print "blue"
285
359
lcd .backlight (lcd .BLUE )
286
360
sleep (1 )
361
+ print "violet"
287
362
lcd .backlight (lcd .VIOLET )
288
363
sleep (1 )
289
- lcd .backlight (lcd .ON )
290
- sleep (1 )
364
+ print "off"
291
365
lcd .backlight (lcd .OFF )
292
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
+
0 commit comments