# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import digitalio import busio import board from adafruit_epd.epd import Adafruit_EPD from adafruit_epd.il0373 import Adafruit_IL0373 from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import from adafruit_epd.ssd1680 import Adafruit_SSD1680 # pylint: disable=unused-import from adafruit_epd.ssd1681 import Adafruit_SSD1681 # pylint: disable=unused-import from adafruit_epd.uc8151d import Adafruit_UC8151D # pylint: disable=unused-import # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) ecs = digitalio.DigitalInOut(board.D10) dc = digitalio.DigitalInOut(board.D9) srcs = digitalio.DigitalInOut(board.D7) # can be None to use internal memory rst = digitalio.DigitalInOut(board.D11) # can be None to not use this pin busy = digitalio.DigitalInOut(board.D12) # can be None to not use this pin # give them all to our driver print("Creating display") # display = Adafruit_SSD1608(200, 200, # 1.54" HD mono display # display = Adafruit_SSD1675(122, 250, # 2.13" HD mono display # display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color display # display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display # display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display # display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display # display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display # display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display # display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display display = Adafruit_IL0373( 104, 212, # 2.13" Tri-color display spi, cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy, ) # IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines! # display.set_black_buffer(1, False) # display.set_color_buffer(1, False) # IF YOU HAVE A 2.9" FLEXIBLE DISPLAY uncomment these lines! # display.set_black_buffer(1, True) # display.set_color_buffer(1, True) display.rotation = 0 FILENAME = "blinka.bmp" def read_le(s): # as of this writting, int.from_bytes does not have LE support, DIY! result = 0 shift = 0 for byte in bytearray(s): result += byte << shift shift += 8 return result class BMPError(Exception): pass def display_bitmap(epd, filename): # pylint: disable=too-many-locals, too-many-branches try: f = open(filename, "rb") # pylint: disable=consider-using-with except OSError: print("Couldn't open file") return print("File opened") try: if f.read(2) != b"BM": # check signature raise BMPError("Not BitMap file") bmpFileSize = read_le(f.read(4)) f.read(4) # Read & ignore creator bytes bmpImageoffset = read_le(f.read(4)) # Start of image data headerSize = read_le(f.read(4)) bmpWidth = read_le(f.read(4)) bmpHeight = read_le(f.read(4)) flip = True print( "Size: %d\nImage offset: %d\nHeader size: %d" % (bmpFileSize, bmpImageoffset, headerSize) ) print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight)) if read_le(f.read(2)) != 1: raise BMPError("Not singleplane") bmpDepth = read_le(f.read(2)) # bits per pixel print("Bit depth: %d" % (bmpDepth)) if bmpDepth != 24: raise BMPError("Not 24-bit") if read_le(f.read(2)) != 0: raise BMPError("Compressed file") print("Image OK! Drawing...") rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary for row in range(bmpHeight): # For each scanline... if flip: # Bitmap is stored bottom-to-top order (normal BMP) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize else: # Bitmap is stored top-to-bottom pos = bmpImageoffset + row * rowSize # print ("seek to %d" % pos) f.seek(pos) rowdata = f.read(3 * bmpWidth) for col in range(bmpWidth): b, g, r = rowdata[3 * col : 3 * col + 3] # BMP files store RGB in BGR if r < 0x80 and g < 0x80 and b < 0x80: epd.pixel(col, row, Adafruit_EPD.BLACK) elif r >= 0x80 and g >= 0x80 and b >= 0x80: pass # epd.pixel(row, col, Adafruit_EPD.WHITE) elif r >= 0x80: epd.pixel(col, row, Adafruit_EPD.RED) except OSError: print("Couldn't read file") except BMPError as e: print("Failed to parse BMP: " + e.args[0]) finally: f.close() print("Finished drawing") # clear the buffer display.fill(Adafruit_EPD.WHITE) display_bitmap(display, FILENAME) display.display()