├── .gitignore ├── LICENSE.txt ├── README.md ├── docs └── demo.jpg ├── epaper1in54.py ├── epaper1in54b.py ├── epaper2in13.py ├── epaper2in13b.py ├── epaper2in7.py ├── epaper2in7b.py ├── epaper2in9.py ├── epaper2in9b.py ├── epaper4in2.py ├── epaper4in2b.py ├── epaper5in83.py ├── epaper5in83b.py ├── epaper7in5.py ├── epaper7in5b.py └── examples ├── 2in9-hello-world ├── hello-world-white.bmp ├── hello-world-white.png ├── hello-world.bmp ├── hello-world.png ├── image_dark.py ├── image_light.py └── test.py └── 4in2-hello-world ├── image_dark.py ├── image_light.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | temp/ -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Waveshare 4 | Copyright (c) 2018 Mike Causer 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 all 14 | 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 THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroPython Waveshare e-Paper 2 | 3 | MicroPython drivers for various Waveshare e-Paper displays, based on the original Waveshare Raspberry Pi examples found in the [wiki](https://www.waveshare.com/wiki/Main_Page). 4 | 5 | ![demo](docs/demo.jpg) 6 | 7 | | Waveshare e-Paper Module | Colors | Grey Level | Resolution px | Display mm | Outline mm | Partial Refresh | Full Refresh | Interface | Pi Header | Controller | Display | 8 | | ----------------------------------------------------------------------------------------- | -------------------- |:----------:|:-------------:|:--------------:|:-------------:|:---------------:|:------------:|:---------:|:---------:|:-----------|:-----------------------------------------------------------------------------:| 9 | | [1.54inch e-Paper Module](https://www.waveshare.com/wiki/1.54inch_e-Paper_Module) | Black, White | 2 | 200 × 200 | 27.60 × 27.60 | 48.0 × 33.0 | 0.3 | 2 | SPI | No | ? | [GDEH0154D27](http://www.good-display.com/products_detail/productId=365.html) | 10 | | [1.54inch e-Paper Module (B)](https://www.waveshare.com/wiki/1.54inch_e-Paper_Module_(B)) | Black, White, Red | 2 | 200 × 200 | 27.60 × 27.60 | 48.0 × 33.0 | N/A | 8 | SPI | No | ? | [GDEW0154Z04](http://www.good-display.com/products_detail/productId=307.html) | 11 | | [1.54inch e-Paper Module (C)](https://www.waveshare.com/wiki/1.54inch_e-Paper_Module_(C)) | Black, White, Yellow | 2 | 152 × 152 | 27.51 × 27.51 | 48.0 × 33.0 | N/A | 27 | SPI | No | ? | [GDEW0154C39](http://www.good-display.com/products_detail/productId=385.html) | 12 | | [2.13inch e-Paper HAT](https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT) | Black, White | 2 | 250 × 122 | 48.55 × 23.71 | 65.0 × 30.2 | 0.3 | 2 | SPI | Yes | IL3895 | [GDEH0213B1](http://www.good-display.com/products_detail/productId=346.html) | 13 | | [2.13inch e-Paper HAT (B)](https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT_(B)) | Black, White, Red | 2 | 212 × 104 | 48.55 × 23.71 | 65.0 × 30.2 | N/A | 15 | SPI | Yes | ? | [GDEW0213Z16](http://www.good-display.com/products_detail/productId=310.html) | 14 | | [2.13inch e-Paper HAT (C)](https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT_(C)) | Black, White, Yellow | 2 | 212 × 104 | 48.55 × 23.71 | 65.0 × 30.2 | N/A | 15 | SPI | Yes | ? | [GDEW0213C38](http://www.good-display.com/products_detail/productId=380.html) | 15 | | [2.7inch e-Paper HAT](https://www.waveshare.com/wiki/2.7inch_e-Paper_HAT) | Black, White | 2 | 264 × 176 | 57.29 × 38.19 | 85.0 × 56.0 | N/A | 6 | SPI | Yes | ? | [GDEW027W3](http://www.good-display.com/products_detail/productId=319.html) | 16 | | [2.7inch e-Paper HAT (B)](https://www.waveshare.com/wiki/2.7inch_e-Paper_HAT_(B)) | Black, White, Red | 2 | 264 × 176 | 57.29 × 38.19 | 85.0 × 56.0 | N/A | 15 | SPI | Yes | ? | [GDEW027C44](http://www.good-display.com/products_detail/productId=320.html) | 17 | | [2.9inch e-Paper Module](https://www.waveshare.com/wiki/2.9inch_e-Paper_Module) | Black, White | 2 | 296 × 128 | 66.89 × 29.05 | 89.5 × 38.0 | 0.3 | 2 | SPI | No | IL3820 | [GDEH029A1](http://www.good-display.com/products_detail/productId=251.html) | 18 | | [2.9inch e-Paper Module (B)](https://www.waveshare.com/wiki/2.9inch_e-Paper_Module_(B)) | Black, White, Red | 2 | 296 × 128 | 66.89 × 29.05 | 89.5 × 38.0 | N/A | 15 | SPI | No | IL3820? | [GDEW029Z10](http://www.good-display.com/products_detail/productId=308.html) | 19 | | [2.9inch e-Paper Module (C)](https://www.waveshare.com/wiki/2.9inch_e-Paper_Module_(C)) | Black, White, Yellow | 2 | 296 × 128 | 66.89 × 29.05 | 89.5 × 38.0 | N/A | 15 | SPI | No | IL3820? | [GDEW029C32](http://www.good-display.com/products_detail/productId=378.html) | 20 | | [4.2inch e-Paper Module](https://www.waveshare.com/wiki/4.2inch_e-Paper_Module) | Black, White | 2 | 400 × 300 | 84.80 × 63.60 | 103.0 × 78.5 | N/A | 4 | SPI | No | ? | [GDEW042T2](http://www.good-display.com/products_detail/productId=321.html) | 21 | | [4.2inch e-Paper Module (B)](https://www.waveshare.com/wiki/4.2inch_e-Paper_Module_(B)) | Black, White, Red | 2 | 400 × 300 | 84.80 × 63.60 | 103.0 × 78.5 | N/A | 15 | SPI | No | ? | [GDEW042Z15](http://www.good-display.com/products_detail/productId=322.html) | 22 | | [4.2inch e-Paper Module (C)](https://www.waveshare.com/wiki/4.2inch_e-Paper_Module_(C)) | Black, White, Yellow | 2 | 400 × 300 | 84.80 × 63.60 | 103.0 × 78.5 | N/A | 15 | SPI | No | ? | [GDEW042C37](http://www.good-display.com/products_detail/productId=379.html) | 23 | | [4.3inch e-Paper UART Module](https://www.waveshare.com/wiki/4.3inch_e-Paper_UART_Module) | Black, White | 4 | 800 × 600 | 88.00 × 66.00 | 118.0 × 75.0 | N/A | 1.5 | UART | No | ? | [GDE043A2](http://www.good-display.com/products_detail/productId=361.html) | 24 | | [5.83inch e-Paper HAT](https://www.waveshare.com/wiki/5.83inch_e-Paper_HAT) | Black, White | 2 | 600 × 448 | 118.8 × 88.26 | 125.4 × 99.5 | N/A | 3.5 | SPI | Yes | ? | [GDEW0583T7](http://www.good-display.com/products_detail/productId=387.html) | 25 | | [5.83inch e-Paper HAT (B)](https://www.waveshare.com/wiki/5.83inch_e-Paper_HAT_(B)) | Black, White, Red | 2 | 600 × 448 | 118.8 × 88.26 | 125.4 × 99.5 | N/A | 14 | SPI | Yes | ? | [GDEW0583Z21](http://www.good-display.com/products_detail/productId=383.html) | 26 | | [5.83inch e-Paper HAT (C)](https://www.waveshare.com/wiki/5.83inch_e-Paper_HAT_(C)) | Black, White, Yellow | 2 | 600 × 448 | 118.8 × 88.26 | 125.4 × 99.5 | N/A | 26 | SPI | Yes | ? | [GDEW0583C64](http://www.good-display.com/products_detail/productId=388.html) | 27 | | [7.5inch e-Paper HAT](https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT) | Black, White | 2 | 600 × 384 | 163.20 × 97.92 | 170.2 × 111.2 | N/A | 6 | SPI | Yes | ? | [GDEW075T8](http://www.good-display.com/products_detail/productId=323.html) | 28 | | [7.5inch e-Paper HAT (B)](https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(B)) | Black, White, Red | 2 | 640 × 384 | 163.20 × 97.92 | 170.2 × 111.2 | N/A | 31 | SPI | Yes | ? | [GDEW075Z09](http://www.good-display.com/products_detail/productId=324.html) | 29 | | [7.5inch e-Paper HAT (C)](https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(C)) | Black, White, Yellow | 2 | 640 × 384 | 163.20 × 97.92 | 170.2 × 111.2 | N/A | 31 | SPI | Yes | ? | [GDEW075C21](http://www.good-display.com/products_detail/productId=381.html) | 30 | 31 | ## Links 32 | 33 | * [Waveshare Wiki](https://www.waveshare.com/wiki/Main_Page) 34 | * [micropython.org](http://micropython.org) 35 | * [Docs on framebuf](http://docs.micropython.org/en/latest/pyboard/library/framebuf.html) 36 | 37 | ## License 38 | 39 | Licensed under the [MIT License](http://opensource.org/licenses/MIT). 40 | -------------------------------------------------------------------------------- /docs/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcauser/micropython-waveshare-epaper/24c454cdd004c273d8dc3349ec365e87dec371ea/docs/demo.jpg -------------------------------------------------------------------------------- /epaper1in54.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 1.54" Black/White GDEH0154D27 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(200) 34 | EPD_HEIGHT = const(200) 35 | 36 | # Display commands 37 | DRIVER_OUTPUT_CONTROL = const(0x01) 38 | BOOSTER_SOFT_START_CONTROL = const(0x0C) 39 | #GATE_SCAN_START_POSITION = const(0x0F) 40 | DEEP_SLEEP_MODE = const(0x10) 41 | DATA_ENTRY_MODE_SETTING = const(0x11) 42 | #SW_RESET = const(0x12) 43 | #TEMPERATURE_SENSOR_CONTROL = const(0x1A) 44 | MASTER_ACTIVATION = const(0x20) 45 | #DISPLAY_UPDATE_CONTROL_1 = const(0x21) 46 | DISPLAY_UPDATE_CONTROL_2 = const(0x22) 47 | WRITE_RAM = const(0x24) 48 | WRITE_VCOM_REGISTER = const(0x2C) 49 | WRITE_LUT_REGISTER = const(0x32) 50 | SET_DUMMY_LINE_PERIOD = const(0x3A) 51 | SET_GATE_TIME = const(0x3B) # not in datasheet 52 | #BORDER_WAVEFORM_CONTROL = const(0x3C) 53 | SET_RAM_X_ADDRESS_START_END_POSITION = const(0x44) 54 | SET_RAM_Y_ADDRESS_START_END_POSITION = const(0x45) 55 | SET_RAM_X_ADDRESS_COUNTER = const(0x4E) 56 | SET_RAM_Y_ADDRESS_COUNTER = const(0x4F) 57 | TERMINATE_FRAME_READ_WRITE = const(0xFF) # aka NOOP 58 | 59 | BUSY = const(1) # 1=busy, 0=idle 60 | 61 | class EPD: 62 | def __init__(self, spi, cs, dc, rst, busy): 63 | self.spi = spi 64 | self.cs = cs 65 | self.dc = dc 66 | self.rst = rst 67 | self.busy = busy 68 | self.cs.init(self.cs.OUT, value=1) 69 | self.dc.init(self.dc.OUT, value=0) 70 | self.rst.init(self.rst.OUT, value=0) 71 | self.busy.init(self.busy.IN) 72 | self.width = EPD_WIDTH 73 | self.height = EPD_HEIGHT 74 | 75 | LUT_FULL_UPDATE = bytearray(b'\x02\x02\x01\x11\x12\x12\x22\x22\x66\x69\x69\x59\x58\x99\x99\x88\x00\x00\x00\x00\xF8\xB4\x13\x51\x35\x51\x51\x19\x01\x00') 76 | LUT_PARTIAL_UPDATE = bytearray(b'\x10\x18\x18\x08\x18\x18\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x14\x44\x12\x00\x00\x00\x00\x00\x00') 77 | 78 | def _command(self, command, data=None): 79 | self.dc(0) 80 | self.cs(0) 81 | self.spi.write(bytearray([command])) 82 | self.cs(1) 83 | if data is not None: 84 | self._data(data) 85 | 86 | def _data(self, data): 87 | self.dc(1) 88 | self.cs(0) 89 | self.spi.write(data) 90 | self.cs(1) 91 | 92 | def init(self): 93 | self.reset() 94 | self._command(DRIVER_OUTPUT_CONTROL) 95 | self._data(bytearray([(EPD_HEIGHT - 1) & 0xFF])) 96 | self._data(bytearray([((EPD_HEIGHT - 1) >> 8) & 0xFF])) 97 | self._data(bytearray([0x00])) # GD = 0 SM = 0 TB = 0 98 | self._command(BOOSTER_SOFT_START_CONTROL, b'\xD7\xD6\x9D') 99 | self._command(WRITE_VCOM_REGISTER, b'\xA8') # VCOM 7C 100 | self._command(SET_DUMMY_LINE_PERIOD, b'\x1A') # 4 dummy lines per gate 101 | self._command(SET_GATE_TIME, b'\x08') # 2us per line 102 | self._command(DATA_ENTRY_MODE_SETTING, b'\x03') # X increment Y increment 103 | self.set_lut(self.LUT_FULL_UPDATE) 104 | 105 | def wait_until_idle(self): 106 | while self.busy.value() == BUSY: 107 | sleep_ms(100) 108 | 109 | def reset(self): 110 | self.rst(0) 111 | sleep_ms(200) 112 | self.rst(1) 113 | sleep_ms(200) 114 | 115 | def set_lut(self, lut): 116 | self._command(WRITE_LUT_REGISTER, lut) 117 | 118 | # put an image in the frame memory 119 | def set_frame_memory(self, image, x, y, w, h): 120 | # x point must be the multiple of 8 or the last 3 bits will be ignored 121 | x = x & 0xF8 122 | w = w & 0xF8 123 | 124 | if (x + w >= self.width): 125 | x_end = self.width - 1 126 | else: 127 | x_end = x + w - 1 128 | 129 | if (y + h >= self.height): 130 | y_end = self.height - 1 131 | else: 132 | y_end = y + h - 1 133 | 134 | self.set_memory_area(x, y, x_end, y_end) 135 | self.set_memory_pointer(x, y) 136 | self._command(WRITE_RAM, image) 137 | 138 | # replace the frame memory with the specified color 139 | def clear_frame_memory(self, color): 140 | self.set_memory_area(0, 0, self.width - 1, self.height - 1) 141 | self.set_memory_pointer(0, 0) 142 | self._command(WRITE_RAM) 143 | # send the color data 144 | for i in range(0, self.width // 8 * self.height): 145 | self._data(bytearray([color])) 146 | 147 | # draw the current frame memory and switch to the next memory area 148 | def display_frame(self): 149 | self._command(DISPLAY_UPDATE_CONTROL_2, b'\xC4') 150 | self._command(MASTER_ACTIVATION) 151 | self._command(TERMINATE_FRAME_READ_WRITE) 152 | self.wait_until_idle() 153 | 154 | # specify the memory area for data R/W 155 | def set_memory_area(self, x_start, y_start, x_end, y_end): 156 | self._command(SET_RAM_X_ADDRESS_START_END_POSITION) 157 | # x point must be the multiple of 8 or the last 3 bits will be ignored 158 | self._data(bytearray([(x_start >> 3) & 0xFF])) 159 | self._data(bytearray([(x_end >> 3) & 0xFF])) 160 | self._command(SET_RAM_Y_ADDRESS_START_END_POSITION, ustruct.pack("> 3) & 0xFF])) 167 | self._command(SET_RAM_Y_ADDRESS_COUNTER, ustruct.pack("BH", EPD_WIDTH, EPD_HEIGHT)) 134 | self._command(VCM_DC_SETTING_REGISTER, b'\x0E') # -1.4V 135 | self.set_lut_bw() 136 | self.set_lut_red() 137 | 138 | def wait_until_idle(self): 139 | while self.busy.value() == BUSY: 140 | sleep_ms(100) 141 | 142 | def reset(self): 143 | self.rst(0) 144 | sleep_ms(200) 145 | self.rst(1) 146 | sleep_ms(200) 147 | 148 | def set_lut_bw(self): 149 | self._command(VCOM_LUT, self.LUT_VCOM0) # vcom 150 | self._command(W2W_LUT, self.LUT_W) # ww -- 151 | self._command(B2W_LUT, self.LUT_B) # bw r 152 | self._command(W2B_LUT, self.LUT_G1) # wb w 153 | self._command(B2B_LUT, self.LUT_G2) # bb b 154 | 155 | def set_lut_red(self): 156 | self._command(LUT_RED_0, self.LUT_VCOM1) 157 | self._command(LUT_RED_1, self.LUT_RED0) 158 | self._command(LUT_RED_2, self.LUT_RED1) 159 | 160 | def display_frame(self, frame_buffer_black, frame_buffer_red): 161 | if (frame_buffer_black != None): 162 | self._command(DATA_START_TRANSMISSION_1) 163 | sleep_ms(2) 164 | for i in range(0, self.width * self.height // 8): 165 | temp = 0x00 166 | for bit in range(0, 4): 167 | if (frame_buffer_black[i] & (0x80 >> bit) != 0): 168 | temp |= 0xC0 >> (bit * 2) 169 | self._data(bytearray([temp])) 170 | temp = 0x00 171 | for bit in range(4, 8): 172 | if (frame_buffer_black[i] & (0x80 >> bit) != 0): 173 | temp |= 0xC0 >> ((bit - 4) * 2) 174 | self._data(bytearray([temp])) 175 | sleep_ms(2) 176 | if (frame_buffer_red != None): 177 | self._command(DATA_START_TRANSMISSION_2) 178 | sleep_ms(2) 179 | for i in range(0, self.width * self.height // 8): 180 | self._data(bytearray([frame_buffer_red[i]])) 181 | sleep_ms(2) 182 | 183 | self._command(DISPLAY_REFRESH) 184 | self.wait_until_idle() 185 | 186 | def set_rotate(self, rotate): 187 | if (rotate == ROTATE_0): 188 | self.rotate = ROTATE_0 189 | self.width = EPD_WIDTH 190 | self.height = EPD_HEIGHT 191 | elif (rotate == ROTATE_90): 192 | self.rotate = ROTATE_90 193 | self.width = EPD_HEIGHT 194 | self.height = EPD_WIDTH 195 | elif (rotate == ROTATE_180): 196 | self.rotate = ROTATE_180 197 | self.width = EPD_WIDTH 198 | self.height = EPD_HEIGHT 199 | elif (rotate == ROTATE_270): 200 | self.rotate = ROTATE_270 201 | self.width = EPD_HEIGHT 202 | self.height = EPD_WIDTH 203 | 204 | def set_pixel(self, frame_buffer, x, y, colored): 205 | if (x < 0 or x >= self.width or y < 0 or y >= self.height): 206 | return 207 | if (self.rotate == ROTATE_0): 208 | self.set_absolute_pixel(frame_buffer, x, y, colored) 209 | elif (self.rotate == ROTATE_90): 210 | point_temp = x 211 | x = EPD_WIDTH - y 212 | y = point_temp 213 | self.set_absolute_pixel(frame_buffer, x, y, colored) 214 | elif (self.rotate == ROTATE_180): 215 | x = EPD_WIDTH - x 216 | y = EPD_HEIGHT- y 217 | self.set_absolute_pixel(frame_buffer, x, y, colored) 218 | elif (self.rotate == ROTATE_270): 219 | point_temp = x 220 | x = y 221 | y = EPD_HEIGHT - point_temp 222 | self.set_absolute_pixel(frame_buffer, x, y, colored) 223 | 224 | def set_absolute_pixel(self, frame_buffer, x, y, colored): 225 | # To avoid display orientation effects 226 | # use EPD_WIDTH instead of self.width 227 | # use EPD_HEIGHT instead of self.height 228 | if (x < 0 or x >= EPD_WIDTH or y < 0 or y >= EPD_HEIGHT): 229 | return 230 | if (colored): 231 | frame_buffer[(x + y * EPD_WIDTH) // 8] &= ~(0x80 >> (x % 8)) 232 | else: 233 | frame_buffer[(x + y * EPD_WIDTH) // 8] |= 0x80 >> (x % 8) 234 | 235 | def display_string_at(self, frame_buffer, x, y, text, font, colored): 236 | image = Image.new('1', (self.width, self.height)) 237 | draw = ImageDraw.Draw(image) 238 | draw.text((x, y), text, font = font, fill = 255) 239 | # Set buffer to value of Python Imaging Library image. 240 | # Image must be in mode 1. 241 | pixels = image.load() 242 | for y in range(self.height): 243 | for x in range(self.width): 244 | # Set the bits for the column of pixels at the current position. 245 | if pixels[x, y] != 0: 246 | self.set_pixel(frame_buffer, x, y, colored) 247 | 248 | def draw_line(self, frame_buffer, x0, y0, x1, y1, colored): 249 | # Bresenham algorithm 250 | dx = abs(x1 - x0) 251 | sx = 1 if x0 < x1 else -1 252 | dy = -abs(y1 - y0) 253 | sy = 1 if y0 < y1 else -1 254 | err = dx + dy 255 | while((x0 != x1) and (y0 != y1)): 256 | self.set_pixel(frame_buffer, x0, y0 , colored) 257 | if (2 * err >= dy): 258 | err += dy 259 | x0 += sx 260 | if (2 * err <= dx): 261 | err += dx 262 | y0 += sy 263 | 264 | def draw_horizontal_line(self, frame_buffer, x, y, width, colored): 265 | for i in range(x, x + width): 266 | self.set_pixel(frame_buffer, i, y, colored) 267 | 268 | def draw_vertical_line(self, frame_buffer, x, y, height, colored): 269 | for i in range(y, y + height): 270 | self.set_pixel(frame_buffer, x, i, colored) 271 | 272 | def draw_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 273 | min_x = x0 if x1 > x0 else x1 274 | max_x = x1 if x1 > x0 else x0 275 | min_y = y0 if y1 > y0 else y1 276 | max_y = y1 if y1 > y0 else y0 277 | self.draw_horizontal_line(frame_buffer, min_x, min_y, max_x - min_x + 1, colored) 278 | self.draw_horizontal_line(frame_buffer, min_x, max_y, max_x - min_x + 1, colored) 279 | self.draw_vertical_line(frame_buffer, min_x, min_y, max_y - min_y + 1, colored) 280 | self.draw_vertical_line(frame_buffer, max_x, min_y, max_y - min_y + 1, colored) 281 | 282 | def draw_filled_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 283 | min_x = x0 if x1 > x0 else x1 284 | max_x = x1 if x1 > x0 else x0 285 | min_y = y0 if y1 > y0 else y1 286 | max_y = y1 if y1 > y0 else y0 287 | for i in range(min_x, max_x + 1): 288 | self.draw_vertical_line(frame_buffer, i, min_y, max_y - min_y + 1, colored) 289 | 290 | def draw_circle(self, frame_buffer, x, y, radius, colored): 291 | # Bresenham algorithm 292 | x_pos = -radius 293 | y_pos = 0 294 | err = 2 - 2 * radius 295 | if (x >= self.width or y >= self.height): 296 | return 297 | while True: 298 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 299 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 300 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 301 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 302 | e2 = err 303 | if (e2 <= y_pos): 304 | y_pos += 1 305 | err += y_pos * 2 + 1 306 | if(-x_pos == y_pos and e2 <= x_pos): 307 | e2 = 0 308 | if (e2 > x_pos): 309 | x_pos += 1 310 | err += x_pos * 2 + 1 311 | if x_pos > 0: 312 | break 313 | 314 | def draw_filled_circle(self, frame_buffer, x, y, radius, colored): 315 | # Bresenham algorithm 316 | x_pos = -radius 317 | y_pos = 0 318 | err = 2 - 2 * radius 319 | if (x >= self.width or y >= self.height): 320 | return 321 | while True: 322 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 323 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 324 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 325 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 326 | self.draw_horizontal_line(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored) 327 | self.draw_horizontal_line(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored) 328 | e2 = err 329 | if (e2 <= y_pos): 330 | y_pos += 1 331 | err += y_pos * 2 + 1 332 | if(-x_pos == y_pos and e2 <= x_pos): 333 | e2 = 0 334 | if (e2 > x_pos): 335 | x_pos += 1 336 | err += x_pos * 2 + 1 337 | if x_pos > 0: 338 | break 339 | 340 | # to wake call reset() or init() 341 | def sleep(self): 342 | # TODO do we need to reset these here? 343 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x17') # for this panel, must be 0x17 344 | self._command(VCM_DC_SETTING_REGISTER, b'\x00') # to solve Vcom drop 345 | self._command(POWER_SETTING, b'\x02\x00\x00\x00') # gate switch to external 346 | # /TODO 347 | self.wait_until_idle() 348 | self._command(POWER_OFF) 349 | -------------------------------------------------------------------------------- /epaper2in13.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 2.13" Black/White GDEH0213B1 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(128) 34 | EPD_HEIGHT = const(250) 35 | # datasheet says 250x122 (increased to 128 to be multiples of 8) 36 | 37 | # Display commands 38 | DRIVER_OUTPUT_CONTROL = const(0x01) 39 | # Gate Driving Voltage Control 0x03 40 | # Source Driving voltage Control 0x04 41 | BOOSTER_SOFT_START_CONTROL = const(0x0C) # not in datasheet 42 | #GATE_SCAN_START_POSITION = const(0x0F) # not in datasheet 43 | DEEP_SLEEP_MODE = const(0x10) 44 | DATA_ENTRY_MODE_SETTING = const(0x11) 45 | #SW_RESET = const(0x12) 46 | #TEMPERATURE_SENSOR_CONTROL = const(0x1A) 47 | MASTER_ACTIVATION = const(0x20) 48 | #DISPLAY_UPDATE_CONTROL_1 = const(0x21) 49 | DISPLAY_UPDATE_CONTROL_2 = const(0x22) 50 | # Panel Break Detection 0x23 51 | WRITE_RAM = const(0x24) 52 | WRITE_VCOM_REGISTER = const(0x2C) 53 | # Status Bit Read 0x2F 54 | WRITE_LUT_REGISTER = const(0x32) 55 | SET_DUMMY_LINE_PERIOD = const(0x3A) 56 | SET_GATE_TIME = const(0x3B) 57 | #BORDER_WAVEFORM_CONTROL = const(0x3C) 58 | SET_RAM_X_ADDRESS_START_END_POSITION = const(0x44) 59 | SET_RAM_Y_ADDRESS_START_END_POSITION = const(0x45) 60 | SET_RAM_X_ADDRESS_COUNTER = const(0x4E) 61 | SET_RAM_Y_ADDRESS_COUNTER = const(0x4F) 62 | TERMINATE_FRAME_READ_WRITE = const(0xFF) # not in datasheet, aka NOOP 63 | 64 | BUSY = const(1) # 1=busy, 0=idle 65 | 66 | class EPD: 67 | def __init__(self, spi, cs, dc, rst, busy): 68 | self.spi = spi 69 | self.cs = cs 70 | self.dc = dc 71 | self.rst = rst 72 | self.busy = busy 73 | self.cs.init(self.cs.OUT, value=1) 74 | self.dc.init(self.dc.OUT, value=0) 75 | self.rst.init(self.rst.OUT, value=0) 76 | self.busy.init(self.busy.IN) 77 | self.width = EPD_WIDTH 78 | self.height = EPD_HEIGHT 79 | 80 | LUT_FULL_UPDATE = bytearray(b'\x22\x55\xAA\x55\xAA\x55\xAA\x11\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x01\x00\x00\x00\x00\x00') 81 | LUT_PARTIAL_UPDATE = bytearray(b'\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 82 | 83 | def _command(self, command, data=None): 84 | self.dc(0) 85 | self.cs(0) 86 | self.spi.write(bytearray([command])) 87 | self.cs(1) 88 | if data is not None: 89 | self._data(data) 90 | 91 | def _data(self, data): 92 | self.dc(1) 93 | self.cs(0) 94 | self.spi.write(data) 95 | self.cs(1) 96 | 97 | def init(self): 98 | self.reset() 99 | self._command(DRIVER_OUTPUT_CONTROL) 100 | self._data(bytearray([(EPD_HEIGHT - 1) & 0xFF])) 101 | self._data(bytearray([((EPD_HEIGHT - 1) >> 8) & 0xFF])) 102 | self._data(bytearray([0x00])) # GD = 0 SM = 0 TB = 0 103 | self._command(BOOSTER_SOFT_START_CONTROL, b'\xD7\xD6\x9D') 104 | self._command(WRITE_VCOM_REGISTER, b'\xA8') # VCOM 7C 105 | self._command(SET_DUMMY_LINE_PERIOD, b'\x1A') # 4 dummy lines per gate 106 | self._command(SET_GATE_TIME, b'\x08') # 2us per line 107 | self._command(DATA_ENTRY_MODE_SETTING, b'\x03') # X increment Y increment 108 | self.set_lut(self.LUT_FULL_UPDATE) 109 | 110 | def wait_until_idle(self): 111 | while self.busy.value() == BUSY: 112 | sleep_ms(100) 113 | 114 | def reset(self): 115 | self.rst(0) 116 | sleep_ms(200) 117 | self.rst(1) 118 | sleep_ms(200) 119 | 120 | def set_lut(self, lut): 121 | self._command(WRITE_LUT_REGISTER, lut) 122 | 123 | # put an image in the frame memory 124 | def set_frame_memory(self, image, x, y, w, h): 125 | # x point must be the multiple of 8 or the last 3 bits will be ignored 126 | x = x & 0xF8 127 | w = w & 0xF8 128 | 129 | if (x + w >= self.width): 130 | x_end = self.width - 1 131 | else: 132 | x_end = x + w - 1 133 | 134 | if (y + h >= self.height): 135 | y_end = self.height - 1 136 | else: 137 | y_end = y + h - 1 138 | 139 | self.set_memory_area(x, y, x_end, y_end) 140 | self.set_memory_pointer(x, y) 141 | self._command(WRITE_RAM, image) 142 | 143 | # replace the frame memory with the specified color 144 | def clear_frame_memory(self, color): 145 | self.set_memory_area(0, 0, self.width - 1, self.height - 1) 146 | self.set_memory_pointer(0, 0) 147 | self._command(WRITE_RAM) 148 | # send the color data 149 | for i in range(0, self.width // 8 * self.height): 150 | self._data(bytearray([color])) 151 | 152 | # draw the current frame memory and switch to the next memory area 153 | def display_frame(self): 154 | self._command(DISPLAY_UPDATE_CONTROL_2, b'\xC4') 155 | self._command(MASTER_ACTIVATION) 156 | self._command(TERMINATE_FRAME_READ_WRITE) 157 | self.wait_until_idle() 158 | 159 | # specify the memory area for data R/W 160 | def set_memory_area(self, x_start, y_start, x_end, y_end): 161 | self._command(SET_RAM_X_ADDRESS_START_END_POSITION) 162 | # x point must be the multiple of 8 or the last 3 bits will be ignored 163 | self._data(bytearray([(x_start >> 3) & 0xFF])) 164 | self._data(bytearray([(x_end >> 3) & 0xFF])) 165 | self._command(SET_RAM_Y_ADDRESS_START_END_POSITION, ustruct.pack("> 3) & 0xFF])) 172 | self._command(SET_RAM_Y_ADDRESS_COUNTER, ustruct.pack("BH", EPD_WIDTH, EPD_HEIGHT)) 122 | 123 | def wait_until_idle(self): 124 | while self.busy.value() == BUSY: 125 | sleep_ms(100) 126 | 127 | def reset(self): 128 | self.rst(0) 129 | sleep_ms(200) 130 | self.rst(1) 131 | sleep_ms(200) 132 | 133 | def display_frame(self, frame_buffer_black, frame_buffer_red): 134 | if (frame_buffer_black != None): 135 | self._command(DATA_START_TRANSMISSION_1) 136 | sleep_ms(2) 137 | for i in range(0, self.width * self.height // 8): 138 | self._data(bytearray([frame_buffer_black[i]])) 139 | sleep_ms(2) 140 | if (frame_buffer_red != None): 141 | self._command(DATA_START_TRANSMISSION_2) 142 | sleep_ms(2) 143 | for i in range(0, self.width * self.height // 8): 144 | self._data(bytearray([frame_buffer_red[i]])) 145 | sleep_ms(2) 146 | 147 | self._command(DISPLAY_REFRESH) 148 | self.wait_until_idle() 149 | 150 | def set_rotate(self, rotate): 151 | if (rotate == ROTATE_0): 152 | self.rotate = ROTATE_0 153 | self.width = epdif.EPD_WIDTH 154 | self.height = epdif.EPD_HEIGHT 155 | elif (rotate == ROTATE_90): 156 | self.rotate = ROTATE_90 157 | self.width = epdif.EPD_HEIGHT 158 | self.height = epdif.EPD_WIDTH 159 | elif (rotate == ROTATE_180): 160 | self.rotate = ROTATE_180 161 | self.width = epdif.EPD_WIDTH 162 | self.height = epdif.EPD_HEIGHT 163 | elif (rotate == ROTATE_270): 164 | self.rotate = ROTATE_270 165 | self.width = epdif.EPD_HEIGHT 166 | self.height = epdif.EPD_WIDTH 167 | 168 | def set_pixel(self, frame_buffer, x, y, colored): 169 | if (x < 0 or x >= self.width or y < 0 or y >= self.height): 170 | return 171 | if (self.rotate == ROTATE_0): 172 | self.set_absolute_pixel(frame_buffer, x, y, colored) 173 | elif (self.rotate == ROTATE_90): 174 | point_temp = x 175 | x = epdif.EPD_WIDTH - y 176 | y = point_temp 177 | self.set_absolute_pixel(frame_buffer, x, y, colored) 178 | elif (self.rotate == ROTATE_180): 179 | x = epdif.EPD_WIDTH - x 180 | y = epdif.EPD_HEIGHT- y 181 | self.set_absolute_pixel(frame_buffer, x, y, colored) 182 | elif (self.rotate == ROTATE_270): 183 | point_temp = x 184 | x = y 185 | y = epdif.EPD_HEIGHT - point_temp 186 | self.set_absolute_pixel(frame_buffer, x, y, colored) 187 | 188 | def set_absolute_pixel(self, frame_buffer, x, y, colored): 189 | # To avoid display orientation effects 190 | # use EPD_WIDTH instead of self.width 191 | # use EPD_HEIGHT instead of self.height 192 | if (x < 0 or x >= EPD_WIDTH or y < 0 or y >= EPD_HEIGHT): 193 | return 194 | if (colored): 195 | frame_buffer[(x + y * EPD_WIDTH) // 8] &= ~(0x80 >> (x % 8)) 196 | else: 197 | frame_buffer[(x + y * EPD_WIDTH) // 8] |= 0x80 >> (x % 8) 198 | 199 | def draw_string_at(self, frame_buffer, x, y, text, font, colored): 200 | image = Image.new('1', (self.width, self.height)) 201 | draw = ImageDraw.Draw(image) 202 | draw.text((x, y), text, font = font, fill = 255) 203 | # Set buffer to value of Python Imaging Library image. 204 | # Image must be in mode 1. 205 | pixels = image.load() 206 | for y in range(self.height): 207 | for x in range(self.width): 208 | # Set the bits for the column of pixels at the current position. 209 | if pixels[x, y] != 0: 210 | self.set_pixel(frame_buffer, x, y, colored) 211 | 212 | def draw_line(self, frame_buffer, x0, y0, x1, y1, colored): 213 | # Bresenham algorithm 214 | dx = abs(x1 - x0) 215 | sx = 1 if x0 < x1 else -1 216 | dy = -abs(y1 - y0) 217 | sy = 1 if y0 < y1 else -1 218 | err = dx + dy 219 | while((x0 != x1) and (y0 != y1)): 220 | self.set_pixel(frame_buffer, x0, y0 , colored) 221 | if (2 * err >= dy): 222 | err += dy 223 | x0 += sx 224 | if (2 * err <= dx): 225 | err += dx 226 | y0 += sy 227 | 228 | def draw_horizontal_line(self, frame_buffer, x, y, width, colored): 229 | for i in range(x, x + width): 230 | self.set_pixel(frame_buffer, i, y, colored) 231 | 232 | def draw_vertical_line(self, frame_buffer, x, y, height, colored): 233 | for i in range(y, y + height): 234 | self.set_pixel(frame_buffer, x, i, colored) 235 | 236 | def draw_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 237 | min_x = x0 if x1 > x0 else x1 238 | max_x = x1 if x1 > x0 else x0 239 | min_y = y0 if y1 > y0 else y1 240 | max_y = y1 if y1 > y0 else y0 241 | self.draw_horizontal_line(frame_buffer, min_x, min_y, max_x - min_x + 1, colored) 242 | self.draw_horizontal_line(frame_buffer, min_x, max_y, max_x - min_x + 1, colored) 243 | self.draw_vertical_line(frame_buffer, min_x, min_y, max_y - min_y + 1, colored) 244 | self.draw_vertical_line(frame_buffer, max_x, min_y, max_y - min_y + 1, colored) 245 | 246 | def draw_filled_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 247 | min_x = x0 if x1 > x0 else x1 248 | max_x = x1 if x1 > x0 else x0 249 | min_y = y0 if y1 > y0 else y1 250 | max_y = y1 if y1 > y0 else y0 251 | for i in range(min_x, max_x + 1): 252 | self.draw_vertical_line(frame_buffer, i, min_y, max_y - min_y + 1, colored) 253 | 254 | def draw_circle(self, frame_buffer, x, y, radius, colored): 255 | # Bresenham algorithm 256 | x_pos = -radius 257 | y_pos = 0 258 | err = 2 - 2 * radius 259 | if (x >= self.width or y >= self.height): 260 | return 261 | while True: 262 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 263 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 264 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 265 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 266 | e2 = err 267 | if (e2 <= y_pos): 268 | y_pos += 1 269 | err += y_pos * 2 + 1 270 | if(-x_pos == y_pos and e2 <= x_pos): 271 | e2 = 0 272 | if (e2 > x_pos): 273 | x_pos += 1 274 | err += x_pos * 2 + 1 275 | if x_pos > 0: 276 | break 277 | 278 | def draw_filled_circle(self, frame_buffer, x, y, radius, colored): 279 | # Bresenham algorithm 280 | x_pos = -radius 281 | y_pos = 0 282 | err = 2 - 2 * radius 283 | if (x >= self.width or y >= self.height): 284 | return 285 | while True: 286 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 287 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 288 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 289 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 290 | self.draw_horizontal_line(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored) 291 | self.draw_horizontal_line(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored) 292 | e2 = err 293 | if (e2 <= y_pos): 294 | y_pos += 1 295 | err += y_pos * 2 + 1 296 | if(-x_pos == y_pos and e2 <= x_pos): 297 | e2 = 0 298 | if (e2 > x_pos): 299 | x_pos += 1 300 | err += x_pos * 2 + 1 301 | if x_pos > 0: 302 | break 303 | 304 | # to wake call reset() or init() 305 | def sleep(self): 306 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x37') 307 | self._command(VCM_DC_SETTING_REGISTER, b'\x00') # to solve Vcom drop 308 | self._command(POWER_SETTING, b'\x02\x00\x00\x00') # gate switch to external 309 | self.wait_until_idle() 310 | self._command(POWER_OFF) 311 | -------------------------------------------------------------------------------- /epaper2in7.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 2.7" Black/White GDEW027W3 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | 31 | # Display resolution 32 | EPD_WIDTH = const(176) 33 | EPD_HEIGHT = const(264) 34 | 35 | # Display commands 36 | PANEL_SETTING = const(0x00) 37 | POWER_SETTING = const(0x01) 38 | #POWER_OFF = const(0x02) 39 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 40 | POWER_ON = const(0x04) 41 | #POWER_ON_MEASURE = const(0x05) 42 | BOOSTER_SOFT_START = const(0x06) 43 | DEEP_SLEEP = const(0x07) 44 | DATA_START_TRANSMISSION_1 = const(0x10) 45 | #DATA_STOP = const(0x11) 46 | DISPLAY_REFRESH = const(0x12) 47 | DATA_START_TRANSMISSION_2 = const(0x13) # not in datasheet 48 | #PARTIAL_DATA_START_TRANSMISSION_1 = const(0x14) 49 | #PARTIAL_DATA_START_TRANSMISSION_2 = const(0x15) 50 | PARTIAL_DISPLAY_REFRESH = const(0x16) 51 | LUT_FOR_VCOM = const(0x20) # LUT for VCOM(LUT1) 52 | LUT_WHITE_TO_WHITE = const(0x21) # White to white LUT (LUTWW) 53 | LUT_BLACK_TO_WHITE = const(0x22) # Black to white LUT (LUTBW/LUTR) 54 | LUT_WHITE_TO_BLACK = const(0x23) # White to Black LUT (LUTWB/LUTW) 55 | LUT_BLACK_TO_BLACK = const(0x24) # Black to Black LUT (LUTBB/LUTB) 56 | PLL_CONTROL = const(0x30) 57 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 58 | #TEMPERATURE_SENSOR_CALIBRATION = const(0x41) 59 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 60 | #TEMPERATURE_SENSOR_READ = const(0x43) 61 | #VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 62 | #LOW_POWER_DETECTION = const(0x51) 63 | #TCON_SETTING = const(0x60) 64 | #TCON_RESOLUTION = const(0x61) 65 | #SOURCE_AND_GATE_START_SETTING = const(0x62) 66 | #GET_STATUS = const(0x71) 67 | #AUTO_MEASURE_VCOM = const(0x80) 68 | #VCOM_VALUE = const(0x81) 69 | VCM_DC_SETTING_REGISTER = const(0x82) 70 | #PROGRAM_MODE = const(0xA0) 71 | #ACTIVE_PROGRAM = const(0xA1) 72 | #READ_OTP_DATA = const(0xA2) 73 | POWER_OPTIMIZATION = const(0xF8) # Power optimization in flow diagram 74 | 75 | BUSY = const(0) # 0=busy, 1=idle 76 | 77 | class EPD: 78 | def __init__(self, spi, cs, dc, rst, busy): 79 | self.spi = spi 80 | self.cs = cs 81 | self.dc = dc 82 | self.rst = rst 83 | self.busy = busy 84 | self.cs.init(self.cs.OUT, value=1) 85 | self.dc.init(self.dc.OUT, value=0) 86 | self.rst.init(self.rst.OUT, value=0) 87 | self.busy.init(self.busy.IN) 88 | self.width = EPD_WIDTH 89 | self.height = EPD_HEIGHT 90 | 91 | LUT_VCOM_DC = bytearray(b'\x00\x00\x00\x0F\x0F\x00\x00\x05\x00\x32\x32\x00\x00\x02\x00\x0F\x0F\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 92 | LUT_WW = bytearray(b'\x50\x0F\x0F\x00\x00\x05\x60\x32\x32\x00\x00\x02\xA0\x0F\x0F\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # R21H 93 | LUT_BW = LUT_BW # R22H r 94 | LUT_BB = bytearray(b'\xA0\x0F\x0F\x00\x00\x05\x60\x32\x32\x00\x00\x02\x50\x0F\x0F\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # R24H b 95 | LUT_WB = LUT_BB # R23H w 96 | 97 | def _command(self, command, data=None): 98 | self.dc(0) 99 | self.cs(0) 100 | self.spi.write(bytearray([command])) 101 | self.cs(1) 102 | if data is not None: 103 | self._data(data) 104 | 105 | def _data(self, data): 106 | self.dc(1) 107 | self.cs(0) 108 | self.spi.write(data) 109 | self.cs(1) 110 | 111 | def init(self): 112 | self.reset() 113 | self._command(POWER_SETTING, b'\x03\x00\x2B\x2B\x09') # VDS_EN VDG_EN, VCOM_HV VGHL_LV[1] VGHL_LV[0], VDH, VDL, VDHR 114 | self._command(BOOSTER_SOFT_START, b'\x07\x07\x17') 115 | self._command(POWER_OPTIMIZATION, b'\x60\xA5') 116 | self._command(POWER_OPTIMIZATION, b'\x89\xA5') 117 | self._command(POWER_OPTIMIZATION, b'\x90\x00') 118 | self._command(POWER_OPTIMIZATION, b'\x93\x2A') 119 | self._command(POWER_OPTIMIZATION, b'\xA0\xA5') 120 | self._command(POWER_OPTIMIZATION, b'\xA1\x00') 121 | self._command(POWER_OPTIMIZATION, b'\x73\x41') 122 | self._command(PARTIAL_DISPLAY_REFRESH, b'\x00') 123 | self._command(POWER_ON) 124 | self.wait_until_idle() 125 | self._command(PANEL_SETTING, b'\xAF') # KW-BF KWR-AF BWROTP 0f 126 | self._command(PLL_CONTROL, b'\x3A') # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ 127 | self._command(VCM_DC_SETTING_REGISTER, b'\x12') 128 | sleep_ms(2) 129 | self.set_lut() 130 | 131 | def wait_until_idle(self): 132 | while self.busy.value() == BUSY: 133 | sleep_ms(100) 134 | 135 | def reset(self): 136 | self.rst(0) 137 | sleep_ms(200) 138 | self.rst(1) 139 | sleep_ms(200) 140 | 141 | def set_lut(self): 142 | self._command(LUT_FOR_VCOM, self.LUT_VCOM_DC) # vcom 143 | self._command(LUT_WHITE_TO_WHITE, self.LUT_WW) # ww -- 144 | self._command(LUT_BLACK_TO_WHITE, self.LUT_BW) # bw r 145 | self._command(LUT_WHITE_TO_BLACK, self.LUT_BB) # wb w 146 | self._command(LUT_BLACK_TO_BLACK, self.LUT_WB) # bb b 147 | 148 | # draw the current frame memory 149 | def display_frame(self, frame_buffer): 150 | if (frame_buffer != None): 151 | self._command(DATA_START_TRANSMISSION_1) 152 | sleep_ms(2) 153 | for i in range(0, self.width * self.height // 8): 154 | self._data(bytearray([0xFF])) 155 | sleep_ms(2) 156 | self._command(DATA_START_TRANSMISSION_2) 157 | sleep_ms(2) 158 | for i in range(0, self.width * self.height // 8): 159 | self._data(bytearray([frame_buffer[i]])) 160 | sleep_ms(2) 161 | self._command(DISPLAY_REFRESH) 162 | self.wait_until_idle() 163 | 164 | # to wake call reset() or init() 165 | def sleep(self): 166 | self._command(DEEP_SLEEP, b'\xA5') 167 | -------------------------------------------------------------------------------- /epaper2in7b.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 2.7" Black/White/Red GDEW027C44 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | # is there a black/white/yellow panel? 29 | 30 | from micropython import const 31 | from time import sleep_ms 32 | import ustruct 33 | 34 | # Display resolution 35 | EPD_WIDTH = const(176) 36 | EPD_HEIGHT = const(264) 37 | 38 | # Display commands 39 | PANEL_SETTING = const(0x00) 40 | POWER_SETTING = const(0x01) 41 | #POWER_OFF = const(0x02) 42 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 43 | POWER_ON = const(0x04) 44 | #POWER_ON_MEASURE = const(0x05) 45 | BOOSTER_SOFT_START = const(0x06) 46 | DEEP_SLEEP = const(0x07) 47 | #DATA_START_TRANSMISSION_1 = const(0x10) 48 | #DATA_STOP = const(0x11) 49 | DISPLAY_REFRESH = const(0x12) 50 | DATA_START_TRANSMISSION_2 = const(0x13) 51 | #PARTIAL_DATA_START_TRANSMISSION_1 = const(0x14) 52 | #PARTIAL_DATA_START_TRANSMISSION_2 = const(0x15) 53 | PARTIAL_DISPLAY_REFRESH = const(0x16) 54 | LUT_FOR_VCOM = const(0x20) 55 | LUT_WHITE_TO_WHITE = const(0x21) 56 | LUT_BLACK_TO_WHITE = const(0x22) 57 | LUT_WHITE_TO_BLACK = const(0x23) 58 | LUT_BLACK_TO_BLACK = const(0x24) 59 | PLL_CONTROL = const(0x30) 60 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 61 | #TEMPERATURE_SENSOR_CALIBRATION = const(0x41) 62 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 63 | #TEMPERATURE_SENSOR_READ = const(0x43) 64 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 65 | #LOW_POWER_DETECTION = const(0x51) 66 | #TCON_SETTING = const(0x60) 67 | TCON_RESOLUTION = const(0x61) 68 | #SOURCE_AND_GATE_START_SETTING = const(0x62) 69 | #GET_STATUS = const(0x71) 70 | #AUTO_MEASURE_VCOM = const(0x80) 71 | #VCOM_VALUE = const(0x81) 72 | VCM_DC_SETTING_REGISTER = const(0x82) 73 | #PROGRAM_MODE = const(0xA0) 74 | #ACTIVE_PROGRAM = const(0xA1) 75 | #READ_OTP_DATA = const(0xA2) 76 | POWER_OPTIMIZATION = const(0xF8) # Power optimization in flow diagram 77 | 78 | # Display orientation 79 | ROTATE_0 = const(0) 80 | ROTATE_90 = const(1) 81 | ROTATE_180 = const(2) 82 | ROTATE_270 = const(3) 83 | 84 | BUSY = const(0) # 0=busy, 1=idle 85 | 86 | class EPD: 87 | def __init__(self, spi, cs, dc, rst, busy): 88 | self.spi = spi 89 | self.cs = cs 90 | self.dc = dc 91 | self.rst = rst 92 | self.busy = busy 93 | self.cs.init(self.cs.OUT, value=1) 94 | self.dc.init(self.dc.OUT, value=0) 95 | self.rst.init(self.rst.OUT, value=0) 96 | self.busy.init(self.busy.IN) 97 | self.width = EPD_WIDTH 98 | self.height = EPD_HEIGHT 99 | self.rotate = ROTATE_0 100 | 101 | LUT_VCOM_DC = bytearray(b'\x00\x00\x00\x1A\x1A\x00\x00\x01\x00\x0A\x0A\x00\x00\x08\x00\x0E\x01\x0E\x01\x10\x00\x0A\x0A\x00\x00\x08\x00\x04\x10\x00\x00\x05\x00\x03\x0E\x00\x00\x0A\x00\x23\x00\x00\x00\x01') 102 | LUT_WW = bytearray(b'\x90\x1A\x1A\x00\x00\x01\x40\x0A\x0A\x00\x00\x08\x84\x0E\x01\x0E\x01\x10\x80\x0A\x0A\x00\x00\x08\x00\x04\x10\x00\x00\x05\x00\x03\x0E\x00\x00\x0A\x00\x23\x00\x00\x00\x01') # R21H 103 | LUT_BW = bytearray(b'\xA0\x1A\x1A\x00\x00\x01\x00\x0A\x0A\x00\x00\x08\x84\x0E\x01\x0E\x01\x10\x90\x0A\x0A\x00\x00\x08\xB0\x04\x10\x00\x00\x05\xB0\x03\x0E\x00\x00\x0A\xC0\x23\x00\x00\x00\x01') # R22H r 104 | LUT_BB = LUT_WW # R23H w 105 | LUT_WB = bytearray(b'\x90\x1A\x1A\x00\x00\x01\x20\x0A\x0A\x00\x00\x08\x84\x0E\x01\x0E\x01\x10\x10\x0A\x0A\x00\x00\x08\x00\x04\x10\x00\x00\x05\x00\x03\x0E\x00\x00\x0A\x00\x23\x00\x00\x00\x01') # R24H b 106 | 107 | def _command(self, command, data=None): 108 | self.dc(0) 109 | self.cs(0) 110 | self.spi.write(bytearray([command])) 111 | self.cs(1) 112 | if data is not None: 113 | self._data(data) 114 | 115 | def _data(self, data): 116 | self.dc(1) 117 | self.cs(0) 118 | self.spi.write(data) 119 | self.cs(1) 120 | 121 | def init(self): 122 | self.reset() 123 | self._command(POWER_ON) 124 | self.wait_until_idle() 125 | self._command(PANEL_SETTING, b'\xAF') # (296x160, LUT from register, B/W/R run both LU1 LU2, scan up, shift right, bootster on) KW-BF KWR-AF BWROTP 0f 126 | self._command(PLL_CONTROL, b'\x3A') # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ 127 | self._command(POWER_SETTING, b'\x03\x00\x2b\x2b\x09') # VDS_EN VDG_EN, VCOM_HV VGHL_LV[1] VGHL_LV[0], VDH, VDL, VDHR 128 | self._command(BOOSTER_SOFT_START, b'\x07\x07\x17') 129 | self._command(POWER_OPTIMIZATION, b'\x60\xA5') 130 | self._command(POWER_OPTIMIZATION, b'\x89\xA5') 131 | self._command(POWER_OPTIMIZATION, b'\x90\x00') 132 | self._command(POWER_OPTIMIZATION, b'\x93\x2A') 133 | self._command(POWER_OPTIMIZATION, b'\x73\x41') 134 | self._command(VCM_DC_SETTING_REGISTER, b'\x12') 135 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x87') # define by OTP 136 | self.set_lut() 137 | self._command(PARTIAL_DISPLAY_REFRESH, b'\x00') 138 | 139 | def wait_until_idle(self): 140 | while self.busy.value() == BUSY: 141 | sleep_ms(100) 142 | 143 | def reset(self): 144 | self.rst(0) 145 | sleep_ms(200) 146 | self.rst(1) 147 | sleep_ms(200) 148 | 149 | def set_lut(self): 150 | self._command(LUT_FOR_VCOM, self.LUT_VCOM_DC) # vcom 151 | self._command(LUT_WHITE_TO_WHITE, self.LUT_WW) # ww -- 152 | self._command(LUT_BLACK_TO_WHITE, self.LUT_BW) # bw r 153 | self._command(LUT_WHITE_TO_BLACK, self.LUT_BB) # wb w 154 | self._command(LUT_BLACK_TO_BLACK, self.LUT_WB) # bb b 155 | 156 | def display_frame(self, frame_buffer_black, frame_buffer_red): 157 | self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 158 | 159 | if (frame_buffer_black != None): 160 | self._command(DATA_START_TRANSMISSION_1) 161 | sleep_ms(2) 162 | for i in range(0, self.width * self.height // 8): 163 | self._data(bytearray([frame_buffer_black[i]])) 164 | sleep_ms(2) 165 | if (frame_buffer_red != None): 166 | self._command(DATA_START_TRANSMISSION_2) 167 | sleep_ms(2) 168 | for i in range(0, self.width * self.height // 8): 169 | self._data(bytearray([frame_buffer_red[i]])) 170 | sleep_ms(2) 171 | 172 | self._command(DISPLAY_REFRESH) 173 | self.wait_until_idle() 174 | 175 | def set_rotate(self, rotate): 176 | if (rotate == ROTATE_0): 177 | self.rotate = ROTATE_0 178 | self.width = EPD_WIDTH 179 | self.height = EPD_HEIGHT 180 | elif (rotate == ROTATE_90): 181 | self.rotate = ROTATE_90 182 | self.width = EPD_HEIGHT 183 | self.height = EPD_WIDTH 184 | elif (rotate == ROTATE_180): 185 | self.rotate = ROTATE_180 186 | self.width = EPD_WIDTH 187 | self.height = EPD_HEIGHT 188 | elif (rotate == ROTATE_270): 189 | self.rotate = ROTATE_270 190 | self.width = EPD_HEIGHT 191 | self.height = EPD_WIDTH 192 | 193 | def set_pixel(self, frame_buffer, x, y, colored): 194 | if (x < 0 or x >= self.width or y < 0 or y >= self.height): 195 | return 196 | if (self.rotate == ROTATE_0): 197 | self.set_absolute_pixel(frame_buffer, x, y, colored) 198 | elif (self.rotate == ROTATE_90): 199 | point_temp = x 200 | x = EPD_WIDTH - y 201 | y = point_temp 202 | self.set_absolute_pixel(frame_buffer, x, y, colored) 203 | elif (self.rotate == ROTATE_180): 204 | x = EPD_WIDTH - x 205 | y = EPD_HEIGHT- y 206 | self.set_absolute_pixel(frame_buffer, x, y, colored) 207 | elif (self.rotate == ROTATE_270): 208 | point_temp = x 209 | x = y 210 | y = EPD_HEIGHT - point_temp 211 | self.set_absolute_pixel(frame_buffer, x, y, colored) 212 | 213 | def set_absolute_pixel(self, frame_buffer, x, y, colored): 214 | # To avoid display orientation effects 215 | # use EPD_WIDTH instead of self.width 216 | # use EPD_HEIGHT instead of self.height 217 | if (x < 0 or x >= EPD_WIDTH or y < 0 or y >= EPD_HEIGHT): 218 | return 219 | if (colored): 220 | frame_buffer[(x + y * EPD_WIDTH) // 8] |= 0x80 >> (x % 8) 221 | else: 222 | frame_buffer[(x + y * EPD_WIDTH) // 8] &= ~(0x80 >> (x % 8)) 223 | 224 | def draw_string_at(self, frame_buffer, x, y, text, font, colored): 225 | image = Image.new('1', (self.width, self.height)) 226 | draw = ImageDraw.Draw(image) 227 | draw.text((x, y), text, font = font, fill = 255) 228 | # Set buffer to value of Python Imaging Library image. 229 | # Image must be in mode 1. 230 | pixels = image.load() 231 | for y in range(self.height): 232 | for x in range(self.width): 233 | # Set the bits for the column of pixels at the current position. 234 | if pixels[x, y] != 0: 235 | self.set_pixel(frame_buffer, x, y, colored) 236 | 237 | def draw_line(self, frame_buffer, x0, y0, x1, y1, colored): 238 | # Bresenham algorithm 239 | dx = abs(x1 - x0) 240 | sx = 1 if x0 < x1 else -1 241 | dy = -abs(y1 - y0) 242 | sy = 1 if y0 < y1 else -1 243 | err = dx + dy 244 | while((x0 != x1) and (y0 != y1)): 245 | self.set_pixel(frame_buffer, x0, y0 , colored) 246 | if (2 * err >= dy): 247 | err += dy 248 | x0 += sx 249 | if (2 * err <= dx): 250 | err += dx 251 | y0 += sy 252 | 253 | def draw_horizontal_line(self, frame_buffer, x, y, width, colored): 254 | for i in range(x, x + width): 255 | self.set_pixel(frame_buffer, i, y, colored) 256 | 257 | def draw_vertical_line(self, frame_buffer, x, y, height, colored): 258 | for i in range(y, y + height): 259 | self.set_pixel(frame_buffer, x, i, colored) 260 | 261 | def draw_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 262 | min_x = x0 if x1 > x0 else x1 263 | max_x = x1 if x1 > x0 else x0 264 | min_y = y0 if y1 > y0 else y1 265 | max_y = y1 if y1 > y0 else y0 266 | self.draw_horizontal_line(frame_buffer, min_x, min_y, max_x - min_x + 1, colored) 267 | self.draw_horizontal_line(frame_buffer, min_x, max_y, max_x - min_x + 1, colored) 268 | self.draw_vertical_line(frame_buffer, min_x, min_y, max_y - min_y + 1, colored) 269 | self.draw_vertical_line(frame_buffer, max_x, min_y, max_y - min_y + 1, colored) 270 | 271 | def draw_filled_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 272 | min_x = x0 if x1 > x0 else x1 273 | max_x = x1 if x1 > x0 else x0 274 | min_y = y0 if y1 > y0 else y1 275 | max_y = y1 if y1 > y0 else y0 276 | for i in range(min_x, max_x + 1): 277 | self.draw_vertical_line(frame_buffer, i, min_y, max_y - min_y + 1, colored) 278 | 279 | def draw_circle(self, frame_buffer, x, y, radius, colored): 280 | # Bresenham algorithm 281 | x_pos = -radius 282 | y_pos = 0 283 | err = 2 - 2 * radius 284 | if (x >= self.width or y >= self.height): 285 | return 286 | while True: 287 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 288 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 289 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 290 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 291 | e2 = err 292 | if (e2 <= y_pos): 293 | y_pos += 1 294 | err += y_pos * 2 + 1 295 | if(-x_pos == y_pos and e2 <= x_pos): 296 | e2 = 0 297 | if (e2 > x_pos): 298 | x_pos += 1 299 | err += x_pos * 2 + 1 300 | if x_pos > 0: 301 | break 302 | 303 | def draw_filled_circle(self, frame_buffer, x, y, radius, colored): 304 | # Bresenham algorithm 305 | x_pos = -radius 306 | y_pos = 0 307 | err = 2 - 2 * radius 308 | if (x >= self.width or y >= self.height): 309 | return 310 | while True: 311 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 312 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 313 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 314 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 315 | self.draw_horizontal_line(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored); 316 | self.draw_horizontal_line(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored); 317 | e2 = err 318 | if (e2 <= y_pos): 319 | y_pos += 1 320 | err += y_pos * 2 + 1 321 | if(-x_pos == y_pos and e2 <= x_pos): 322 | e2 = 0 323 | if (e2 > x_pos): 324 | x_pos += 1 325 | err += x_pos * 2 + 1 326 | if x_pos > 0: 327 | break 328 | 329 | # to wake call reset() or init() 330 | def sleep(self): 331 | self._command(DEEP_SLEEP, b'\xA5') 332 | -------------------------------------------------------------------------------- /epaper2in9.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 2.9" Black/White GDEH029A1 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(128) 34 | EPD_HEIGHT = const(296) 35 | 36 | # Display commands 37 | DRIVER_OUTPUT_CONTROL = const(0x01) 38 | BOOSTER_SOFT_START_CONTROL = const(0x0C) 39 | #GATE_SCAN_START_POSITION = const(0x0F) 40 | DEEP_SLEEP_MODE = const(0x10) 41 | DATA_ENTRY_MODE_SETTING = const(0x11) 42 | #SW_RESET = const(0x12) 43 | #TEMPERATURE_SENSOR_CONTROL = const(0x1A) 44 | MASTER_ACTIVATION = const(0x20) 45 | #DISPLAY_UPDATE_CONTROL_1 = const(0x21) 46 | DISPLAY_UPDATE_CONTROL_2 = const(0x22) 47 | WRITE_RAM = const(0x24) 48 | WRITE_VCOM_REGISTER = const(0x2C) 49 | WRITE_LUT_REGISTER = const(0x32) 50 | SET_DUMMY_LINE_PERIOD = const(0x3A) 51 | SET_GATE_TIME = const(0x3B) 52 | #BORDER_WAVEFORM_CONTROL = const(0x3C) 53 | SET_RAM_X_ADDRESS_START_END_POSITION = const(0x44) 54 | SET_RAM_Y_ADDRESS_START_END_POSITION = const(0x45) 55 | SET_RAM_X_ADDRESS_COUNTER = const(0x4E) 56 | SET_RAM_Y_ADDRESS_COUNTER = const(0x4F) 57 | TERMINATE_FRAME_READ_WRITE = const(0xFF) 58 | 59 | BUSY = const(1) # 1=busy, 0=idle 60 | 61 | class EPD: 62 | def __init__(self, spi, cs, dc, rst, busy): 63 | self.spi = spi 64 | self.cs = cs 65 | self.dc = dc 66 | self.rst = rst 67 | self.busy = busy 68 | self.cs.init(self.cs.OUT, value=1) 69 | self.dc.init(self.dc.OUT, value=0) 70 | self.rst.init(self.rst.OUT, value=0) 71 | self.busy.init(self.busy.IN) 72 | self.width = EPD_WIDTH 73 | self.height = EPD_HEIGHT 74 | 75 | # 30 bytes (look up tables) 76 | # original waveshare example 77 | LUT_FULL_UPDATE = bytearray(b'\x02\x02\x01\x11\x12\x12\x22\x22\x66\x69\x69\x59\x58\x99\x99\x88\x00\x00\x00\x00\xF8\xB4\x13\x51\x35\x51\x51\x19\x01\x00') 78 | LUT_PARTIAL_UPDATE = bytearray(b'\x10\x18\x18\x08\x18\x18\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x14\x44\x12\x00\x00\x00\x00\x00\x00') 79 | 80 | # https://github.com/ZinggJM/GxEPD/blob/master/GxGDEH029A1/GxGDEH029A1.cpp 81 | #LUT_FULL_UPDATE = bytearray(b'\x50\xAA\x55\xAA\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x1F\x00\x00\x00\x00\x00\x00\x00') 82 | #LUT_PARTIAL_UPDATE = bytearray(b'\x10\x18\x18\x08\x18\x18\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x14\x44\x12\x00\x00\x00\x00\x00\x00') 83 | 84 | def _command(self, command, data=None): 85 | self.dc(0) 86 | self.cs(0) 87 | self.spi.write(bytearray([command])) 88 | self.cs(1) 89 | if data is not None: 90 | self._data(data) 91 | 92 | def _data(self, data): 93 | self.dc(1) 94 | self.cs(0) 95 | self.spi.write(data) 96 | self.cs(1) 97 | 98 | def init(self): 99 | self.reset() 100 | self._command(DRIVER_OUTPUT_CONTROL, ustruct.pack("= self.width): 128 | x_end = self.width - 1 129 | else: 130 | x_end = x + w - 1 131 | 132 | if (y + h >= self.height): 133 | y_end = self.height - 1 134 | else: 135 | y_end = y + h - 1 136 | 137 | self.set_memory_area(x, y, x_end, y_end) 138 | self.set_memory_pointer(x, y) 139 | self._command(WRITE_RAM, image) 140 | 141 | # replace the frame memory with the specified color 142 | def clear_frame_memory(self, color): 143 | self.set_memory_area(0, 0, self.width - 1, self.height - 1) 144 | self.set_memory_pointer(0, 0) 145 | self._command(WRITE_RAM) 146 | # send the color data 147 | for i in range(0, self.width // 8 * self.height): 148 | self._data(bytearray([color])) 149 | 150 | # draw the current frame memory and switch to the next memory area 151 | def display_frame(self): 152 | self._command(DISPLAY_UPDATE_CONTROL_2, b'\xC4') 153 | self._command(MASTER_ACTIVATION) 154 | self._command(TERMINATE_FRAME_READ_WRITE) 155 | self.wait_until_idle() 156 | 157 | # specify the memory area for data R/W 158 | def set_memory_area(self, x_start, y_start, x_end, y_end): 159 | self._command(SET_RAM_X_ADDRESS_START_END_POSITION) 160 | # x point must be the multiple of 8 or the last 3 bits will be ignored 161 | self._data(bytearray([(x_start >> 3) & 0xFF])) 162 | self._data(bytearray([(x_end >> 3) & 0xFF])) 163 | self._command(SET_RAM_Y_ADDRESS_START_END_POSITION, ustruct.pack("> 3) & 0xFF])) 170 | self._command(SET_RAM_Y_ADDRESS_COUNTER, ustruct.pack("BH", EPD_WIDTH, EPD_HEIGHT)) 117 | self._command(VCM_DC_SETTING_REGISTER, b'\x0A') 118 | 119 | def wait_until_idle(self): 120 | while self.busy.value() == BUSY: 121 | sleep_ms(100) 122 | 123 | def reset(self): 124 | self.rst(0) 125 | sleep_ms(200) 126 | self.rst(1) 127 | sleep_ms(200) 128 | 129 | def display_frame(self, frame_buffer_black, frame_buffer_red): 130 | if (frame_buffer_black != None): 131 | self._command(DATA_START_TRANSMISSION_1) 132 | sleep_ms(2) 133 | for i in range(0, self.width * self.height // 8): 134 | self._data(bytearray([frame_buffer_black[i]])) 135 | sleep_ms(2) 136 | if (frame_buffer_red != None): 137 | self._command(DATA_START_TRANSMISSION_2) 138 | sleep_ms(2) 139 | for i in range(0, self.width * self.height // 8): 140 | self._data(bytearray([frame_buffer_red[i]])) 141 | sleep_ms(2) 142 | 143 | self._command(DISPLAY_REFRESH) 144 | self.wait_until_idle() 145 | 146 | def set_rotate(self, rotate): 147 | if (rotate == ROTATE_0): 148 | self.rotate = ROTATE_0 149 | self.width = epdif.EPD_WIDTH 150 | self.height = epdif.EPD_HEIGHT 151 | elif (rotate == ROTATE_90): 152 | self.rotate = ROTATE_90 153 | self.width = epdif.EPD_HEIGHT 154 | self.height = epdif.EPD_WIDTH 155 | elif (rotate == ROTATE_180): 156 | self.rotate = ROTATE_180 157 | self.width = epdif.EPD_WIDTH 158 | self.height = epdif.EPD_HEIGHT 159 | elif (rotate == ROTATE_270): 160 | self.rotate = ROTATE_270 161 | self.width = epdif.EPD_HEIGHT 162 | self.height = epdif.EPD_WIDTH 163 | 164 | def set_pixel(self, frame_buffer, x, y, colored): 165 | if (x < 0 or x >= self.width or y < 0 or y >= self.height): 166 | return 167 | if (self.rotate == ROTATE_0): 168 | self.set_absolute_pixel(frame_buffer, x, y, colored) 169 | elif (self.rotate == ROTATE_90): 170 | point_temp = x 171 | x = epdif.EPD_WIDTH - y 172 | y = point_temp 173 | self.set_absolute_pixel(frame_buffer, x, y, colored) 174 | elif (self.rotate == ROTATE_180): 175 | x = epdif.EPD_WIDTH - x 176 | y = epdif.EPD_HEIGHT- y 177 | self.set_absolute_pixel(frame_buffer, x, y, colored) 178 | elif (self.rotate == ROTATE_270): 179 | point_temp = x 180 | x = y 181 | y = epdif.EPD_HEIGHT - point_temp 182 | self.set_absolute_pixel(frame_buffer, x, y, colored) 183 | 184 | def set_absolute_pixel(self, frame_buffer, x, y, colored): 185 | # To avoid display orientation effects 186 | # use EPD_WIDTH instead of self.width 187 | # use EPD_HEIGHT instead of self.height 188 | if (x < 0 or x >= EPD_WIDTH or y < 0 or y >= EPD_HEIGHT): 189 | return 190 | if (colored): 191 | frame_buffer[(x + y * EPD_WIDTH) // 8] &= ~(0x80 >> (x % 8)) 192 | else: 193 | frame_buffer[(x + y * EPD_WIDTH) // 8] |= 0x80 >> (x % 8) 194 | 195 | def draw_string_at(self, frame_buffer, x, y, text, font, colored): 196 | image = Image.new('1', (self.width, self.height)) 197 | draw = ImageDraw.Draw(image) 198 | draw.text((x, y), text, font = font, fill = 255) 199 | # Set buffer to value of Python Imaging Library image. 200 | # Image must be in mode 1. 201 | pixels = image.load() 202 | for y in range(self.height): 203 | for x in range(self.width): 204 | # Set the bits for the column of pixels at the current position. 205 | if pixels[x, y] != 0: 206 | self.set_pixel(frame_buffer, x, y, colored) 207 | 208 | def draw_line(self, frame_buffer, x0, y0, x1, y1, colored): 209 | # Bresenham algorithm 210 | dx = abs(x1 - x0) 211 | sx = 1 if x0 < x1 else -1 212 | dy = -abs(y1 - y0) 213 | sy = 1 if y0 < y1 else -1 214 | err = dx + dy 215 | while((x0 != x1) and (y0 != y1)): 216 | self.set_pixel(frame_buffer, x0, y0 , colored) 217 | if (2 * err >= dy): 218 | err += dy 219 | x0 += sx 220 | if (2 * err <= dx): 221 | err += dx 222 | y0 += sy 223 | 224 | def draw_horizontal_line(self, frame_buffer, x, y, width, colored): 225 | for i in range(x, x + width): 226 | self.set_pixel(frame_buffer, i, y, colored) 227 | 228 | def draw_vertical_line(self, frame_buffer, x, y, height, colored): 229 | for i in range(y, y + height): 230 | self.set_pixel(frame_buffer, x, i, colored) 231 | 232 | def draw_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 233 | min_x = x0 if x1 > x0 else x1 234 | max_x = x1 if x1 > x0 else x0 235 | min_y = y0 if y1 > y0 else y1 236 | max_y = y1 if y1 > y0 else y0 237 | self.draw_horizontal_line(frame_buffer, min_x, min_y, max_x - min_x + 1, colored) 238 | self.draw_horizontal_line(frame_buffer, min_x, max_y, max_x - min_x + 1, colored) 239 | self.draw_vertical_line(frame_buffer, min_x, min_y, max_y - min_y + 1, colored) 240 | self.draw_vertical_line(frame_buffer, max_x, min_y, max_y - min_y + 1, colored) 241 | 242 | def draw_filled_rectangle(self, frame_buffer, x0, y0, x1, y1, colored): 243 | min_x = x0 if x1 > x0 else x1 244 | max_x = x1 if x1 > x0 else x0 245 | min_y = y0 if y1 > y0 else y1 246 | max_y = y1 if y1 > y0 else y0 247 | for i in range(min_x, max_x + 1): 248 | self.draw_vertical_line(frame_buffer, i, min_y, max_y - min_y + 1, colored) 249 | 250 | def draw_circle(self, frame_buffer, x, y, radius, colored): 251 | # Bresenham algorithm 252 | x_pos = -radius 253 | y_pos = 0 254 | err = 2 - 2 * radius 255 | if (x >= self.width or y >= self.height): 256 | return 257 | while True: 258 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 259 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 260 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 261 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 262 | e2 = err 263 | if (e2 <= y_pos): 264 | y_pos += 1 265 | err += y_pos * 2 + 1 266 | if(-x_pos == y_pos and e2 <= x_pos): 267 | e2 = 0 268 | if (e2 > x_pos): 269 | x_pos += 1 270 | err += x_pos * 2 + 1 271 | if x_pos > 0: 272 | break 273 | 274 | def draw_filled_circle(self, frame_buffer, x, y, radius, colored): 275 | # Bresenham algorithm 276 | x_pos = -radius 277 | y_pos = 0 278 | err = 2 - 2 * radius 279 | if (x >= self.width or y >= self.height): 280 | return 281 | while True: 282 | self.set_pixel(frame_buffer, x - x_pos, y + y_pos, colored) 283 | self.set_pixel(frame_buffer, x + x_pos, y + y_pos, colored) 284 | self.set_pixel(frame_buffer, x + x_pos, y - y_pos, colored) 285 | self.set_pixel(frame_buffer, x - x_pos, y - y_pos, colored) 286 | self.draw_horizontal_line(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored) 287 | self.draw_horizontal_line(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored) 288 | e2 = err 289 | if (e2 <= y_pos): 290 | y_pos += 1 291 | err += y_pos * 2 + 1 292 | if(-x_pos == y_pos and e2 <= x_pos): 293 | e2 = 0 294 | if (e2 > x_pos): 295 | x_pos += 1 296 | err += x_pos * 2 + 1 297 | if x_pos > 0: 298 | break 299 | 300 | # to wake call reset() or init() 301 | def sleep(self): 302 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x37') 303 | self._command(VCM_DC_SETTING_REGISTER, b'\x00') # to solve Vcom drop 304 | self._command(POWER_SETTING, b'\x02\x00\x00\x00') # gate switch to external 305 | self.wait_until_idle() 306 | self._command(POWER_OFF) 307 | -------------------------------------------------------------------------------- /epaper4in2.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 4.2" Black/White GDEW042T2 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(400) 34 | EPD_HEIGHT = const(300) 35 | 36 | # Display commands 37 | PANEL_SETTING = const(0x00) 38 | POWER_SETTING = const(0x01) 39 | POWER_OFF = const(0x02) 40 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 41 | POWER_ON = const(0x04) 42 | #POWER_ON_MEASURE = const(0x05) 43 | BOOSTER_SOFT_START = const(0x06) 44 | DEEP_SLEEP = const(0x07) 45 | DATA_START_TRANSMISSION_1 = const(0x10) 46 | #DATA_STOP = const(0x11) 47 | DISPLAY_REFRESH = const(0x12) 48 | DATA_START_TRANSMISSION_2 = const(0x13) 49 | LUT_FOR_VCOM = const(0x20) 50 | LUT_WHITE_TO_WHITE = const(0x21) 51 | LUT_BLACK_TO_WHITE = const(0x22) 52 | LUT_WHITE_TO_BLACK = const(0x23) 53 | LUT_BLACK_TO_BLACK = const(0x24) 54 | PLL_CONTROL = const(0x30) 55 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 56 | #TEMPERATURE_SENSOR_SELECTION = const(0x41) 57 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 58 | #TEMPERATURE_SENSOR_READ = const(0x43) 59 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 60 | #LOW_POWER_DETECTION = const(0x51) 61 | #TCON_SETTING = const(0x60) 62 | RESOLUTION_SETTING = const(0x61) 63 | #GSST_SETTING = const(0x65) 64 | #GET_STATUS = const(0x71) 65 | #AUTO_MEASUREMENT_VCOM = const(0x80) 66 | #READ_VCOM_VALUE = const(0x81) 67 | VCM_DC_SETTING = const(0x82) 68 | #PARTIAL_WINDOW = const(0x90) 69 | #PARTIAL_IN = const(0x91) 70 | #PARTIAL_OUT = const(0x92) 71 | 72 | #PROGRAM_MODE = const(0xA0) 73 | #ACTIVE_PROGRAMMING = const(0xA1) 74 | #READ_OTP = const(0xA2) 75 | #POWER_SAVING = const(0xE3) 76 | 77 | BUSY = const(0) # 0=busy, 1=idle 78 | 79 | class EPD: 80 | def __init__(self, spi, cs, dc, rst, busy): 81 | self.spi = spi 82 | self.cs = cs 83 | self.dc = dc 84 | self.rst = rst 85 | self.busy = busy 86 | self.cs.init(self.cs.OUT, value=1) 87 | self.dc.init(self.dc.OUT, value=0) 88 | self.rst.init(self.rst.OUT, value=0) 89 | self.busy.init(self.busy.IN) 90 | self.width = EPD_WIDTH 91 | self.height = EPD_HEIGHT 92 | 93 | # 44/42 bytes (look up tables) 94 | LUT_VCOM0 = bytearray(b'\x00\x17\x00\x00\x00\x02\x00\x17\x17\x00\x00\x02\x00\x0A\x01\x00\x00\x01\x00\x0E\x0E\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 95 | LUT_WW = bytearray(b'\x40\x17\x00\x00\x00\x02\x90\x17\x17\x00\x00\x02\x40\x0A\x01\x00\x00\x01\xA0\x0E\x0E\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 96 | LUT_BW = LUT_WW 97 | LUT_BB = bytearray(b'\x80\x17\x00\x00\x00\x02\x90\x17\x17\x00\x00\x02\x80\x0A\x01\x00\x00\x01\x50\x0E\x0E\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 98 | LUT_WB = LUT_BB 99 | 100 | def _command(self, command, data=None): 101 | self.dc(0) 102 | self.cs(0) 103 | self.spi.write(bytearray([command])) 104 | self.cs(1) 105 | if data is not None: 106 | self._data(data) 107 | 108 | def _data(self, data): 109 | self.dc(1) 110 | self.cs(0) 111 | self.spi.write(data) 112 | self.cs(1) 113 | 114 | def init(self): 115 | self.reset() 116 | self._command(POWER_SETTING, b'\x03\x00\x2B\x2B\xFF') # VDS_EN VDG_EN, VCOM_HV VGHL_LV[1] VGHL_LV[0], VDH, VDL, VDHR 117 | self._command(BOOSTER_SOFT_START, b'\x17\x17\x17') # 07 0f 17 1f 27 2F 37 2f 118 | self._command(POWER_ON) 119 | self.wait_until_idle() 120 | self._command(PANEL_SETTING, b'\xBF\x0B') # KW-BF KWR-AF BWROTP 0f 121 | self._command(PLL_CONTROL, b'\x3C') # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ 122 | 123 | def wait_until_idle(self): 124 | while self.busy.value() == BUSY: 125 | sleep_ms(100) 126 | 127 | def reset(self): 128 | self.rst(0) 129 | sleep_ms(200) 130 | self.rst(1) 131 | sleep_ms(200) 132 | 133 | def set_lut(self): 134 | self._command(LUT_FOR_VCOM, self.LUT_VCOM0) # vcom 135 | self._command(LUT_WHITE_TO_WHITE, self.LUT_WW) # ww -- 136 | self._command(LUT_BLACK_TO_WHITE, self.LUT_BW) # bw r 137 | self._command(LUT_WHITE_TO_BLACK, self.LUT_BB) # wb w 138 | self._command(LUT_BLACK_TO_BLACK, self.LUT_WB) # bb b 139 | 140 | # draw the current frame memory 141 | def display_frame(self, frame_buffer): 142 | self._command(RESOLUTION_SETTING, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 143 | self._command(VCM_DC_SETTING, b'\x12') 144 | self._command(VCOM_AND_DATA_INTERVAL_SETTING) 145 | self._command(0x97) # VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 146 | # TODO should ^ this be _data(0x97), not sure what it does 147 | 148 | if (frame_buffer != None): 149 | self._command(DATA_START_TRANSMISSION_1) 150 | for i in range(0, self.width * self.height // 8): 151 | self._data(bytearray([0xFF])) # bit set: white, bit reset: black 152 | sleep_ms(2) 153 | self._command(DATA_START_TRANSMISSION_2) 154 | for i in range(0, self.width * self.height // 8): 155 | self._data(bytearray([frame_buffer[i]])) 156 | sleep_ms(2) 157 | 158 | self.set_lut() 159 | self._command(DISPLAY_REFRESH) 160 | sleep_ms(100) 161 | self.wait_until_idle() 162 | 163 | # to wake call reset() or init() 164 | def sleep(self): 165 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x17') # border floating 166 | self._command(VCM_DC_SETTING) # VCOM to 0V 167 | self._command(PANEL_SETTING) 168 | sleep_ms(100) 169 | self._command(POWER_SETTING, b'\x00\x00\x00\x00\x00') # VG&VS to 0V fast 170 | sleep_ms(100) 171 | self._command(POWER_OFF) 172 | self.wait_until_idle() 173 | self._command(DEEP_SLEEP, b'\xA5') 174 | -------------------------------------------------------------------------------- /epaper4in2b.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 4.2" Black/White/Red GDEW042Z15 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | # also works for black/white/yellow GDEW042C37? 29 | 30 | from micropython import const 31 | from time import sleep_ms 32 | 33 | # Display resolution 34 | EPD_WIDTH = const(400) 35 | EPD_HEIGHT = const(300) 36 | 37 | # Display commands 38 | PANEL_SETTING = const(0x00) 39 | #POWER_SETTING = const(0x01) 40 | POWER_OFF = const(0x02) 41 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 42 | POWER_ON = const(0x04) 43 | #POWER_ON_MEASURE = const(0x05) 44 | BOOSTER_SOFT_START = const(0x06) 45 | DEEP_SLEEP = const(0x07) 46 | DATA_START_TRANSMISSION_1 = const(0x10) 47 | #DATA_STOP = const(0x11) 48 | DISPLAY_REFRESH = const(0x12) 49 | DATA_START_TRANSMISSION_2 = const(0x13) 50 | #VCOM_LUT = const(0x20) 51 | #W2W_LUT = const(0x21) 52 | #B2W_LUT = const(0x22) 53 | #W2B_LUT = const(0x23) 54 | #B2B_LUT = const(0x24) 55 | #PLL_CONTROL = const(0x30) 56 | #TEMPERATURE_SENSOR_CALIBRATION = const(0x40) 57 | #TEMPERATURE_SENSOR_SELECTION = const(0x41) 58 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 59 | #TEMPERATURE_SENSOR_READ = const(0x43) 60 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 61 | #LOW_POWER_DETECTION = const(0x51) 62 | #TCON_SETTING = const(0x60) 63 | #RESOLUTION_SETTING = const(0x61) 64 | #GSST_SETTING = const(0x65) 65 | #GET_STATUS = const(0x71) 66 | #AUTO_MEASURE_VCOM = const(0x80) 67 | #VCOM_VALUE = const(0x81) 68 | #VCM_DC_SETTING = const(0x82) 69 | #PARTIAL_WINDOW = const(0x90) 70 | #PARTIAL_IN = const(0x91) 71 | #PARTIAL_OUT = const(0x92) 72 | #PROGRAM_MODE = const(0xA0) 73 | #ACTIVE_PROGRAM = const(0xA1) 74 | #READ_OTP_DATA = const(0xA2) 75 | #POWER_SAVING = const(0xE3) 76 | 77 | BUSY = const(0) # 0=busy, 1=idle 78 | 79 | class EPD: 80 | def __init__(self, spi, cs, dc, rst, busy): 81 | self.spi = spi 82 | self.cs = cs 83 | self.dc = dc 84 | self.rst = rst 85 | self.busy = busy 86 | self.cs.init(self.cs.OUT, value=1) 87 | self.dc.init(self.dc.OUT, value=0) 88 | self.rst.init(self.rst.OUT, value=0) 89 | self.busy.init(self.busy.IN) 90 | self.width = EPD_WIDTH 91 | self.height = EPD_HEIGHT 92 | 93 | def _command(self, command, data=None): 94 | self.dc(0) 95 | self.cs(0) 96 | self.spi.write(bytearray([command])) 97 | self.cs(1) 98 | if data is not None: 99 | self._data(data) 100 | 101 | def _data(self, data): 102 | self.dc(1) 103 | self.cs(0) 104 | self.spi.write(data) 105 | self.cs(1) 106 | 107 | def init(self): 108 | self.reset() 109 | self._command(BOOSTER_SOFT_START, b'\x17\x17\x17') # 07 0f 17 1f 27 2F 37 2f 110 | self._command(POWER_ON) 111 | self.wait_until_idle() 112 | self._command(PANEL_SETTING, b'\x0F') # LUT from OTP 113 | 114 | def wait_until_idle(self): 115 | while self.busy.value() == BUSY: 116 | sleep_ms(100) 117 | 118 | def reset(self): 119 | self.rst(0) 120 | sleep_ms(200) 121 | self.rst(1) 122 | sleep_ms(200) 123 | 124 | # draw the current frame memory 125 | def display_frame(self, frame_buffer_black, frame_buffer_red): 126 | if (frame_buffer_black != None): 127 | self._command(DATA_START_TRANSMISSION_1) 128 | sleep_ms(2) 129 | for i in range(0, self.width * self.height // 8): 130 | self._data(bytearray([frame_buffer_black[i]])) 131 | sleep_ms(2) 132 | if (frame_buffer_red != None): 133 | self._command(DATA_START_TRANSMISSION_2) 134 | sleep_ms(2) 135 | for i in range(0, self.width * self.height // 8): 136 | self._data(bytearray([frame_buffer_red[i]])) 137 | sleep_ms(2) 138 | 139 | self._command(DISPLAY_REFRESH) 140 | self.wait_until_idle() 141 | 142 | # to wake call reset() or init() 143 | def sleep(self): 144 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\xF7') # border floating 145 | self._command(POWER_OFF) 146 | self.wait_until_idle() 147 | self._command(DEEP_SLEEP, b'\xA5') # check code 148 | -------------------------------------------------------------------------------- /epaper5in83.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 5.83" Black/White GDEW0583T7 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(600) 34 | EPD_HEIGHT = const(448) 35 | 36 | # Display commands 37 | PANEL_SETTING = const(0x00) 38 | POWER_SETTING = const(0x01) 39 | POWER_OFF = const(0x02) 40 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 41 | POWER_ON = const(0x04) 42 | #POWER_ON_MEASURE = const(0x05) 43 | BOOSTER_SOFT_START = const(0x06) 44 | DEEP_SLEEP = const(0x07) 45 | DATA_START_TRANSMISSION_1 = const(0x10) 46 | #DATA_STOP = const(0x11) 47 | DISPLAY_REFRESH = const(0x12) 48 | #IMAGE_PROCESS = const(0x13) 49 | #LUT_FOR_VCOM = const(0x20) 50 | #LUT_BLUE = const(0x21) 51 | #LUT_WHITE = const(0x22) 52 | #LUT_GRAY_1 = const(0x23) 53 | #LUT_GRAY_2 = const(0x24) 54 | #LUT_RED_0 = const(0x25) 55 | #LUT_RED_1 = const(0x26) 56 | #LUT_RED_2 = const(0x27) 57 | #LUT_RED_3 = const(0x28) 58 | #LUT_XON = const(0x29) 59 | PLL_CONTROL = const(0x30) 60 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 61 | TEMPERATURE_CALIBRATION = const(0x41) 62 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 63 | #TEMPERATURE_SENSOR_READ = const(0x43) 64 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 65 | #LOW_POWER_DETECTION = const(0x51) 66 | TCON_SETTING = const(0x60) 67 | TCON_RESOLUTION = const(0x61) 68 | #SPI_FLASH_CONTROL = const(0x65) 69 | #REVISION = const(0x70) 70 | #GET_STATUS = const(0x71) 71 | #AUTO_MEASUREMENT_VCOM = const(0x80) 72 | #READ_VCOM_VALUE = const(0x81) 73 | VCM_DC_SETTING = const(0x82) 74 | FLASH_MODE = const(0xE5) 75 | 76 | BUSY = const(0) # 0=busy, 1=idle 77 | 78 | class EPD: 79 | def __init__(self, spi, cs, dc, rst, busy): 80 | self.spi = spi 81 | self.cs = cs 82 | self.dc = dc 83 | self.rst = rst 84 | self.busy = busy 85 | self.cs.init(self.cs.OUT, value=1) 86 | self.dc.init(self.dc.OUT, value=0) 87 | self.rst.init(self.rst.OUT, value=0) 88 | self.busy.init(self.busy.IN) 89 | self.width = EPD_WIDTH 90 | self.height = EPD_HEIGHT 91 | 92 | def _command(self, command, data=None): 93 | self.dc(0) 94 | self.cs(0) 95 | self.spi.write(bytearray([command])) 96 | self.cs(1) 97 | if data is not None: 98 | self._data(data) 99 | 100 | def _data(self, data): 101 | self.dc(1) 102 | self.cs(0) 103 | self.spi.write(data) 104 | self.cs(1) 105 | 106 | def init(self): 107 | self.reset() 108 | self._command(POWER_SETTING, b'\x37\x00') 109 | self._command(PANEL_SETTING, b'\xCF\x08') 110 | self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28') 111 | self._command(POWER_ON) 112 | self.wait_until_idle() 113 | self._command(PLL_CONTROL, b'\x3C') 114 | self._command(TEMPERATURE_CALIBRATION, b'\x00') 115 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77') 116 | self._command(TCON_SETTING, b'\x22') 117 | self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 118 | self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file 119 | self._command(FLASH_MODE, b'\x03') 120 | 121 | def wait_until_idle(self): 122 | while self.busy.value() == BUSY: 123 | sleep_ms(100) 124 | 125 | def reset(self): 126 | self.rst(0) 127 | sleep_ms(200) 128 | self.rst(1) 129 | sleep_ms(200) 130 | 131 | # draw the current frame memory 132 | def display_frame(self, frame_buffer): 133 | if (frame_buffer != None): 134 | self._command(DATA_START_TRANSMISSION_1) 135 | for i in range(0, self.width * self.height // 4): 136 | temp1 = frame_buffer[i] 137 | j = 0 138 | while (j < 4): 139 | if ((temp1 & 0xC0) == 0xC0): 140 | temp2 = 0x03 141 | elif ((temp1 & 0xC0) == 0x00): 142 | temp2 = 0x00 143 | else: 144 | temp2 = 0x04 145 | temp2 = (temp2 << 4) & 0xFF 146 | temp1 = (temp1 << 2) & 0xFF 147 | j += 1 148 | if((temp1 & 0xC0) == 0xC0): 149 | temp2 |= 0x03 150 | elif ((temp1 & 0xC0) == 0x00): 151 | temp2 |= 0x00 152 | else: 153 | temp2 |= 0x04 154 | temp1 = (temp1 << 2) & 0xFF 155 | self._data(bytearray([temp2])) 156 | j += 1 157 | self._command(DISPLAY_REFRESH) 158 | sleep_ms(100) 159 | self.wait_until_idle() 160 | 161 | # to wake call reset() or init() 162 | def sleep(self): 163 | self._command(POWER_OFF) 164 | self.wait_until_idle() 165 | self._command(DEEP_SLEEP, b'\xA5') 166 | -------------------------------------------------------------------------------- /epaper5in83b.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 5.83" Black/White/Red GDEW0583Z21 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(600) 34 | EPD_HEIGHT = const(448) 35 | 36 | # Display commands 37 | PANEL_SETTING = const(0x00) 38 | POWER_SETTING = const(0x01) 39 | POWER_OFF = const(0x02) 40 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 41 | POWER_ON = const(0x04) 42 | #POWER_ON_MEASURE = const(0x05) 43 | BOOSTER_SOFT_START = const(0x06) 44 | DEEP_SLEEP = const(0x07) 45 | DATA_START_TRANSMISSION_1 = const(0x10) 46 | #DATA_STOP = const(0x11) 47 | DISPLAY_REFRESH = const(0x12) 48 | #IMAGE_PROCESS = const(0x13) 49 | #LUT_FOR_VCOM = const(0x20) 50 | #LUT_BLUE = const(0x21) 51 | #LUT_WHITE = const(0x22) 52 | #LUT_GRAY_1 = const(0x23) 53 | #LUT_GRAY_2 = const(0x24) 54 | #LUT_RED_0 = const(0x25) 55 | #LUT_RED_1 = const(0x26) 56 | #LUT_RED_2 = const(0x27) 57 | #LUT_RED_3 = const(0x28) 58 | #LUT_XON = const(0x29) 59 | PLL_CONTROL = const(0x30) 60 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 61 | TEMPERATURE_CALIBRATION = const(0x41) 62 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 63 | #TEMPERATURE_SENSOR_READ = const(0x43) 64 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 65 | #LOW_POWER_DETECTION = const(0x51) 66 | TCON_SETTING = const(0x60) 67 | TCON_RESOLUTION = const(0x61) 68 | #SPI_FLASH_CONTROL = const(0x65) 69 | #REVISION = const(0x70) 70 | #GET_STATUS = const(0x71) 71 | #AUTO_MEASUREMENT_VCOM = const(0x80) 72 | #READ_VCOM_VALUE = const(0x81) 73 | VCM_DC_SETTING = const(0x82) 74 | FLASH_MODE = const(0xE5) 75 | 76 | BUSY = const(0) # 0=busy, 1=idle 77 | 78 | class EPD: 79 | def __init__(self, spi, cs, dc, rst, busy): 80 | self.spi = spi 81 | self.cs = cs 82 | self.dc = dc 83 | self.rst = rst 84 | self.busy = busy 85 | self.cs.init(self.cs.OUT, value=1) 86 | self.dc.init(self.dc.OUT, value=0) 87 | self.rst.init(self.rst.OUT, value=0) 88 | self.busy.init(self.busy.IN) 89 | self.width = EPD_WIDTH 90 | self.height = EPD_HEIGHT 91 | 92 | def _command(self, command, data=None): 93 | self.dc(0) 94 | self.cs(0) 95 | self.spi.write(bytearray([command])) 96 | self.cs(1) 97 | if data is not None: 98 | self._data(data) 99 | 100 | def _data(self, data): 101 | self.dc(1) 102 | self.cs(0) 103 | self.spi.write(data) 104 | self.cs(1) 105 | 106 | def init(self): 107 | self.reset() 108 | self._command(POWER_SETTING, b'\x37\x00') 109 | self._command(PANEL_SETTING, b'\xCF\x08') 110 | self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28') 111 | self._command(POWER_ON) 112 | self.wait_until_idle() 113 | self._command(PLL_CONTROL, b'\x3C') 114 | self._command(TEMPERATURE_CALIBRATION, b'\x00') 115 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77') 116 | self._command(TCON_SETTING, b'\x22') 117 | self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 118 | self._command(VCM_DC_SETTING, b'\x20') # decide by LUT file 119 | self._command(FLASH_MODE, b'\x03') 120 | 121 | def wait_until_idle(self): 122 | while self.busy.value() == BUSY: 123 | sleep_ms(100) 124 | 125 | def reset(self): 126 | self.rst(0) 127 | sleep_ms(200) 128 | self.rst(1) 129 | sleep_ms(200) 130 | 131 | # draw the current frame memory 132 | def display_frame(self, frame_buffer_black, frame_buffer_red): 133 | if (frame_buffer != None and frame_buffer_red != None): 134 | self._command(DATA_START_TRANSMISSION_1) 135 | for i in range(0, self.width * self.height // 8): 136 | temp1 = frame_buffer_black[i] 137 | temp2 = frame_buffer_red[i] 138 | j = 0 139 | while (j < 8): 140 | if ((temp2 & 0x80) == 0x00): 141 | temp3 = 0x04 #red 142 | elif ((temp1 & 0x80) == 0x00): 143 | temp3 = 0x00 #black 144 | else: 145 | temp3 = 0x03 #white 146 | 147 | temp3 = (temp3 << 4) & 0xFF 148 | temp1 = (temp1 << 1) & 0xFF 149 | temp2 = (temp2 << 1) & 0xFF 150 | j += 1 151 | if ((temp2 & 0x80) == 0x00): 152 | temp3 |= 0x04 #red 153 | elif ((temp1 & 0x80) == 0x00): 154 | temp3 |= 0x00 #black 155 | else: 156 | temp3 |= 0x03 #white 157 | temp1 = (temp1 << 1) & 0xFF 158 | temp2 = (temp2 << 1) & 0xFF 159 | self._data(bytearray([temp3])) 160 | j += 1 161 | self._command(DISPLAY_REFRESH) 162 | sleep_ms(100) 163 | self.wait_until_idle() 164 | 165 | # to wake call reset() or init() 166 | def sleep(self): 167 | self._command(POWER_OFF) 168 | self.wait_until_idle() 169 | self._command(DEEP_SLEEP, b'\xA5') 170 | -------------------------------------------------------------------------------- /epaper7in5.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 7.5" Black/White GDEW075T8 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | from micropython import const 29 | from time import sleep_ms 30 | import ustruct 31 | 32 | # Display resolution 33 | EPD_WIDTH = const(640) 34 | EPD_HEIGHT = const(384) 35 | 36 | # Display commands 37 | PANEL_SETTING = const(0x00) 38 | POWER_SETTING = const(0x01) 39 | POWER_OFF = const(0x02) 40 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 41 | POWER_ON = const(0x04) 42 | #POWER_ON_MEASURE = const(0x05) 43 | BOOSTER_SOFT_START = const(0x06) 44 | DEEP_SLEEP = const(0x07) 45 | DATA_START_TRANSMISSION_1 = const(0x10) 46 | #DATA_STOP = const(0x11) 47 | DISPLAY_REFRESH = const(0x12) 48 | #IMAGE_PROCESS = const(0x13) 49 | #LUT_FOR_VCOM = const(0x20) 50 | #LUT_BLUE = const(0x21) 51 | #LUT_WHITE = const(0x22) 52 | #LUT_GRAY_1 = const(0x23) 53 | #LUT_GRAY_2 = const(0x24) 54 | #LUT_RED_0 = const(0x25) 55 | #LUT_RED_1 = const(0x26) 56 | #LUT_RED_2 = const(0x27) 57 | #LUT_RED_3 = const(0x28) 58 | #LUT_XON = const(0x29) 59 | PLL_CONTROL = const(0x30) 60 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 61 | TEMPERATURE_CALIBRATION = const(0x41) 62 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 63 | #TEMPERATURE_SENSOR_READ = const(0x43) 64 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 65 | #LOW_POWER_DETECTION = const(0x51) 66 | TCON_SETTING = const(0x60) 67 | TCON_RESOLUTION = const(0x61) 68 | #SPI_FLASH_CONTROL = const(0x65) 69 | #REVISION = const(0x70) 70 | #GET_STATUS = const(0x71) 71 | #AUTO_MEASUREMENT_VCOM = const(0x80) 72 | #READ_VCOM_VALUE = const(0x81) 73 | VCM_DC_SETTING = const(0x82) 74 | FLASH_MODE = const(0xE5) 75 | 76 | BUSY = const(0) # 0=busy, 1=idle 77 | 78 | class EPD: 79 | def __init__(self, spi, cs, dc, rst, busy): 80 | self.spi = spi 81 | self.cs = cs 82 | self.dc = dc 83 | self.rst = rst 84 | self.busy = busy 85 | self.cs.init(self.cs.OUT, value=1) 86 | self.dc.init(self.dc.OUT, value=0) 87 | self.rst.init(self.rst.OUT, value=0) 88 | self.busy.init(self.busy.IN) 89 | self.width = EPD_WIDTH 90 | self.height = EPD_HEIGHT 91 | 92 | def _command(self, command, data=None): 93 | self.dc(0) 94 | self.cs(0) 95 | self.spi.write(bytearray([command])) 96 | self.cs(1) 97 | if data is not None: 98 | self._data(data) 99 | 100 | def _data(self, data): 101 | self.dc(1) 102 | self.cs(0) 103 | self.spi.write(data) 104 | self.cs(1) 105 | 106 | def init(self): 107 | self.reset() 108 | self._command(POWER_SETTING, b'\x37\x00') 109 | self._command(PANEL_SETTING, b'\xCF\x08') 110 | self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28') 111 | self._command(POWER_ON) 112 | self.wait_until_idle() 113 | self._command(PLL_CONTROL, b'\x3C') 114 | self._command(TEMPERATURE_CALIBRATION, b'\x00') 115 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77') 116 | self._command(TCON_SETTING, b'\x22') 117 | self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 118 | self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file 119 | self._command(FLASH_MODE, b'\x03') 120 | 121 | def wait_until_idle(self): 122 | while self.busy.value() == BUSY: 123 | sleep_ms(100) 124 | 125 | def reset(self): 126 | self.rst(0) 127 | sleep_ms(200) 128 | self.rst(1) 129 | sleep_ms(200) 130 | 131 | # draw the current frame memory 132 | def display_frame(self, frame_buffer): 133 | self._command(DATA_START_TRANSMISSION_1) 134 | for i in range(0, self.width * self.height // 8): 135 | temp1 = frame_buffer[i] 136 | j = 0 137 | while (j < 8): 138 | if (temp1 & 0x80): 139 | temp2 = 0x03 140 | else: 141 | temp2 = 0x00 142 | temp2 = (temp2 << 4) & 0xFF 143 | temp1 = (temp1 << 1) & 0xFF 144 | j += 1 145 | if (temp1 & 0x80): 146 | temp2 |= 0x03 147 | else: 148 | temp2 |= 0x00 149 | temp1 = (temp1 << 1) & 0xFF 150 | self._data(bytearray([temp2])) 151 | j += 1 152 | self._command(DISPLAY_REFRESH) 153 | sleep_ms(100) 154 | self.wait_until_idle() 155 | 156 | # to wake call reset() or init() 157 | def sleep(self): 158 | self._command(POWER_OFF) 159 | self.wait_until_idle() 160 | self._command(DEEP_SLEEP, b'\xA5') 161 | -------------------------------------------------------------------------------- /epaper7in5b.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Waveshare 7.5" Black/White/Red GDEW075Z09 e-paper display driver 3 | https://github.com/mcauser/micropython-waveshare-epaper 4 | 5 | MIT License 6 | Copyright (c) 2017 Waveshare 7 | Copyright (c) 2018 Mike Causer 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | """ 27 | 28 | # also works for black/white/yellow GDEW075C21? 29 | 30 | from micropython import const 31 | from time import sleep_ms 32 | import ustruct 33 | 34 | # Display resolution 35 | EPD_WIDTH = const(640) 36 | EPD_HEIGHT = const(384) 37 | 38 | # Display commands 39 | PANEL_SETTING = const(0x00) 40 | POWER_SETTING = const(0x01) 41 | POWER_OFF = const(0x02) 42 | #POWER_OFF_SEQUENCE_SETTING = const(0x03) 43 | POWER_ON = const(0x04) 44 | #POWER_ON_MEASURE = const(0x05) 45 | BOOSTER_SOFT_START = const(0x06) 46 | DEEP_SLEEP = const(0x07) 47 | DATA_START_TRANSMISSION_1 = const(0x10) 48 | #DATA_STOP = const(0x11) 49 | DISPLAY_REFRESH = const(0x12) 50 | #IMAGE_PROCESS = const(0x13) 51 | #LUT_FOR_VCOM = const(0x20) 52 | #LUT_BLUE = const(0x21) 53 | #LUT_WHITE = const(0x22) 54 | #LUT_GRAY_1 = const(0x23) 55 | #LUT_GRAY_2 = const(0x24) 56 | #LUT_RED_0 = const(0x25) 57 | #LUT_RED_1 = const(0x26) 58 | #LUT_RED_2 = const(0x27) 59 | #LUT_RED_3 = const(0x28) 60 | #LUT_XON = const(0x29) 61 | PLL_CONTROL = const(0x30) 62 | #TEMPERATURE_SENSOR_COMMAND = const(0x40) 63 | TEMPERATURE_CALIBRATION = const(0x41) 64 | #TEMPERATURE_SENSOR_WRITE = const(0x42) 65 | #TEMPERATURE_SENSOR_READ = const(0x43) 66 | VCOM_AND_DATA_INTERVAL_SETTING = const(0x50) 67 | #LOW_POWER_DETECTION = const(0x51) 68 | TCON_SETTING = const(0x60) 69 | TCON_RESOLUTION = const(0x61) 70 | #SPI_FLASH_CONTROL = const(0x65) 71 | #REVISION = const(0x70) 72 | #GET_STATUS = const(0x71) 73 | #AUTO_MEASUREMENT_VCOM = const(0x80) 74 | #READ_VCOM_VALUE = const(0x81) 75 | VCM_DC_SETTING = const(0x82) 76 | FLASH_MODE = const(0xE5) 77 | 78 | BUSY = const(0) # 0=busy, 1=idle 79 | 80 | class EPD: 81 | def __init__(self, spi, cs, dc, rst, busy): 82 | self.spi = spi 83 | self.cs = cs 84 | self.dc = dc 85 | self.rst = rst 86 | self.busy = busy 87 | self.cs.init(self.cs.OUT, value=1) 88 | self.dc.init(self.dc.OUT, value=0) 89 | self.rst.init(self.rst.OUT, value=0) 90 | self.busy.init(self.busy.IN) 91 | self.width = EPD_WIDTH 92 | self.height = EPD_HEIGHT 93 | 94 | def _command(self, command, data=None): 95 | self.dc(0) 96 | self.cs(0) 97 | self.spi.write(bytearray([command])) 98 | self.cs(1) 99 | if data is not None: 100 | self._data(data) 101 | 102 | def _data(self, data): 103 | self.dc(1) 104 | self.cs(0) 105 | self.spi.write(data) 106 | self.cs(1) 107 | 108 | def init(self): 109 | self.reset() 110 | self._command(POWER_SETTING, b'\x37\x00') 111 | self._command(PANEL_SETTING, b'\xCF\x08') 112 | self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28') 113 | self._command(POWER_ON) 114 | self.wait_until_idle() 115 | self._command(PLL_CONTROL, b'\x3C') 116 | self._command(TEMPERATURE_CALIBRATION, b'\x00') 117 | self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77') 118 | self._command(TCON_SETTING, b'\x22') 119 | self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT)) 120 | self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file 121 | self._command(FLASH_MODE, b'\x03') 122 | 123 | def wait_until_idle(self): 124 | while self.busy.value() == BUSY: 125 | sleep_ms(100) 126 | 127 | def reset(self): 128 | self.rst(0) 129 | sleep_ms(200) 130 | self.rst(1) 131 | sleep_ms(200) 132 | 133 | # draw the current frame memory 134 | def display_frame(self, frame_buffer): 135 | self._command(DATA_START_TRANSMISSION_1) 136 | for i in range(0, self.width * self.height // 4): 137 | temp1 = frame_buffer[i] 138 | j = 0 139 | while (j < 4): 140 | if ((temp1 & 0xC0) == 0xC0): 141 | temp2 = 0x03 142 | elif ((temp1 & 0xC0) == 0x00): 143 | temp2 = 0x00 144 | else: 145 | temp2 = 0x04 146 | temp2 = (temp2 << 4) & 0xFF 147 | temp1 = (temp1 << 2) & 0xFF 148 | j += 1 149 | if ((temp1 & 0xC0) == 0xC0): 150 | temp2 |= 0x03 151 | elif ((temp1 & 0xC0) == 0x00): 152 | temp2 |= 0x00 153 | else: 154 | temp2 |= 0x04 155 | temp1 = (temp1 << 2) & 0xFF 156 | self._data(bytearray([temp2])) 157 | j += 1 158 | self._command(DISPLAY_REFRESH) 159 | sleep_ms(100) 160 | self.wait_until_idle() 161 | 162 | # to wake call reset() or init() 163 | def sleep(self): 164 | self._command(POWER_OFF) 165 | self.wait_until_idle() 166 | self._command(DEEP_SLEEP, b'\xA5') 167 | -------------------------------------------------------------------------------- /examples/2in9-hello-world/hello-world-white.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcauser/micropython-waveshare-epaper/24c454cdd004c273d8dc3349ec365e87dec371ea/examples/2in9-hello-world/hello-world-white.bmp -------------------------------------------------------------------------------- /examples/2in9-hello-world/hello-world-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcauser/micropython-waveshare-epaper/24c454cdd004c273d8dc3349ec365e87dec371ea/examples/2in9-hello-world/hello-world-white.png -------------------------------------------------------------------------------- /examples/2in9-hello-world/hello-world.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcauser/micropython-waveshare-epaper/24c454cdd004c273d8dc3349ec365e87dec371ea/examples/2in9-hello-world/hello-world.bmp -------------------------------------------------------------------------------- /examples/2in9-hello-world/hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcauser/micropython-waveshare-epaper/24c454cdd004c273d8dc3349ec365e87dec371ea/examples/2in9-hello-world/hello-world.png -------------------------------------------------------------------------------- /examples/2in9-hello-world/image_dark.py: -------------------------------------------------------------------------------- 1 | # "hello world", rotated 90 deg, black bg, white text 2 | # 128 x 296 3 | hello_world_dark = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF7\xDF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE3\xC3\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE3\xC1\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC1\xE0\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC1\xE0\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x81\xF0\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\xF0\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\xF8\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x78\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x7C\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x3C\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x3E\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x3F\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x1F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x1F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xE0\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x07\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF8\x03\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x03\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x00\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x03\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x03\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x00\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x03\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x01\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x01\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x01\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 4 | -------------------------------------------------------------------------------- /examples/2in9-hello-world/image_light.py: -------------------------------------------------------------------------------- 1 | # "hello world", rotated 90 deg, white bg, black text 2 | # 128 x 296 3 | hello_world_light = bytearray(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x08\x20\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1C\x3C\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1C\x3E\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3E\x1F\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3E\x1F\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7E\x0F\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x0F\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x07\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x87\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x83\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xC3\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xC1\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xC0\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xE0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xE0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x1F\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xF8\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x07\xFC\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x8F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFC\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFF\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xFC\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFC\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFF\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xFC\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFE\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFE\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x7F\xFF\xFE\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF') 4 | -------------------------------------------------------------------------------- /examples/2in9-hello-world/test.py: -------------------------------------------------------------------------------- 1 | import epaper2in9 2 | from pyb import SPI 3 | 4 | # SPI3 on Black STM32F407VET6 5 | spi = SPI(3, SPI.MASTER, baudrate=2000000, polarity=0, phase=0) 6 | cs = pyb.Pin('PB6') 7 | dc = pyb.Pin('PB7') 8 | rst = pyb.Pin('PB8') 9 | busy = pyb.Pin('PB9') 10 | 11 | e = epaper2in9.EPD(spi, cs, dc, rst, busy) 12 | e.init() 13 | 14 | w = 128 15 | h = 296 16 | x = 0 17 | y = 0 18 | 19 | # -------------------- 20 | 21 | # write hello world with black bg and white text 22 | from image_dark import hello_world_dark 23 | e.clear_frame_memory(b'\xFF') 24 | e.set_frame_memory(hello_world_dark, x, y, w, h) 25 | e.display_frame() 26 | 27 | # -------------------- 28 | 29 | # write hello world with white bg and black text 30 | from image_light import hello_world_light 31 | e.clear_frame_memory(b'\xFF') 32 | e.set_frame_memory(hello_world_light, x, y, w, h) 33 | e.display_frame() 34 | 35 | # -------------------- 36 | 37 | # clear display 38 | e.clear_frame_memory(b'\xFF') 39 | e.display_frame() 40 | 41 | # use a frame buffer 42 | # 128 * 296 / 8 = 4736 - thats a lot of pixels 43 | import framebuf 44 | buf = bytearray(128 * 296 // 8) 45 | fb = framebuf.FrameBuffer(buf, 128, 296, framebuf.MONO_HLSB) 46 | black = 0 47 | white = 1 48 | fb.fill(white) 49 | fb.text('Hello World',30,0,black) 50 | fb.pixel(30, 10, black) 51 | fb.hline(30, 30, 10, black) 52 | fb.vline(30, 50, 10, black) 53 | fb.line(30, 70, 40, 80, black) 54 | fb.rect(30, 90, 10, 10, black) 55 | fb.fill_rect(30, 110, 10, 10, black) 56 | for row in range(0,37): 57 | fb.text(str(row),0,row*8,black) 58 | fb.text('Line 36',0,288,black) 59 | e.set_frame_memory(buf, x, y, w, h) 60 | e.display_frame() 61 | 62 | # -------------------- 63 | 64 | # wrap text inside a box 65 | import framebuf 66 | buf = bytearray(128 * 296 // 8) 67 | fb = framebuf.FrameBuffer(buf, 128, 296, framebuf.MONO_HLSB) 68 | black = 0 69 | white = 1 70 | # clear 71 | fb.fill(white) 72 | e.set_frame_memory(buf, x, y, w, h) 73 | e.display_frame() 74 | # display as much as this as fits in the box 75 | str = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vel neque in elit tristique vulputate at et dui. Maecenas nec felis lectus. Pellentesque sit amet facilisis dui. Maecenas ac arcu euismod, tempor massa quis, ultricies est.' 76 | 77 | # this could be useful as a new method in FrameBuffer 78 | def text_wrap(str,x,y,color,w,h,border=None): 79 | # optional box border 80 | if border is not None: 81 | fb.rect(x, y, w, h, border) 82 | cols = w // 8 83 | # for each row 84 | j = 0 85 | for i in range(0, len(str), cols): 86 | # draw as many chars fit on the line 87 | fb.text(str[i:i+cols], x, y + j, color) 88 | j += 8 89 | # dont overflow text outside the box 90 | if j >= h: 91 | break 92 | 93 | # clear 94 | fb.fill(white) 95 | 96 | # draw text box 1 97 | # box position and dimensions 98 | bx = 8 99 | by = 8 100 | bw = w - 16 # 112 = 14 cols 101 | bh = w - 16 # 112 = 14 rows (196 chars in total) 102 | text_wrap(str,bx,by,black,bw,bh,black) 103 | e.set_frame_memory(buf, x, y, w, h) 104 | e.display_frame() 105 | 106 | # draw text box 2 107 | bx = 0 108 | by = 128 109 | bw = w # 128 = 16 cols 110 | bh = 6 * 8 # 48 = 6 rows (96 chars in total) 111 | text_wrap(str,bx,by,black,bw,bh,black) 112 | e.set_frame_memory(buf, x, y, w, h) 113 | e.display_frame() 114 | 115 | # draw text box 3 116 | bx = 0 117 | by = 184 118 | bw = w//2 # 64 = 8 cols 119 | bh = 8 * 8 # 64 = 8 rows (64 chars in total) 120 | text_wrap(str,bx,by,black,bw,bh,None) 121 | e.set_frame_memory(buf, x, y, w, h) 122 | e.display_frame() 123 | 124 | # -------------------- 125 | -------------------------------------------------------------------------------- /examples/4in2-hello-world/image_dark.py: -------------------------------------------------------------------------------- 1 | # "hello world", rotated 90 deg, black bg, white text 2 | # 128 x 296 3 | hello_world_dark = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF7\xDF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE3\xC3\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE3\xC1\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC1\xE0\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC1\xE0\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x81\xF0\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\xF0\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\xF8\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x78\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x7C\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x3C\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x3E\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x3F\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x1F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x1F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xE0\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x07\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF8\x03\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x03\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x00\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x03\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x0F\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x03\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x00\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x03\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFC\x07\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x01\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x7E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x80\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xC0\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xC0\x00\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xE0\x00\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xF0\x01\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x01\xFF\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') 4 | -------------------------------------------------------------------------------- /examples/4in2-hello-world/image_light.py: -------------------------------------------------------------------------------- 1 | # "hello world", rotated 90 deg, white bg, black text 2 | # 128 x 296 3 | hello_world_light = bytearray(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x08\x20\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1C\x3C\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1C\x3E\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3E\x1F\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3E\x1F\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7E\x0F\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x0F\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x07\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x87\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\x83\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xC3\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xC1\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xC0\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xE0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xE0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x1F\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xF8\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x07\xFC\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x8F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFC\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFF\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xFC\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xF0\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFC\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFF\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xFC\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x03\xF8\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFE\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x7F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x3F\xFF\xC1\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x3F\xFF\x83\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x1F\xFF\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x0F\xFE\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x00\x00\x00\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF0\x00\x00\x00\x00\x07\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xF8\x7F\xFF\xFE\x00\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF') 4 | -------------------------------------------------------------------------------- /examples/4in2-hello-world/test.py: -------------------------------------------------------------------------------- 1 | """ 2 | Example for 4.2 inch black & white Waveshare E-ink screen 3 | Run on ESP32 4 | """ 5 | 6 | import epaper4in2 7 | from machine import Pin, SPI 8 | 9 | # SPIV on ESP32 10 | sck = Pin(18) 11 | miso = Pin(19) 12 | mosi = Pin(23) 13 | dc = Pin(32) 14 | cs = Pin(33) 15 | rst = Pin(19) 16 | busy = Pin(35) 17 | spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=sck, miso=miso, mosi=mosi) 18 | 19 | e = epaper4in2.EPD(spi, cs, dc, rst, busy) 20 | e.init() 21 | 22 | w = 400 23 | h = 300 24 | x = 0 25 | y = 0 26 | 27 | # -------------------- 28 | 29 | # use a frame buffer 30 | # 400 * 300 / 8 = 15000 - thats a lot of pixels 31 | import framebuf 32 | buf = bytearray(w * h // 8) 33 | fb = framebuf.FrameBuffer(buf, w, h, framebuf.MONO_HLSB) 34 | black = 0 35 | white = 1 36 | fb.fill(white) 37 | 38 | # -------------------- 39 | 40 | # write hello world with black bg and white text 41 | from image_dark import hello_world_dark 42 | from image_light import hello_world_light 43 | print('Image dark') 44 | bufImage = hello_world_dark 45 | fbImage = framebuf.FrameBuffer(bufImage, 128, 296, framebuf.MONO_HLSB) 46 | fb.blit(fbImage, 20, 2) 47 | bufImage = hello_world_light 48 | fbImage = framebuf.FrameBuffer(bufImage, 128, 296, framebuf.MONO_HLSB) 49 | fb.blit(fbImage, 168, 2) 50 | e.display_frame(buf) 51 | 52 | # -------------------- 53 | 54 | # write hello world with white bg and black text 55 | print('Image light') 56 | #e.display_frame(hello_world_light) 57 | 58 | # -------------------- 59 | 60 | 61 | print('Frame buffer things') 62 | fb.fill(white) 63 | fb.text('Hello World',30,0,black) 64 | fb.pixel(30, 10, black) 65 | fb.hline(30, 30, 10, black) 66 | fb.vline(30, 50, 10, black) 67 | fb.line(30, 70, 40, 80, black) 68 | fb.rect(30, 90, 10, 10, black) 69 | fb.fill_rect(30, 110, 10, 10, black) 70 | for row in range(0,36): 71 | fb.text(str(row),0,row*8,black) 72 | fb.text('Line 36',0,288,black) 73 | e.display_frame(buf) 74 | 75 | # -------------------- 76 | 77 | # wrap text inside a box 78 | black = 0 79 | white = 1 80 | # clear 81 | fb.fill(white) 82 | # display as much as this as fits in the box 83 | str = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vel neque in elit tristique vulputate at et dui. Maecenas nec felis lectus. Pellentesque sit amet facilisis dui. Maecenas ac arcu euismod, tempor massa quis, ultricies est.' 84 | 85 | # this could be useful as a new method in FrameBuffer 86 | def text_wrap(str,x,y,color,w,h,border=None): 87 | # optional box border 88 | if border is not None: 89 | fb.rect(x, y, w, h, border) 90 | cols = w // 8 91 | # for each row 92 | j = 0 93 | for i in range(0, len(str), cols): 94 | # draw as many chars fit on the line 95 | fb.text(str[i:i+cols], x, y + j, color) 96 | j += 8 97 | # dont overflow text outside the box 98 | if j >= h: 99 | break 100 | 101 | # clear 102 | fb.fill(white) 103 | 104 | # draw text box 1 105 | # box position and dimensions 106 | print('Box 1') 107 | bx = 8 108 | by = 8 109 | bw = 112 # = 14 cols 110 | bh = 112 # = 14 rows (196 chars in total) 111 | text_wrap(str,bx,by,black,bw,bh,black) 112 | e.display_frame(buf) 113 | 114 | # draw text box 2 115 | print('Box 2 & 3') 116 | bx = 0 117 | by = 128 118 | bw = w # 128 = 16 cols 119 | bh = 6 * 8 # 48 = 6 rows (96 chars in total) 120 | text_wrap(str,bx,by,black,bw,bh,black) 121 | 122 | # draw text box 3 123 | bx = 0 124 | by = 184 125 | bw = w//2 # 64 = 8 cols 126 | bh = 8 * 8 # 64 = 8 rows (64 chars in total) 127 | text_wrap(str,bx,by,black,bw,bh,None) 128 | e.display_frame(buf) 129 | 130 | # -------------------- 131 | --------------------------------------------------------------------------------