adafruit_charlcd 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/Adafruit_CharLCD.rb +445 -0
  3. metadata +58 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 00f2924b8c332e91c58b7d71ceeb3b01190f1c10
4
+ data.tar.gz: ea8369c4aca6986fe7e74fc4d476c7d289283041
5
+ SHA512:
6
+ metadata.gz: 53a8bead7f77000d4b459bf1dce38aad6652ba17ffed7a759aa86acee18301ea5b4e6878bec3ae4a7f46779f09a2ed021bcaf66ad8e07aa841362c67eb42b9cf
7
+ data.tar.gz: 52158a4d6a7685fb0f8c5d5a9b08ccc09f055945687b251b943d5933153cf523788aa7d73babfae1a253aa75c62627ea5ea335faa9424e7cecd985fe4dbe76c0
@@ -0,0 +1,445 @@
1
+ require 'rpi_gpio'
2
+ # Copyright (c) 2014 Adafruit Industries
3
+ # Author: Tony DiCola
4
+ # Ported by: Rigel
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ # Commands
25
+ LCD_CLEARDISPLAY = 0x01
26
+ LCD_RETURNHOME = 0x02
27
+ LCD_ENTRYMODESET = 0x04
28
+ LCD_DISPLAYCONTROL = 0x08
29
+ LCD_CURSORSHIFT = 0x10
30
+ LCD_FUNCTIONSET = 0x20
31
+ LCD_SETCGRAMADDR = 0x40
32
+ LCD_SETDDRAMADDR = 0x80
33
+
34
+ # Entry flags
35
+ LCD_ENTRYRIGHT = 0x00
36
+ LCD_ENTRYLEFT = 0x02
37
+ LCD_ENTRYSHIFTINCREMENT = 0x01
38
+ LCD_ENTRYSHIFTDECREMENT = 0x00
39
+
40
+ # Control flags
41
+ LCD_DISPLAYON = 0x04
42
+ LCD_DISPLAYOFF = 0x00
43
+ LCD_CURSORON = 0x02
44
+ LCD_CURSOROFF = 0x00
45
+ LCD_BLINKON = 0x01
46
+ LCD_BLINKOFF = 0x00
47
+
48
+ # Move flags
49
+ LCD_DISPLAYMOVE = 0x08
50
+ LCD_CURSORMOVE = 0x00
51
+ LCD_MOVERIGHT = 0x04
52
+ LCD_MOVELEFT = 0x00
53
+
54
+ # Function set flags
55
+ LCD_8BITMODE = 0x10
56
+ LCD_4BITMODE = 0x00
57
+ LCD_2LINE = 0x08
58
+ LCD_1LINE = 0x00
59
+ LCD_5x10DOTS = 0x04
60
+ LCD_5x8DOTS = 0x00
61
+
62
+ # Offset for up to 4 rows.
63
+ LCD_ROW_OFFSETS = [0x00, 0x40, 0x14, 0x54]
64
+
65
+ # Char LCD plate GPIO numbers.
66
+ LCD_PLATE_RS = 15
67
+ LCD_PLATE_RW = 14
68
+ LCD_PLATE_EN = 13
69
+ LCD_PLATE_D4 = 12
70
+ LCD_PLATE_D5 = 11
71
+ LCD_PLATE_D6 = 10
72
+ LCD_PLATE_D7 = 9
73
+ LCD_PLATE_RED = 6
74
+ LCD_PLATE_GREEN = 7
75
+ LCD_PLATE_BLUE = 8
76
+
77
+ # Char LCD plate button names.
78
+ SELECT = 0
79
+ RIGHT = 1
80
+ DOWN = 2
81
+ UP = 3
82
+ LEFT = 4
83
+ # PWM duty cycles
84
+ PWM_FREQUENCY=240
85
+ class Adafruit_CharLCD
86
+ def initialize(rs, en, d4, d5, d6, d7, cols, lines, backlight=nil,
87
+ invert_polarity=true,
88
+ enable_pwm=false,
89
+ initial_backlight=1.0)
90
+ #Initialize the LCD. RS, EN, and D4...D7 parameters should be the pins
91
+ #connected to the LCD RS, clock enable, and data line 4 through 7 connections.
92
+ #The LCD will be used in its 4-bit mode so these 6 lines are the only ones
93
+ #required to use the LCD. You must also pass in the number of columns and
94
+ #lines on the LCD.
95
+ #If you would like to control the backlight, pass in the pin connected to
96
+ #the backlight with the backlight parameter. The invert_polarity boolean
97
+ #controls if the backlight is one with a LOW signal or HIGH signal. The
98
+ #default invert_polarity value is true, i.e. the backlight is on with a
99
+ #LOW signal.
100
+ #You can enable PWM of the backlight pin to have finer control on the
101
+ #brightness. To enable PWM make sure your hardware supports PWM on the
102
+ #provided backlight pin and set enable_pwm to true (the default is false).
103
+ #The appropriate PWM library will be used depending on the platform, but
104
+ #you can provide an explicit one with the pwm parameter.
105
+ #The initial state of the backlight is ON, but you can set it to an
106
+ #explicit initial state with the initial_backlight parameter (0 is off,
107
+ #1 is on/full bright).
108
+ # Save column and line state.
109
+ @_cols = cols
110
+ @_lines = lines
111
+ # Save GPIO state and pin numbers.
112
+ @_rs = rs
113
+ @_en = en
114
+ @_d4 = d4
115
+ @_d5 = d5
116
+ @_d6 = d6
117
+ @_d7 = d7
118
+ # Save backlight state.
119
+ @_backlight = backlight
120
+ @_pwm_enabled = enable_pwm
121
+ @_blpol = !invert_polarity
122
+ #Setting up the pins
123
+ [rs, en, d4, d5, d6, d7].each do |pin|
124
+ RPi::GPIO.setup pin, :as => :output, :initialize => :low
125
+ end
126
+ #setup backlight
127
+ if @_backlight !=nil
128
+ RPi::GPIO.setup @_backlight, :as =>:output,:initialize=>:low
129
+ if enable_pwm
130
+ @_backlightPWM=RPi::GPIO::PWM.new(@_backlight, PWM_FREQUENCY)
131
+ @_backlightPWM.start(_pwm_duty_cycle(initial_backlight))
132
+ else
133
+ #FIXME: I really need to not work through the logic at 03:21 ... https://github.com/adafruit/Adafruit_Python_CharLCD/blob/f5a43f9c331180aeeef9cc86395ad84ca7deb631/Adafruit_CharLCD/Adafruit_CharLCD.py#L148
134
+ if(initial_backlight>0)
135
+
136
+ else
137
+ end
138
+ end
139
+ end
140
+ # Initialize the display.
141
+ # Initialize the display.
142
+ write8(0x33)
143
+ write8(0x32)
144
+ # Initialize display control, function, and mode registers.
145
+ @_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF
146
+ @_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_2LINE | LCD_5x8DOTS
147
+ @_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
148
+ # Write registers.
149
+ write8(LCD_DISPLAYCONTROL | @_displaycontrol)
150
+ write8(LCD_FUNCTIONSET | @_displayfunction)
151
+ write8(LCD_ENTRYMODESET | @_displaymode) # set the entry mode
152
+ clear()
153
+ end
154
+ def home()
155
+ #Move the cursor back to its home (first line and first column).
156
+ write8(LCD_RETURNHOME) # set cursor position to zero
157
+ sleep(0.003) # this command takes a long time!
158
+ end
159
+ def clear()
160
+ #Clear the LCD.
161
+ write8(LCD_CLEARDISPLAY) # command to clear display
162
+ sleep(0.003) # 3000 microsecond sleep, clearing the display takes a long time
163
+ end
164
+ def set_cursor(col, row)
165
+ #Move the cursor to an explicit column and row position.
166
+ # Clamp row to the last row of the display.
167
+ if row > @_lines
168
+ row = @_lines - 1
169
+ end
170
+ # Set location.
171
+ write8(LCD_SETDDRAMADDR | (col + LCD_ROW_OFFSETS[row]))
172
+ end
173
+ def enable_display(enable)
174
+ #Enable or disable the display. Set enable to true to enable.
175
+ if(enable)
176
+ @_displaycontrol |= LCD_DISPLAYON
177
+ else
178
+ @_displaycontrol &= ~LCD_DISPLAYON
179
+ end
180
+ write8(@_displaycontrol|LCD_DISPLAYCONTROL)
181
+ end
182
+ def show_cursor(show)
183
+ #Show or hide the cursor. Cursor is shown if show is true.
184
+ if(show)
185
+ @_displaycontrol |= LCD_CURSORON
186
+ else
187
+ @_displaycontrol &= ~LCD_CURSORON
188
+ end
189
+ write8(@_displaycontrol|LCD_DISPLAYCONTROL)
190
+ end
191
+ def blink(blink)
192
+ #Turn on or off cursor blinking. Set blink to true to enable blinking."""
193
+ if blink
194
+ @_displaycontrol |= LCD_BLINKON
195
+ else
196
+ @_displaycontrol &= ~LCD_BLINKON
197
+ end
198
+ write8(@_displaycontrol|LCD_DISPLAYCONTROL)
199
+ end
200
+ def move_left()
201
+ #Move display left one position.
202
+ write8(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT)
203
+ end
204
+ def move_right()
205
+ #Move display right one position.
206
+ write8(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT)
207
+ end
208
+ def set_left_to_right()
209
+ #Set text direction left to right."""
210
+ @_displaymode |= LCD_ENTRYLEFT
211
+ write8(LCD_ENTRYMODESET | @_displaymode)
212
+ end
213
+ def set_right_to_left()
214
+ #Set text direction right to left.
215
+ @_displaymode &= ~LCD_ENTRYLEFT
216
+ write8(LCD_ENTRYMODESET | @_displaymode)
217
+ end
218
+ def autoscroll(autoscroll)
219
+ #Autoscroll will 'right justify' text from the cursor if set true,
220
+ #otherwise it will 'left justify' the text.
221
+ if autoscroll
222
+ @_displaymode |= LCD_ENTRYSHIFTINCREMENT
223
+ else
224
+ @_displaymode &= ~LCD_ENTRYSHIFTINCREMENT
225
+ end
226
+ write8(LCD_ENTRYMODESET | @_displaymode)
227
+ end
228
+ def message(text)
229
+ #Write text to display. Note that text can include newlines.
230
+ line = 0
231
+ # Iterate through each character.
232
+ text.split("").each{|char|#Bit of a hacky way to do it but 🤷
233
+ # Advance to next line if character is a new line.
234
+ if(char == "\n")
235
+ line += 1
236
+ # Move to left or right side depending on text direction.
237
+ if (@_displaymode & LCD_ENTRYLEFT )> 0
238
+ col = 0
239
+ else
240
+ @_cols-1
241
+ end
242
+ set_cursor(col, line)
243
+ # Write the character to the display.
244
+ else
245
+ write8(char.ord, true)
246
+ end
247
+ }
248
+ end
249
+ def set_backlight(backlight)
250
+ #Enable or disable the backlight. If PWM is not enabled (default), a
251
+ #non-zero backlight value will turn on the backlight and a zero value will
252
+ #turn it off. If PWM is enabled, backlight can be any value from 0.0 to
253
+ #1.0, with 1.0 being full intensity backlight.
254
+ if @_backlight !=nil
255
+ if @_pwm_enabled
256
+ @_backlightPWM=_pwm_duty_cycle(backlight)
257
+ else
258
+ puts backlight
259
+ if(backlight>0)
260
+ RPi::GPIO.set_high @_backlight
261
+ else
262
+ RPi::GPIO.set_low @_backlight
263
+ end
264
+ end
265
+ end
266
+ end
267
+ def write8(value, char_mode=false)
268
+ #Write 8-bit value in character or data mode. Value should be an int
269
+ #value from 0-255, and char_mode is true if character data or false if
270
+ #non-character data (default).
271
+ # One millisecond delay to prevent writing too quickly.
272
+ sleep(0.001)
273
+ # Set character / data bit.
274
+ if(char_mode)
275
+ RPi::GPIO.set_high @_rs
276
+ else
277
+ RPi::GPIO.set_low @_rs
278
+ end
279
+ # Write upper 4 bits.
280
+ {@_d4=>4,@_d5=>5,@_d6=>6,@_d7=>7}.each{|pin,bit|#This is super jankey, but it should work
281
+ if((value>>bit)& 1)>0
282
+ RPi::GPIO.set_high pin
283
+ else
284
+ RPi::GPIO.set_low pin
285
+ end
286
+ }
287
+ #RPi::GPIO.output([@_d4,@_d5,@_d6,@_d7],
288
+ # ((value >> 4) & 1) > 0,
289
+ # ((value >> 5) & 1) > 0,
290
+ # ((value >> 6) & 1) > 0,
291
+ # ((value >> 7) & 1) > 0)
292
+ #RPi::GPIO.output_pins({ @_d4: ((value >> 4) & 1) > 0,
293
+ # @_d5: ((value >> 5) & 1) > 0,
294
+ # @_d6: ((value >> 6) & 1) > 0,
295
+ # @_d7: ((value >> 7) & 1) > 0 })
296
+ _pulse_enable()
297
+ # Write lower 4 bits.
298
+ {@_d4=>0,@_d5=>1,@_d6=>2,@_d7=>3}.each{|pin,bit|#This is super jankey, but it should work
299
+ if((value>>bit)&1)>0
300
+ RPi::GPIO.set_high pin
301
+ else
302
+ RPi::GPIO.set_low pin
303
+ end
304
+ }
305
+ #RPi::GPIO.output([@_d4,@_d5,@_d6,@_d7],
306
+ # (value & 1) > 0,
307
+ # ((value >> 1) & 1) > 0,
308
+ # ((value >> 2) & 1) > 0,
309
+ # ((value >> 3) & 1) > 0)
310
+ _pulse_enable()
311
+ end
312
+ def create_char(location, pattern)
313
+ #Fill one of the first 8 CGRAM locations with custom characters.
314
+ #The location parameter should be between 0 and 7 and pattern should
315
+ #provide an array of 8 bytes containing the pattern. E.g. you can easyly
316
+ #design your custom character at http://www.quinapalus.com/hd44780udg.html
317
+ #To show your custom character use eg. lcd.message('\x01')
318
+ # only position 0..7 are allowed
319
+ location &= 0x7
320
+ write8(LCD_SETCGRAMADDR | (location << 3))
321
+ (0..8).each{|i|
322
+ write8(pattern[i], true)
323
+ }
324
+ end
325
+ def _pulse_enable()
326
+ # Pulse the clock enable line off, on, off to send command.
327
+ RPi::GPIO.set_low @_en
328
+ sleep(0.000001) # 1 microsecond pause - enable pulse must be > 450ns
329
+ RPi::GPIO.set_high @_en
330
+ sleep(0.000001) # 1 microsecond pause - enable pulse must be > 450ns
331
+ RPi::GPIO.set_low @_en
332
+ sleep(0.000001) # commands need > 37us to settle
333
+ end
334
+ def _pwm_duty_cycle(intensity)
335
+ # Convert intensity value of 0.0 to 1.0 to a duty cycle of 0.0 to 100.0
336
+ intensity = 100.0*intensity
337
+ # Invert polarity if required.
338
+ if not @_blpol
339
+ intensity = 100.0-intensity
340
+ end
341
+ return intensity
342
+ end
343
+ end
344
+ #Not comfertable with this bit of code just yet ...
345
+ class Adafruit_RGBCharLCD < Adafruit_CharLCD
346
+ def initialize(rs, en, d4, d5, d6, d7, cols, lines, red, green, blue,
347
+ invert_polarity=True,
348
+ enable_pwm=False,
349
+ initial_color=[1.0, 1.0, 1.0])
350
+ # Initialize the LCD with RGB backlight. RS, EN, and D4...D7 parameters
351
+ # should be the pins connected to the LCD RS, clock enable, and data line
352
+ # 4 through 7 connections. The LCD will be used in its 4-bit mode so these
353
+ # 6 lines are the only ones required to use the LCD. You must also pass in
354
+ # the number of columns and lines on the LCD.
355
+ # The red, green, and blue parameters define the pins which are connected
356
+ # to the appropriate backlight LEDs. The invert_polarity parameter is a
357
+ # boolean that controls if the LEDs are on with a LOW or HIGH signal. By
358
+ # default invert_polarity is True, i.e. the backlight LEDs are on with a
359
+ # low signal. If you want to enable PWM on the backlight LEDs (for finer
360
+ # control of colors) and the hardware supports PWM on the provided pins,
361
+ # set enable_pwm to True. Finally you can set an explicit initial backlight
362
+ # color with the initial_color parameter. The default initial color is
363
+ # white (all LEDs lit).
364
+ # You can optionally pass in an explicit GPIO class,
365
+ # for example if you want to use an MCP230xx GPIO extender. If you don't
366
+ # pass in an GPIO instance, the default GPIO for the running platform will
367
+ # be used.
368
+
369
+ super(rs, en, d4, d5, d6, d7,cols,lines,false,invert_polarity,enable_pwm)
370
+ @_red = red
371
+ @_green = green
372
+ @_blue = blue
373
+ # Setup backlight pins.
374
+ [@_red, @_green, @_blue].each{|pin|
375
+ RPi::GPIO.setup pin, :as => :output, :initialize => :low
376
+ }
377
+ if enable_pwm
378
+ # Determine initial backlight duty cycles.
379
+ @_backlightPWM=[]
380
+ inital_color=_rgb_to_duty_cycle(inital_color)
381
+ {@_red=>initial_color[0], @_green=>initial_color[1], @_blue=>initial_color[2]}.each{|pin,color|
382
+ @_backlightPWM.push<<RPi::GPIO::PWM.new(pin, PWM_FREQUENCY)
383
+ @_backlightPWM[-1].start(color)
384
+ }
385
+ rdc, gdc, bdc = _rgb_to_duty_cycle(initial_color)
386
+ pwm.start(red, rdc)
387
+ pwm.start(green, gdc)
388
+ pwm.start(blue, bdc)
389
+ else
390
+ _rgb_to_pins(rgb).each{|pin,value|
391
+ if(value)
392
+ RPi::GPIO.set_high pin
393
+ end
394
+ }
395
+ end
396
+ end
397
+ def _rgb_to_duty_cycle(rgb)
398
+ # Convert tuple of RGB 0-1 values to tuple of duty cycles (0-100).
399
+ rgb.each{|color|
400
+ color=color.clamp(0.0,1.0)
401
+ color=_pwm_duty_cycle(color)
402
+ }
403
+ return rgb
404
+ end
405
+ def _rgb_to_pins(rgb)
406
+ # Convert tuple of RGB 0-1 values to dict of pin values.
407
+ retDict={}
408
+ {@_red=>rgb[0],@_green=>rgb[1],@_blue=>rgb[2]}.each{|pin,color|
409
+ if(color>0)#FIXME There has to be a more elegant way of doing this ...
410
+ retDict[pin]=@_blpol
411
+ else
412
+ retDict[pin]=!@_blpol
413
+ end
414
+ }
415
+ end
416
+ def set_color(red, green, blue)
417
+ # Set backlight color to provided red, green, and blue values. If PWM
418
+ # is enabled then color components can be values from 0.0 to 1.0, otherwise
419
+ # components should be zero for off and non-zero for on.
420
+ if @_pwm_enabled
421
+ # Set duty cycle of PWM pins.
422
+ rgb=_rgb_to_duty_cycle([red, green, blue])
423
+ for i in (0..2)
424
+ @_backlightPWM[i].duty_cycle=rgb[i]
425
+ end
426
+ else
427
+ # Set appropriate backlight pins based on polarity and enabled colors.
428
+ {@_red=>red,@_green=>green,@_blue=>blue}.each{|pin,value|
429
+ if value>0
430
+ RPi::GPIO.output(pin, @_blpol)
431
+ else
432
+ RPi::GPIO.output(pin,!@_blpol)
433
+ end
434
+ }
435
+ end
436
+ end
437
+ def set_backlight(backlight)
438
+ # Enable or disable the backlight. If PWM is not enabled (default), a
439
+ # non-zero backlight value will turn on the backlight and a zero value will
440
+ # turn it off. If PWM is enabled, backlight can be any value from 0.0 to
441
+ # 1.0, with 1.0 being full intensity backlight. On an RGB display this
442
+ # function will set the backlight to all white.
443
+ set_color(backlight, backlight, backlight)
444
+ end
445
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adafruit_charlcd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alex Maguire
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rpi_gpio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.3
27
+ description: A port of the Adafruit_Python_CharLCD Library
28
+ email: eva@rigel.moe
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/Adafruit_CharLCD.rb
34
+ homepage: http://rubygems.org/gems/Adafruit_CharLCD
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.2.2
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: CharLCD Library for Pi
58
+ test_files: []