@@ -103,6 +103,18 @@ def _set_bit(byte_value, position, val):
103
103
return ret
104
104
105
105
106
+ def _map (xval , in_min , in_max , out_min , out_max ):
107
+ # Affine transfer/map with constrained output.
108
+ outrange = float (out_max - out_min )
109
+ inrange = float (in_max - in_min )
110
+ ret = (xval - in_min ) * (outrange / inrange ) + out_min
111
+ if out_max > out_min :
112
+ ret = max (min (ret , out_max ), out_min )
113
+ else :
114
+ ret = max (min (ret , out_min ), out_max )
115
+ return ret
116
+
117
+
106
118
# pylint: disable-msg=too-many-instance-attributes
107
119
class Character_LCD :
108
120
"""Base class for character LCD."""
@@ -125,9 +137,7 @@ class Character_LCD:
125
137
126
138
"""
127
139
# pylint: disable-msg=too-many-arguments
128
- def __init__ (self , rs , en , d4 , d5 , d6 , d7 , columns , lines ,
129
- backlight_pin = None ,
130
- backlight_inverted = False
140
+ def __init__ (self , rs , en , d4 , d5 , d6 , d7 , columns , lines
131
141
):
132
142
133
143
self .columns = columns
@@ -139,33 +149,25 @@ def __init__(self, rs, en, d4, d5, d6, d7, columns, lines,
139
149
self .dl5 = d5
140
150
self .dl6 = d6
141
151
self .dl7 = d7
142
- # backlight pin
143
- self .backlight_pin = backlight_pin
144
- self .backlight_inverted = backlight_inverted
152
+
145
153
# set all pins as outputs
146
154
for pin in (rs , en , d4 , d5 , d6 , d7 ):
147
155
pin .direction = digitalio .Direction .OUTPUT
148
- # Setup backlight
149
- if backlight_pin is not None :
150
- self .backlight_pin .direction = digitalio .Direction .OUTPUT
151
- if backlight_inverted :
152
- self .backlight_pin .value = 0 # turn backlight on
153
- else :
154
- self .backlight_pin .value = 1 # turn backlight on
155
- # initialize the display
156
+
157
+ # Initialise the display
156
158
self ._write8 (0x33 )
157
159
self ._write8 (0x32 )
158
- # init. display control
160
+ # Initialise display control
159
161
self .displaycontrol = _LCD_DISPLAYON | _LCD_CURSOROFF | _LCD_BLINKOFF
160
- # init display function
162
+ # Initialise display function
161
163
self .displayfunction = _LCD_4BITMODE | _LCD_1LINE | _LCD_2LINE | _LCD_5X8DOTS
162
- # init display mode
164
+ # Initialise display mode
163
165
self .displaymode = _LCD_ENTRYLEFT | _LCD_ENTRYSHIFTDECREMENT
164
- # write to display control
166
+ # Write to displaycontrol
165
167
self ._write8 (_LCD_DISPLAYCONTROL | self .displaycontrol )
166
- # write displayfunction
168
+ # Write to displayfunction
167
169
self ._write8 (_LCD_FUNCTIONSET | self .displayfunction )
168
- # set the entry mode
170
+ # Set entry mode
169
171
self ._write8 (_LCD_ENTRYMODESET | self .displaymode )
170
172
self .clear ()
171
173
@@ -456,42 +458,6 @@ def _right_to_left(self):
456
458
self .displaymode &= ~ _LCD_ENTRYLEFT
457
459
self ._write8 (_LCD_ENTRYMODESET | self .displaymode )
458
460
459
- @property
460
- def backlight (self ):
461
- """Enable or disable backlight. True if backlight is on. False if backlight is off.
462
-
463
- The following example turns the backlight off, then displays, "Hello, world?", then turns
464
- the backlight on and displays, "Hello, world!"
465
-
466
- .. code-block:: python
467
-
468
- import time
469
- import board
470
- import busio
471
- import adafruit_character_lcd.character_lcd_mono as character_lcd
472
-
473
- i2c = busio.I2C(board.SCL, board.SDA)
474
-
475
- lcd = character_lcd.Character_LCD_I2C(i2c, 16, 2)
476
-
477
- lcd.backlight = False
478
- lcd.message = "Hello, world?"
479
- time.sleep(5)
480
- lcd.backlight = True
481
- lcd.message = "Hello, world!"
482
- time.sleep(5)
483
-
484
- """
485
- return self ._enable
486
-
487
- @backlight .setter
488
- def backlight (self , enable ):
489
- self ._enable = enable
490
- if enable and not self .backlight_inverted or not enable and self .backlight_inverted :
491
- self .backlight_pin .value = 1
492
- if enable and self .backlight_inverted or not enable and not self .backlight_inverted :
493
- self .backlight_pin .value = 0
494
-
495
461
def create_char (self , location , pattern ):
496
462
"""
497
463
Fill one of the first 8 CGRAM locations with custom characters.
@@ -545,6 +511,183 @@ def _pulse_enable(self):
545
511
# pylint: enable-msg=too-many-instance-attributes
546
512
547
513
514
+ # pylint: disable-msg=too-many-instance-attributes
515
+ class Character_LCD_Mono (Character_LCD ):
516
+ """Base class for character LCD."""
517
+ """
518
+ Interfaces with a character LCD
519
+ :param ~digitalio.DigitalInOut rs: The reset data line
520
+ :param ~digitalio.DigitalInOut en: The enable data line
521
+ :param ~digitalio.DigitalInOut d4: The data line 4
522
+ :param ~digitalio.DigitalInOut d5: The data line 5
523
+ :param ~digitalio.DigitalInOut d6: The data line 6
524
+ :param ~digitalio.DigitalInOut d7: The data line 7
525
+ :param columns: The columns on the charLCD
526
+ :param lines: The lines on the charLCD
527
+ :param ~digitalio.DigitalInOut backlight_pin: The backlight pin, usually
528
+ the last pin. Check with your datasheet
529
+ :param bool backlight_inverted: False if LCD is not inverted, i.e. backlight pin is connected
530
+ to common anode. True if LCD is inverted i.e. backlight pin is connected to common cathode.
531
+
532
+ """
533
+ # pylint: disable-msg=too-many-arguments
534
+ def __init__ (self , rs , en , d4 , d5 , d6 , d7 , columns , lines ,
535
+ backlight_pin = None , backlight_inverted = False ):
536
+ reset = rs
537
+ enable = en
538
+ db4 = d4
539
+ db5 = d5
540
+ db6 = d6
541
+ db7 = d7
542
+
543
+ # Backlight pin and inversion
544
+ self .backlight_pin = backlight_pin
545
+ self .backlight_inverted = backlight_inverted
546
+
547
+ # Setup backlight
548
+ if backlight_pin is not None :
549
+ self .backlight_pin .direction = digitalio .Direction .OUTPUT
550
+ if backlight_inverted :
551
+ self .backlight_pin .value = 0 # Turn inverted backlight on
552
+ else :
553
+ self .backlight_pin .value = 1 # Turn backlight on
554
+ super ().__init__ (reset , enable , db4 , db5 , db6 , db7 , columns , lines )
555
+ # pylint: enable-msg=too-many-arguments
556
+
557
+ @property
558
+ def backlight (self ):
559
+ """Enable or disable backlight. True if backlight is on. False if backlight is off.
560
+
561
+ The following example turns the backlight off, then displays, "Hello, world?", then turns
562
+ the backlight on and displays, "Hello, world!"
563
+
564
+ .. code-block:: python
565
+
566
+ import time
567
+ import board
568
+ import busio
569
+ import adafruit_character_lcd.character_lcd_mono as character_lcd
570
+
571
+ i2c = busio.I2C(board.SCL, board.SDA)
572
+
573
+ lcd = character_lcd.Character_LCD_I2C(i2c, 16, 2)
574
+
575
+ lcd.backlight = False
576
+ lcd.message = "Hello, world?"
577
+ time.sleep(5)
578
+ lcd.backlight = True
579
+ lcd.message = "Hello, world!"
580
+ time.sleep(5)
581
+
582
+ """
583
+ return self ._enable
584
+
585
+ @backlight .setter
586
+ def backlight (self , enable ):
587
+ self ._enable = enable
588
+ if enable and not self .backlight_inverted or not enable and self .backlight_inverted :
589
+ self .backlight_pin .value = 1
590
+ if enable and self .backlight_inverted or not enable and not self .backlight_inverted :
591
+ self .backlight_pin .value = 0
592
+
593
+
594
+ class Character_LCD_RGB (Character_LCD ):
595
+ """Base class for RGB character LCD."""
596
+
597
+ """ Interfaces with an RGB character LCD
598
+ :param ~digitalio.DigitalInOut rs: The reset data line
599
+ :param ~digitalio.DigitalInOut en: The enable data line
600
+ :param ~digitalio.DigitalInOut d4: The data line 4
601
+ :param ~digitalio.DigitalInOut d5: The data line 5
602
+ :param ~digitalio.DigitalInOut d6: The data line 6
603
+ :param ~digitalio.DigitalInOut d7: The data line 7
604
+ :param columns: The columns on the charLCD
605
+ :param lines: The lines on the charLCD
606
+ :param ~pulseio.PWMOut, ~digitalio.DigitalInOut red: Red RGB Anode
607
+ :param ~pulseio.PWMOut, ~digitalio.DigitalInOut green: Green RGB Anode
608
+ :param ~pulseio.PWMOut, ~digitalio.DigitalInOut blue: Blue RGB Anode
609
+ :param ~digitalio.DigitalInOut read_write: The rw pin. Determines whether to read to or
610
+ write from the display. Not necessary if only writing to the display. Used on shield.
611
+
612
+ """
613
+ # pylint: disable-msg=too-many-arguments
614
+ def __init__ (self , rs , en , d4 , d5 , d6 , d7 , columns , lines , red , green , blue , read_write = None ):
615
+ reset = rs
616
+ enable = en
617
+ db4 = d4
618
+ db5 = d5
619
+ db6 = d6
620
+ db7 = d7
621
+
622
+ # Define read_write (rw) pin
623
+ self .read_write = read_write
624
+
625
+ # Setup rw pin if used
626
+ if read_write is not None :
627
+ self .read_write .direction = digitalio .Direction .OUTPUT
628
+
629
+ # define color params
630
+ self .red = red
631
+ self .green = green
632
+ self .blue = blue
633
+ self .rgb_led = [red , green , blue ]
634
+
635
+ for pin in self .rgb_led :
636
+ if hasattr (pin , 'direction' ):
637
+ # Assume a digitalio.DigitalInOut or compatible interface:
638
+ pin .direction = digitalio .Direction .OUTPUT
639
+ elif not hasattr (pin , 'duty_cycle' ):
640
+ raise TypeError (
641
+ 'RGB LED objects must be instances of digitalio.DigitalInOut'
642
+ ' or pulseio.PWMOut, or provide a compatible interface.'
643
+ )
644
+
645
+ self ._color = [0 , 0 , 0 ]
646
+ super ().__init__ (reset , enable , db4 , db5 , db6 , db7 , columns , lines )
647
+
648
+ @property
649
+ def color (self ):
650
+ """
651
+ The color of the display. Provide a list of three integers ranging 0 - 100, ``[R, G, B]``.
652
+ ``0`` is no color, or "off". ``100`` is maximum color. For example, the brightest red would
653
+ be ``[100, 0, 0]``, and a half-bright purple would be, ``[50, 0, 50]``.
654
+
655
+ If PWM is unavailable, ``0`` is off, and non-zero is on. For example, ``[1, 0, 0]`` would
656
+ be red.
657
+
658
+ The following example turns the LCD red and displays, "Hello, world!".
659
+
660
+ .. code-block:: python
661
+
662
+ import time
663
+ import board
664
+ import busio
665
+ import adafruit_character_lcd.character_lcd_rgb as character_lcd
666
+
667
+ i2c = busio.I2C(board.SCL, board.SDA)
668
+
669
+ lcd = character_lcd.Character_LCD_I2C_RGB(i2c, 16, 2)
670
+
671
+ lcd.color = [100, 0, 0]
672
+ lcd.message = "Hello, world!"
673
+ time.sleep(5)
674
+ """
675
+ return self ._color
676
+
677
+ @color .setter
678
+ def color (self , color ):
679
+ self ._color = color
680
+ for number , pin in enumerate (self .rgb_led ):
681
+ if hasattr (pin , 'duty_cycle' ):
682
+ # Assume a pulseio.PWMOut or compatible interface and set duty cycle:
683
+ pin .duty_cycle = int (_map (color [number ], 0 , 100 , 65535 , 0 ))
684
+ elif hasattr (pin , 'value' ):
685
+ # If we don't have a PWM interface, all we can do is turn each color
686
+ # on / off. Assume a DigitalInOut (or compatible interface) and write
687
+ # 0 (on) to pin for any value greater than 0, or 1 (off) for 0:
688
+ pin .value = 0 if color [number ] > 0 else 1
689
+
690
+
548
691
class Character_LCD_I2C (Character_LCD ):
549
692
"""Character LCD connected to I2C/SPI backpack using its I2C connection.
550
693
This is a subclass of Character_LCD and implements all of the same
0 commit comments