/ adafruit_pcd8544.py
adafruit_pcd8544.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2018 Tony DiCola, ladyada for Adafruit Industries 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 """ 23 `adafruit_pcd8544` 24 ==================================================== 25 26 A display control library for Nokia 5110 PCD8544 monochrome displays 27 28 * Author(s): ladyada 29 30 Implementation Notes 31 -------------------- 32 33 **Hardware:** 34 35 * `Nokia 5110 PCD8544 Display <https://www.adafruit.com/product/338>`_ 36 37 **Software and Dependencies:** 38 39 * Adafruit CircuitPython firmware for the supported boards: 40 https://github.com/adafruit/circuitpython/releases 41 42 * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 43 44 """ 45 46 import time 47 from micropython import const 48 from adafruit_bus_device import spi_device 49 50 try: 51 import framebuf 52 except ImportError: 53 import adafruit_framebuf as framebuf 54 55 __version__ = "0.0.0-auto.0" 56 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PCD8544.git" 57 58 _LCDWIDTH = const(84) 59 _LCDHEIGHT = const(48) 60 _PCD8544_POWERDOWN = const(0x04) 61 _PCD8544_ENTRYMODE = const(0x02) 62 _PCD8544_EXTENDEDINSTRUCTION = const(0x01) 63 _PCD8544_DISPLAYBLANK = const(0x0) 64 _PCD8544_DISPLAYNORMAL = const(0x4) 65 _PCD8544_DISPLAYALLON = const(0x1) 66 _PCD8544_DISPLAYINVERTED = const(0x5) 67 _PCD8544_FUNCTIONSET = const(0x20) 68 _PCD8544_DISPLAYCONTROL = const(0x08) 69 _PCD8544_SETYADDR = const(0x40) 70 _PCD8544_SETXADDR = const(0x80) 71 _PCD8544_SETTEMP = const(0x04) 72 _PCD8544_SETBIAS = const(0x10) 73 _PCD8544_SETVOP = const(0x80) 74 75 76 class PCD8544(framebuf.FrameBuffer): 77 """Nokia 5110/3310 PCD8544-based LCD display.""" 78 79 # pylint: disable=too-many-instance-attributes 80 81 def __init__( 82 self, 83 spi, 84 dc_pin, 85 cs_pin, 86 reset_pin=None, 87 *, 88 contrast=80, 89 bias=4, 90 baudrate=1000000 91 ): 92 self._dc_pin = dc_pin 93 dc_pin.switch_to_output(value=False) 94 95 self.spi_device = spi_device.SPIDevice(spi, cs_pin, baudrate=baudrate) 96 97 self._reset_pin = reset_pin 98 if reset_pin: 99 reset_pin.switch_to_output(value=True) 100 101 self.buffer = bytearray((_LCDHEIGHT // 8) * _LCDWIDTH) 102 super().__init__(self.buffer, _LCDWIDTH, _LCDHEIGHT) 103 104 self._contrast = None 105 self._bias = None 106 self._invert = False 107 108 self.reset() 109 # Set LCD bias. 110 self.bias = bias 111 self.contrast = contrast 112 113 def reset(self): 114 """Reset the display""" 115 if self._reset_pin: 116 # Toggle RST low to reset. 117 self._reset_pin.value = False 118 time.sleep(0.5) 119 self._reset_pin.value = True 120 time.sleep(0.5) 121 122 def write_cmd(self, cmd): 123 """Send a command to the SPI device""" 124 self._dc_pin.value = 0 125 with self.spi_device as spi: 126 spi.write(bytearray([cmd])) # pylint: disable=no-member 127 128 def extended_command(self, cmd): 129 """Send a command in extended mode""" 130 # Set extended command mode 131 self.write_cmd(_PCD8544_FUNCTIONSET | _PCD8544_EXTENDEDINSTRUCTION) 132 self.write_cmd(cmd) 133 # Set normal display mode. 134 self.write_cmd(_PCD8544_FUNCTIONSET) 135 self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYNORMAL) 136 137 def show(self): 138 """write out the frame buffer via SPI""" 139 self.write_cmd(_PCD8544_SETYADDR) 140 self.write_cmd(_PCD8544_SETXADDR) 141 self._dc_pin.value = True 142 with self.spi_device as spi: 143 spi.write(self.buffer) # pylint: disable=no-member 144 145 @property 146 def invert(self): 147 """Whether the display is inverted, cached value""" 148 return self._invert 149 150 @invert.setter 151 def invert(self, val): 152 """Set invert on or normal display on""" 153 self._invert = val 154 self.write_cmd(_PCD8544_FUNCTIONSET) 155 if val: 156 self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYINVERTED) 157 else: 158 self.write_cmd(_PCD8544_DISPLAYCONTROL | _PCD8544_DISPLAYNORMAL) 159 160 @property 161 def contrast(self): 162 """The cached contrast value""" 163 return self._contrast 164 165 @contrast.setter 166 def contrast(self, val): 167 """Set contrast to specified value (should be 0-127).""" 168 self._contrast = max(0, min(val, 0x7F)) # Clamp to values 0-0x7f 169 self.extended_command(_PCD8544_SETVOP | self._contrast) 170 171 @property 172 def bias(self): 173 """The cached bias value""" 174 return self._bias 175 176 @bias.setter 177 def bias(self, val): 178 """Set display bias""" 179 self._bias = val 180 self.extended_command(_PCD8544_SETBIAS | self._bias)