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 from adafruit_epd.il0398 import Adafruit_IL0398 # 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_IL91874(176, 264, spi, # 2.7" Tri-color display #display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display #display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display #display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) # IF YOU HAVE A FLEXIBLE DISPLAY (2.13" or 2.9") uncomment these lines! #display.set_black_buffer(1, False) #display.set_color_buffer(1, False) display.rotation = 3 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): try: f = open("/" + filename, "rb") 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... print(row) 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()