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
+ OUTPUT = 0
15
+ INPUT = 1
16
+ mcp = Adafruit_MCP230XX (busnum = 0 , address = 0x20 , num_gpios = 16 )
17
+
18
+
19
+ class Adafruit_CharLCD :
20
+
21
+ # commands
22
+ LCD_CLEARDISPLAY = 0x01
23
+ LCD_RETURNHOME = 0x02
24
+ LCD_ENTRYMODESET = 0x04
25
+ LCD_DISPLAYCONTROL = 0x08
26
+ LCD_CURSORSHIFT = 0x10
27
+ LCD_FUNCTIONSET = 0x20
28
+ LCD_SETCGRAMADDR = 0x40
29
+ LCD_SETDDRAMADDR = 0x80
30
+
31
+ # flags for display entry mode
32
+ LCD_ENTRYRIGHT = 0x00
33
+ LCD_ENTRYLEFT = 0x02
34
+ LCD_ENTRYSHIFTINCREMENT = 0x01
35
+ LCD_ENTRYSHIFTDECREMENT = 0x00
36
+
37
+ # flags for display on/off control
38
+ LCD_DISPLAYON = 0x04
39
+ LCD_DISPLAYOFF = 0x00
40
+ LCD_CURSORON = 0x02
41
+ LCD_CURSOROFF = 0x00
42
+ LCD_BLINKON = 0x01
43
+ LCD_BLINKOFF = 0x00
44
+
45
+ # flags for display/cursor shift
46
+ LCD_DISPLAYMOVE = 0x08
47
+ LCD_CURSORMOVE = 0x00
48
+
49
+ # flags for display/cursor shift
50
+ LCD_DISPLAYMOVE = 0x08
51
+ LCD_CURSORMOVE = 0x00
52
+ LCD_MOVERIGHT = 0x04
53
+ LCD_MOVELEFT = 0x00
54
+
55
+ # flags for function set
56
+ LCD_8BITMODE = 0x10
57
+ LCD_4BITMODE = 0x00
58
+ LCD_2LINE = 0x08
59
+ LCD_1LINE = 0x00
60
+ LCD_5x10DOTS = 0x04
61
+ LCD_5x8DOTS = 0x00
62
+
63
+
64
+
65
+ def __init__ (self , pin_rs = 25 , pin_e = 24 , pins_db = [23 , 17 , 21 , 22 ], pin_rw = 0 ):
66
+ self .pin_rs = pin_rs
67
+ self .pin_e = pin_e
68
+ self .pin_rw = pin_rw
69
+ self .pins_db = pins_db
70
+
71
+ mcp .config (self .pin_e , OUTPUT )
72
+ mcp .config (self .pin_rs , OUTPUT )
73
+ mcp .config (self .pin_rw , OUTPUT )
74
+ mcp .output (self .pin_rw , 0 )
75
+ mcp .output (self .pin_e , 0 )
76
+
77
+ for pin in self .pins_db :
78
+ mcp .config (pin , OUTPUT )
79
+
80
+ self .write4bits (0x33 ) # initialization
81
+ self .write4bits (0x32 ) # initialization
82
+ self .write4bits (0x28 ) # 2 line 5x7 matrix
83
+ self .write4bits (0x0C ) # turn cursor off 0x0E to enable cursor
84
+ self .write4bits (0x06 ) # shift cursor right
85
+
86
+ self .displaycontrol = self .LCD_DISPLAYON | self .LCD_CURSOROFF | self .LCD_BLINKOFF
87
+
88
+ self .displayfunction = self .LCD_4BITMODE | self .LCD_1LINE | self .LCD_5x8DOTS
89
+ self .displayfunction |= self .LCD_2LINE
90
+
91
+ """ Initialize to default text direction (for romance languages) """
92
+ self .displaymode = self .LCD_ENTRYLEFT | self .LCD_ENTRYSHIFTDECREMENT
93
+ self .write4bits (self .LCD_ENTRYMODESET | self .displaymode ) # set the entry mode
94
+
95
+
96
+ def begin (self , cols , lines ):
97
+ if (lines > 1 ):
98
+ self .numlines = lines
99
+ self .displayfunction |= self .LCD_2LINE
100
+ self .currline = 0
101
+ self .clear ()
102
+
103
+ def home (self ):
104
+ self .write4bits (self .LCD_RETURNHOME ) # set cursor position to zero
105
+ self .delayMicroseconds (2000 ) # this command takes a long time!
106
+
107
+ def clear (self ):
108
+ self .write4bits (self .LCD_CLEARDISPLAY ) # command to clear display
109
+ self .delayMicroseconds (2000 ) # 2000 microsecond sleep, clearing the display takes a long time
110
+
111
+ def setCursor (self , col , row ):
112
+ self .row_offsets = [ 0x00 , 0x40 , 0x14 , 0x54 ]
113
+ if ( row > self .numlines ):
114
+ row = self .numlines - 1 # we count rows starting w/0
115
+ self .write4bits (self .LCD_SETDDRAMADDR | (col + self .row_offsets [row ]))
116
+
117
+ def noDisplay (self ):
118
+ """ Turn the display off (quickly) """
119
+ self .displaycontrol &= ~ self .LCD_DISPLAYON
120
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
121
+
122
+ def display (self ):
123
+ """ Turn the display on (quickly) """
124
+ self .displaycontrol |= self .LCD_DISPLAYON
125
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
126
+
127
+ def noCursor (self ):
128
+ """ Turns the underline cursor on/off """
129
+ self .displaycontrol &= ~ self .LCD_CURSORON
130
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
131
+
132
+
133
+ def cursor (self ):
134
+ """ Cursor On """
135
+ self .displaycontrol |= self .LCD_CURSORON
136
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
137
+
138
+ def noBlink (self ):
139
+ """ Turn on and off the blinking cursor """
140
+ self .displaycontrol &= ~ self .LCD_BLINKON
141
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
142
+
143
+ def noBlink (self ):
144
+ """ Turn on and off the blinking cursor """
145
+ self .displaycontrol &= ~ self .LCD_BLINKON
146
+ self .write4bits (self .LCD_DISPLAYCONTROL | self .displaycontrol )
147
+
148
+ def DisplayLeft (self ):
149
+ """ These commands scroll the display without changing the RAM """
150
+ self .write4bits (self .LCD_CURSORSHIFT | self .LCD_DISPLAYMOVE | self .LCD_MOVELEFT )
151
+
152
+ def scrollDisplayRight (self ):
153
+ """ These commands scroll the display without changing the RAM """
154
+ self .write4bits (self .LCD_CURSORSHIFT | self .LCD_DISPLAYMOVE | self .LCD_MOVERIGHT );
155
+
156
+ def leftToRight (self ):
157
+ """ This is for text that flows Left to Right """
158
+ self .displaymode |= self .LCD_ENTRYLEFT
159
+ self .write4bits (self .LCD_ENTRYMODESET | self .displaymode );
160
+
161
+ def rightToLeft (self ):
162
+ """ This is for text that flows Right to Left """
163
+ self .displaymode &= ~ self .LCD_ENTRYLEFT
164
+ self .write4bits (self .LCD_ENTRYMODESET | self .displaymode )
165
+
166
+ def autoscroll (self ):
167
+ """ This will 'right justify' text from the cursor """
168
+ self .displaymode |= self .LCD_ENTRYSHIFTINCREMENT
169
+ self .write4bits (self .LCD_ENTRYMODESET | self .displaymode )
170
+
171
+ def noAutoscroll (self ):
172
+ """ This will 'left justify' text from the cursor """
173
+ self .displaymode &= ~ self .LCD_ENTRYSHIFTINCREMENT
174
+ self .write4bits (self .LCD_ENTRYMODESET | self .displaymode )
175
+
176
+ def write4bits (self , bits , char_mode = False ):
177
+ """ Send command to LCD """
178
+ #self.delayMicroseconds(1000) # 1000 microsecond sleep
179
+ bits = bin (bits )[2 :].zfill (8 )
180
+ mcp .output (self .pin_rs , char_mode )
181
+
182
+ for i in range (4 ):
183
+ if bits [i ] == "1" :
184
+ mcp .output (self .pins_db [::- 1 ][i ], True )
185
+ else :
186
+ mcp .output (self .pins_db [::- 1 ][i ], False )
187
+ self .pulseEnable ()
188
+
189
+ for i in range (4 ,8 ):
190
+ if bits [i ] == "1" :
191
+ mcp .output (self .pins_db [::- 1 ][i - 4 ], True )
192
+ else :
193
+ mcp .output (self .pins_db [::- 1 ][i - 4 ], False )
194
+ self .pulseEnable ()
195
+
196
+ def delayMicroseconds (self , microseconds ):
197
+ seconds = microseconds / 1000000 # divide microseconds by 1 million for seconds
198
+ sleep (seconds )
199
+
200
+ def pulseEnable (self ):
201
+ mcp .output (self .pin_e , True )
202
+ self .delayMicroseconds (1 ) # 1 microsecond pause - enable pulse must be > 450ns
203
+ mcp .output (self .pin_e , False )
204
+ #self.delayMicroseconds(1) # commands need > 37us to settle
205
+
206
+ def message (self , text ):
207
+ """ Send string to LCD. Newline wraps to second line"""
208
+ for char in text :
209
+ if char == '\n ' :
210
+ self .write4bits (0xC0 ) # next line
211
+ else :
212
+ self .write4bits (ord (char ),True )
213
+
214
+
215
+
216
+ if __name__ == '__main__' :
217
+
218
+
219
+ # input test
220
+ # for i in range(16):
221
+ # mcp.pullup(i, 1)
222
+ # while (True):
223
+ # for i in range(16):
224
+ # print "%d: %x" % (i, mcp.input(i) >> i)
225
+ mcp .config (6 , OUTPUT )
226
+ mcp .config (7 , OUTPUT )
227
+ mcp .config (8 , OUTPUT )
228
+ mcp .output (6 , 0 ) # red
229
+ mcp .output (7 , 0 ) # green
230
+ mcp .output (8 , 0 ) # blue
231
+
232
+ lcd = Adafruit_CharLCD (15 , 13 , [12 ,11 ,10 ,9 ], 14 )
233
+ lcd .clear ()
234
+ lcd .message ("Adafruit RGB LCD\n Plate w/Keypad!" )
235
+ while 1 :
236
+ mcp .output (6 , 0 ) # red
237
+ mcp .output (7 , 1 ) # green
238
+ mcp .output (8 , 1 ) # blue
239
+ sleep (1 )
240
+ mcp .output (7 , 0 ) # green
241
+ sleep (1 )
242
+ mcp .output (6 , 1 ) # red
243
+ sleep (1 )
244
+ mcp .output (8 , 0 ) # blue
245
+ sleep (1 )
246
+ mcp .output (7 , 1 ) # green
247
+ sleep (1 )
248
+ mcp .output (6 , 0 ) # red
249
+ sleep (1 )
250
+
0 commit comments