Updating Board Design

Choosing A Microcontroller

Since I have two different boards for the driver-side electronics and back-of-car electronics, I need to choose an appropriate microcontroller to design a second board with.

This forum revealed to me that the ESP32-C3 isn't suitable for controlling servo motors.

In hindsight, it's good that I designed my first board with a microcontroller that can use WiFi and Bluetooth because some part of the board will need to communicate the custom message to display on the screen, which can be updated remotely from an app or website. I might also want to consider handling this functionality on the other board, but I feel it's not necessary.

Prompt

I'm designing a PCB board to control a servo motor, an e-paper/e-ink LCD display, and receive signals  over bluetooth (or wifi - they won't be connected to internet so bluetooth is probably a better idea). I am trying to use a microcontroller. I originally was going to use the ESP32-C3 because of the built in bluetooth and wifi, but read some forum posts which revealed that it's not great at controlling a servo motor. I also want to use an integrated circuit and not an arduino or raspberry pi pico, but a board, for example, like the XIAO Seeed rp2040 or an ATTINYMEGA/ATTINY. What do you recommend? Also comment on any choices I've described to you and provide feedback for anything that's not a well-warranted decision or explain why my choices are logical.

Response

Your requirement to control a servo motor, an e-paper/e-ink LCD display, and receive signals over Bluetooth (or WiFi) can be achieved using various microcontroller options. Since you prefer not to use an Arduino or Raspberry Pi Pico, I will recommend a few alternatives.

STM32 microcontrollers: STM32 microcontrollers, particularly the STM32F series (e.g., STM32F103C8T6), offer a good balance of performance, power efficiency, and a variety of peripherals. They can handle servo motor control, e-paper/e-ink displays, and can be paired with a separate Bluetooth module (e.g., HC-05) for communication. You can find various STM32 development boards, such as the Blue Pill, that can be programmed using the Arduino IDE or other development environments.

nRF52 series microcontrollers: The nRF52832 and nRF52840 are ARM Cortex-M4-based microcontrollers with built-in Bluetooth Low Energy (BLE) capabilities. They have sufficient processing power and peripherals to control a servo motor and e-paper/e-ink displays. They are designed for low-power applications, which might be beneficial if power consumption is a concern.

ATSAMD21/51 microcontrollers: These microcontrollers from Microchip (previously Atmel) are ARM Cortex-M0+/M4 based and have good performance for controlling servo motors and e-paper/e-ink displays. You can pair them with an HC-05 Bluetooth module for communication. The Adafruit Feather M0/M4 boards use these microcontrollers, and you can find a variety of examples for controlling peripherals and communication.

Regarding your original choice of ESP32-C3, it is true that it might not be the best option for precise servo motor control due to the

Prompt

pick up where you left off

Response

Due to the fact that ESP32-C3 uses an RISC-V based core, it might not be the best option for precise servo motor control as it can have timing-related challenges. It is also designed with WiFi and Bluetooth connectivity as its primary focus, which can be overkill if you only require Bluetooth communication.

In summary, based on your requirements, I would recommend considering STM32 microcontrollers, nRF52 series microcontrollers, or ATSAMD21/51 microcontrollers as potential options for your PCB board design. These microcontrollers provide sufficient processing power and peripherals to handle servo motor control, e-paper/e-ink displays, and can be paired with a separate Bluetooth module for communication.

Ensure that you verify the specific peripherals and communication interfaces required for your chosen e-paper/e-ink display, servo motor, and Bluetooth module, and make sure the selected microcontroller supports those interfaces. Additionally, consider factors such as power consumption, form factor, and the availability of development resources, libraries, and community support when making your decision.

Prompt

This servo motor which moves the display needs to move the display onto the back window of a car, from the inside. How to you recommend I mount it?

Response

Mounting a servo motor to move a display inside a car can be done in a few steps. I will outline a general approach, but please note that the specific details may vary depending on the make and model of your car, the size and weight of the display, and the type of servo motor you are using.

Determine the best mounting location: Choose a location on the inside of the car's back window where the servo motor can be securely mounted and has sufficient space for the display to move. Make sure there are no obstructions and the window is not tinted in a way that would hinder the visibility of the display.

Design a mounting bracket: Create a custom mounting bracket that can securely hold the servo motor and attach it to the car's interior. The bracket should be made from a durable, lightweight material like aluminum or a strong plastic. The design should also consider cable management for the servo motor, display, and any other required connections.

Attach the mounting bracket: Attach the mounting bracket to the car's interior using strong adhesives, like automotive-grade double-sided tape or adhesive sealant, or by using screws or other fasteners if the car's design allows for it. Ensure that the mounting is secure and does not interfere with any other vehicle functions.

Attach the servo motor to the bracket: Secure the servo motor to the mounting bracket using screws, bolts, or other suitable fasteners. Make sure the servo motor is positioned correctly to move the display as desired.

5

It didn't finish its response for the last prompt, but that's fine since it advise was far to general to be helpful.

The responses for the microcontroller suggestion were helpful, though.

I took a look at Florian Becker and asked ChatGPT 4.0 somre more questions.

Prompt

which of the three suggested microcontrollers should i use

Response

Selecting the most suitable microcontroller from the three suggested options depends on your specific requirements, priorities, and design constraints. I will provide a brief comparison to help you decide:

STM32 microcontrollers: STM32 microcontrollers, particularly the STM32F series, offer a good balance of performance, power efficiency, and a variety of peripherals. They are widely used in the maker community, and you can find extensive resources, libraries, and examples for various applications. If you want a powerful, well-supported microcontroller and don't mind adding a separate Bluetooth module, the STM32 is a solid choice.

nRF52 series microcontrollers: The nRF52832 and nRF52840 are ARM Cortex-M4-based microcontrollers with built-in Bluetooth Low Energy (BLE) capabilities. They are particularly suitable for low-power applications, and their integrated BLE support simplifies the design. If power consumption is a concern or you prefer an integrated Bluetooth solution, the nRF52 series is an excellent option.

ATSAMD21/51 microcontrollers: These microcontrollers from Microchip (previously Atmel) are ARM Cortex-M0+/M4 based and have good performance for controlling peripherals. They are less powerful than STM32 microcontrollers but still provide sufficient resources for your application. If you are already familiar with Atmel microcontrollers or prefer a lower-cost solution, consider the ATSAMD21/51 microcontrollers

I decided on a STM32F series board and found this Instructables tutorial on how to wire and program an e-paper/e-ink display to the microcontroller. I also downloaded this EagleCAD library and imported it into Fusion 360.

I found this site which explains naming conventions for the STM32 boards.

STM32 Naming Convention

In the EagleCAD library I saw four boards:

  • STM32F10XCXT6
  • STM32F10XRXT6
  • STM32F10XTXU6
  • STM32F10XVXT6

I decided on the first board, STM32F10XCXT6, since it has the least number of pins (from what I could tell in the EagleCAD schematic) and is surface-mount where the pin headers are exposed (unlike the STM32F10XTXU6).

Hidden Headers

Pins Exposed

When I put the component in my schematic I at first only saw a small portion of the pins from one port. I then realized that if I kept added components the other pins would be added. I was quickly overwhelmed by the amount of boards and decided to switch to one with less pins.

STM32 Schematic

Based on the Instructable I decided to assign different pins on a 2x5 SMD pin header I found (PINHD-2X5-SMD in the fab library) to the following.

Header Pin STM32 Pin
1 SDA
2 SCL
3 CS
4 DC
5 RST
6 BU
7 BS

Wired Schematic STM32

Auto-Routed

I realized this chip has even more pins than an RP2040 (ATTINY328P) so I may as well just use that one. I could also use that XIAO Seeed RP2040 but am worried it won't have enough pins. This example confirms my worries.

XIAO Seeed to e-Paper

I instead decided to use an ATTINY328P-AN. The DigiKey site linked to this page where I could download a component that I thought I could import into EagleCAD (I selected the Eaglecad6 Library format in the DigiKey download). That format didn't work so I selected Fusion360 PCB which gave an LBR file, as needed.

After talking to Mr. Dubick, I decided to use a Raspberry Pi Pico which allows for me to more easily use an RP2040 with a lot of pins. I downloaded the EagleCAD library here. I used this of the three components since it was the entire Pico board (not just the RP2040 microprocessor) and is surface mount.

Pico Component

I also found this schematic for an e-paper HAT driver linked on this page from this website. I also found this post which compares different methods of operating the e-paper display, and I also skimmed this article.

This website confirmed that SPI communication can be achieved with the Raspberry Pi Pico, and this tutorial eloborates on how to implement it. I also learned that there's a specific HAT driver for a smaller e-paper display designed for the Pico, which is concerned as to whether it's possible to use the Pico to operate a larger display. This website suggested a potential wiring for Arduino to talk to the driver. Here is a detailed pinout sheet for the Pico and here is a detailed pinout sheet for the Arduino Uno.

I then watched this tutorial to gain a better understanding of e-paper displays. This revealed to me that the other wiring I got wasn't correct.

I wasn't sure whether my display was a 7.5", 7.5"B, or 7.5"C display, so I guessed 7.5" for now. I then downloaded a zip file of the code. I copied the epd7in5 folder in the 7.5in display folder to the Arduino Library folder (C:\Users\*YOUR_USER*\Documents\Arduino\libraries). Then it appeared in the Arduino IDE!

Epd Library Arduino IDE

I clicked in which added the following to the top of my code.

#include <epd7in5.h>
#include <epdif.h>

I then went to File > Examples > epd7in5 > epd7in5-demo but got an error that the path didn't exist. I then realized that this used a different address (which I accidentally put the library in before) so I wanted to copy the folder there, as well. But before I did that, I tried again, clicking the library under Examples from Custom Libraries and the example opened! I uploaded the code but got the following error.

:\Users\*USER*\AppData\Local\Temp\.arduinoIDE-unsaved2023223-2744-55l82c.2wca4\epd7in5-demo\imagedata.cpp:27:10: fatal error: avr/pgmspace.h: No such file or directory
 #include <avr/pgmspace.h>
          ^~~~~~~~~~~~~~~~
compilation terminated.

Using library SPI at version 2.0.0 in folder: C:\Users\*USER*\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.7\libraries\SPI 
Using library epd7in5 at version 1.0 in folder: C:\Users\*USER*\Documents\Arduino\libraries\epd7in5 
exit status 1

Compilation error: avr/pgmspace.h: No such file or directory

This site recommended that I simply commented out this include statement, so I changed the top of imagedata.cpp to the following.

#include "imagedata.h"
//#include <avr/pgmspace.h>

The same post later suggested that I change it to the following, and the compilation was successful, but I got an error that I forgot to select a port. I also changed the board to Arduino Uno.

#include "imagedata.h"
//#include <avr/pgmspace.h>
#if defined(AVR)
#include <avr/pgmspace.h>
#else  //defined(AVR)
#include <pgmspace.h>
#endif  //defined(AVR)

I then got an error that the sketch was too large.

Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
Sketch uses 33522 bytes (103%) of program storage space. Maximum is 32256 bytes.
Global variables use 185 bytes (9%) of dynamic memory, leaving 1863 bytes for local variables. Maximum is 2048 bytes.
text section exceeds available space in board

Compilation error: text section exceeds available space in board

I then tried to use an Arduino Mega 2560 that had more memory. I was able to upload the sketch but nothing happened on the screen. I tried directly connecting the screen to the hat without the long ribbon cable and I tried the B/C and V2 versions of the examples in the Waveshare E-Paper library but nothing worked. I tried both the wiring configuration on this website and the one on this website none of which worked!

Failed Arduino Mega

I copied my documentation thus far into ChatGPT (excluding long parts at the end of some links to reduce the number of tokens) and asked it for advice. It's response wasn't helpful.

It seems like you have tried several different approaches to get the 7.5" e-paper waveshare display to work with your Raspberry Pi Pico, but haven't had success yet. Here are some suggestions that may help:

Double check the wiring connections: It's important to make sure that all the wiring connections between the display and the Pico are correct. Make sure to consult the datasheets and schematics of both the display and the Pico to ensure that you're connecting the correct pins.

Check the power supply: Make sure that the display is receiving adequate power. E-paper displays require a high voltage to operate, and it's possible that the power supply you're using isn't providing enough voltage.

Try a different library: If you're having trouble with the library you're currently using, try a different one. There are several libraries available for e-paper displays that work with the Raspberry Pi Pico, so try a few to see which one works best for your setup.

Verify the code: Make sure that the code you're using is correct and that it's compatible with your display and Pico. Double-check the code and verify that it matches the wiring connections.

Try a different display: If you're still having trouble, it's possible that the display itself is faulty. Try using a different display to see if that works with your Pico.

I hope these suggestions help you get your e-paper display working with your Raspberry Pi Pico. Good luck!

I then installed MicroPython using my old documentation as a tutorial. I had already downloaded a ZIP file of this entire repo so I copied the waveshare_epd folder into the RP2040 disk drive that appears when I plug it in while holding the bootloader button.

I installed MicroPython using my old documentation then followed ChatGPT's advice for writing a program in MicroPython using the Waveshare E-Paper library. I right-clicked a file and clicked Upload to / to move it into the Raspberry Pi Pico's harddrive.

Upload to Slash

I encountered many errors using ChatGPT and spent several hours going down a rabbit hole telling it everything that wasn't working. It told me that actually this wouldn't work with MircoPython and gave me the files and a workflow for how to install CircuitPython on a Raspberry Pi Pico. I held the bootloader button while plugging it in then dragged a UF2 file into the drive, causing the board to restart. Here is the full text of my conversation with ChatGPT, or just skip it and move on. The formatting may be slightly strange. In essence, there were so many hallucinations, and it was extremely unhelpful. I learned that I can be much more efficient if I just try to do it myself.

Different Approach

I give up - too much hallucination.

Luckily, I found this library that specifically deals with e-paper in MicroPython, but it doesn't go up to the 9.7" display, so for now I'll just focus on the 7.5" display.

Board not showing up - Press Bootsel, reset button, releaes Bootsel, release reset button.

When I selected < Try to detect port automatically > finally worked. Turns out it wasn't the 3V output plugged into the e-paper display.

from micropython import const
from time import sleep_ms
import ustruct

# Display resolution
EPD_WIDTH  = const(640)
EPD_HEIGHT = const(384)

# Display commands
PANEL_SETTING                  = const(0x00)
POWER_SETTING                  = const(0x01)
POWER_OFF                      = const(0x02)
#POWER_OFF_SEQUENCE_SETTING     = const(0x03)
POWER_ON                       = const(0x04)
#POWER_ON_MEASURE               = const(0x05)
BOOSTER_SOFT_START             = const(0x06)
DEEP_SLEEP                     = const(0x07)
DATA_START_TRANSMISSION_1      = const(0x10)
#DATA_STOP                      = const(0x11)
DISPLAY_REFRESH                = const(0x12)
#IMAGE_PROCESS                  = const(0x13)
#LUT_FOR_VCOM                   = const(0x20)
#LUT_BLUE                       = const(0x21)
#LUT_WHITE                      = const(0x22)
#LUT_GRAY_1                     = const(0x23)
#LUT_GRAY_2                     = const(0x24)
#LUT_RED_0                      = const(0x25)
#LUT_RED_1                      = const(0x26)
#LUT_RED_2                      = const(0x27)
#LUT_RED_3                      = const(0x28)
#LUT_XON                        = const(0x29)
PLL_CONTROL                    = const(0x30)
#TEMPERATURE_SENSOR_COMMAND     = const(0x40)
TEMPERATURE_CALIBRATION        = const(0x41)
#TEMPERATURE_SENSOR_WRITE       = const(0x42)
#TEMPERATURE_SENSOR_READ        = const(0x43)
VCOM_AND_DATA_INTERVAL_SETTING = const(0x50)
#LOW_POWER_DETECTION            = const(0x51)
TCON_SETTING                   = const(0x60)
TCON_RESOLUTION                = const(0x61)
#SPI_FLASH_CONTROL              = const(0x65)
#REVISION                       = const(0x70)
#GET_STATUS                     = const(0x71)
#AUTO_MEASUREMENT_VCOM          = const(0x80)
#READ_VCOM_VALUE                = const(0x81)
VCM_DC_SETTING                 = const(0x82)
FLASH_MODE                     = const(0xE5)

BUSY = const(0)  # 0=busy, 1=idle

class EPD:
    def __init__(self, spi, cs, dc, rst, busy):
        self.spi = spi
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.busy = busy
        self.cs.init(self.cs.OUT, value=1)
        self.dc.init(self.dc.OUT, value=0)
        self.rst.init(self.rst.OUT, value=0)
        self.busy.init(self.busy.IN)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT

    def _command(self, command, data=None):
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([command]))
        self.cs(1)
        if data is not None:
            self._data(data)

    def _data(self, data):
        self.dc(1)
        self.cs(0)
        self.spi.write(data)
        self.cs(1)

    def init(self):
        self.reset()
        self._command(POWER_SETTING, b'\x37\x00')
        self._command(PANEL_SETTING, b'\xCF\x08')
        self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28')
        self._command(POWER_ON)
        self.wait_until_idle()
        self._command(PLL_CONTROL, b'\x3C')
        self._command(TEMPERATURE_CALIBRATION, b'\x00')
        self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77')
        self._command(TCON_SETTING, b'\x22')
        self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT))
        self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file
        self._command(FLASH_MODE, b'\x03')

    def wait_until_idle(self):
        while self.busy.value() == BUSY:
            sleep_ms(100)

    def reset(self):
        self.rst(0)
        sleep_ms(200)
        self.rst(1)
        sleep_ms(200)

    # draw the current frame memory
    def display_frame(self, frame_buffer):
        self._command(DATA_START_TRANSMISSION_1)
        for i in range(0, self.width * self.height // 8):
            temp1 = frame_buffer[i]
            j = 0
            while (j < 8):
                if (temp1 & 0x80):
                    temp2 = 0x03
                else:
                    temp2 = 0x00
                temp2 = (temp2 << 4) & 0xFF
                temp1 = (temp1 << 1) & 0xFF
                j += 1
                if (temp1 & 0x80):
                    temp2 |= 0x03
                else:
                    temp2 |= 0x00
                temp1 = (temp1 << 1) & 0xFF
                self._data(bytearray([temp2]))
                j += 1
        self._command(DISPLAY_REFRESH)
        sleep_ms(100)
        self.wait_until_idle()

    # to wake call reset() or init()
    def sleep(self):
        self._command(POWER_OFF)
        self.wait_until_idle()
        self._command(DEEP_SLEEP, b'\xA5')

import framebuf

epd = EPD(0, 17, 20, 21, 22)
#self, spi, cs, dc, rst, busy
epd.init()
buffer = bytearray(epd.width * epd.height // 8)
fb = framebuf.FrameBuffer(buffer, epd.width, epd.height, framebuf.MONO_HLSB)
fb.fill(0)
epd.display_frame(buffer)

fb.text("Hello, World!", 0, 0, 1)
epd.display_frame(buffer)

Didn't work because numbers in EPD constructor needed to be Pin and SPI objects.

from micropython import const
from time import sleep_ms
import ustruct

# Display resolution
EPD_WIDTH  = const(640)
EPD_HEIGHT = const(384)

# Display commands
PANEL_SETTING                  = const(0x00)
POWER_SETTING                  = const(0x01)
POWER_OFF                      = const(0x02)
#POWER_OFF_SEQUENCE_SETTING     = const(0x03)
POWER_ON                       = const(0x04)
#POWER_ON_MEASURE               = const(0x05)
BOOSTER_SOFT_START             = const(0x06)
DEEP_SLEEP                     = const(0x07)
DATA_START_TRANSMISSION_1      = const(0x10)
#DATA_STOP                      = const(0x11)
DISPLAY_REFRESH                = const(0x12)
#IMAGE_PROCESS                  = const(0x13)
#LUT_FOR_VCOM                   = const(0x20)
#LUT_BLUE                       = const(0x21)
#LUT_WHITE                      = const(0x22)
#LUT_GRAY_1                     = const(0x23)
#LUT_GRAY_2                     = const(0x24)
#LUT_RED_0                      = const(0x25)
#LUT_RED_1                      = const(0x26)
#LUT_RED_2                      = const(0x27)
#LUT_RED_3                      = const(0x28)
#LUT_XON                        = const(0x29)
PLL_CONTROL                    = const(0x30)
#TEMPERATURE_SENSOR_COMMAND     = const(0x40)
TEMPERATURE_CALIBRATION        = const(0x41)
#TEMPERATURE_SENSOR_WRITE       = const(0x42)
#TEMPERATURE_SENSOR_READ        = const(0x43)
VCOM_AND_DATA_INTERVAL_SETTING = const(0x50)
#LOW_POWER_DETECTION            = const(0x51)
TCON_SETTING                   = const(0x60)
TCON_RESOLUTION                = const(0x61)
#SPI_FLASH_CONTROL              = const(0x65)
#REVISION                       = const(0x70)
#GET_STATUS                     = const(0x71)
#AUTO_MEASUREMENT_VCOM          = const(0x80)
#READ_VCOM_VALUE                = const(0x81)
VCM_DC_SETTING                 = const(0x82)
FLASH_MODE                     = const(0xE5)

BUSY = const(0)  # 0=busy, 1=idle

class EPD:
    def __init__(self, spi, cs, dc, rst, busy):
        self.spi = spi
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.busy = busy
        self.cs.init(self.cs.OUT, value=1)
        self.dc.init(self.dc.OUT, value=0)
        self.rst.init(self.rst.OUT, value=0)
        self.busy.init(self.busy.IN)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT

    def _command(self, command, data=None):
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([command]))
        self.cs(1)
        if data is not None:
            self._data(data)

    def _data(self, data):
        self.dc(1)
        self.cs(0)
        self.spi.write(data)
        self.cs(1)

    def init(self):
        self.reset()
        self._command(POWER_SETTING, b'\x37\x00')
        self._command(PANEL_SETTING, b'\xCF\x08')
        self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28')
        self._command(POWER_ON)
        self.wait_until_idle()
        self._command(PLL_CONTROL, b'\x3C')
        self._command(TEMPERATURE_CALIBRATION, b'\x00')
        self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77')
        self._command(TCON_SETTING, b'\x22')
        self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT))
        self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file
        self._command(FLASH_MODE, b'\x03')

    def wait_until_idle(self):
        while self.busy.value() == BUSY:
            sleep_ms(100)

    def reset(self):
        self.rst(0)
        sleep_ms(200)
        self.rst(1)
        sleep_ms(200)

    # draw the current frame memory
    def display_frame(self, frame_buffer):
        self._command(DATA_START_TRANSMISSION_1)
        for i in range(0, self.width * self.height // 8):
            temp1 = frame_buffer[i]
            j = 0
            while (j < 8):
                if (temp1 & 0x80):
                    temp2 = 0x03
                else:
                    temp2 = 0x00
                temp2 = (temp2 << 4) & 0xFF
                temp1 = (temp1 << 1) & 0xFF
                j += 1
                if (temp1 & 0x80):
                    temp2 |= 0x03
                else:
                    temp2 |= 0x00
                temp1 = (temp1 << 1) & 0xFF
                self._data(bytearray([temp2]))
                j += 1
        self._command(DISPLAY_REFRESH)
        sleep_ms(100)
        self.wait_until_idle()

    # to wake call reset() or init()
    def sleep(self):
        self._command(POWER_OFF)
        self.wait_until_idle()
        self._command(DEEP_SLEEP, b'\xA5')

from machine import Pin, SPI
import framebuf

spi = SPI(0, sck=Pin(18), mosi=Pin(19), miso=Pin(16), baudrate=2000000)
cs = Pin(17, Pin.OUT)
dc = Pin(20, Pin.OUT)
rst = Pin(21, Pin.OUT)
busy = Pin(22, Pin.IN)

epd = EPD(spi, cs, dc, rst, busy)
#self, spi, cs, dc, rst, busy
epd.init()
buffer = bytearray(epd.width * epd.height // 8)
fb = framebuf.FrameBuffer(buffer, epd.width, epd.height, framebuf.MONO_HLSB)
fb.fill(0)
epd.display_frame(buffer)

fb.text("Hello, World!", 0, 0, 1)
epd.display_frame(buffer)

This didn't work:

from micropython import const
from time import sleep_ms
import ustruct

# Display resolution
EPD_WIDTH  = const(640)
EPD_HEIGHT = const(384)

# Display commands
PANEL_SETTING                  = const(0x00)
POWER_SETTING                  = const(0x01)
POWER_OFF                      = const(0x02)
#POWER_OFF_SEQUENCE_SETTING     = const(0x03)
POWER_ON                       = const(0x04)
#POWER_ON_MEASURE               = const(0x05)
BOOSTER_SOFT_START             = const(0x06)
DEEP_SLEEP                     = const(0x07)
DATA_START_TRANSMISSION_1      = const(0x10)
#DATA_STOP                      = const(0x11)
DISPLAY_REFRESH                = const(0x12)
#IMAGE_PROCESS                  = const(0x13)
#LUT_FOR_VCOM                   = const(0x20)
#LUT_BLUE                       = const(0x21)
#LUT_WHITE                      = const(0x22)
#LUT_GRAY_1                     = const(0x23)
#LUT_GRAY_2                     = const(0x24)
#LUT_RED_0                      = const(0x25)
#LUT_RED_1                      = const(0x26)
#LUT_RED_2                      = const(0x27)
#LUT_RED_3                      = const(0x28)
#LUT_XON                        = const(0x29)
PLL_CONTROL                    = const(0x30)
#TEMPERATURE_SENSOR_COMMAND     = const(0x40)
TEMPERATURE_CALIBRATION        = const(0x41)
#TEMPERATURE_SENSOR_WRITE       = const(0x42)
#TEMPERATURE_SENSOR_READ        = const(0x43)
VCOM_AND_DATA_INTERVAL_SETTING = const(0x50)
#LOW_POWER_DETECTION            = const(0x51)
TCON_SETTING                   = const(0x60)
TCON_RESOLUTION                = const(0x61)
#SPI_FLASH_CONTROL              = const(0x65)
#REVISION                       = const(0x70)
#GET_STATUS                     = const(0x71)
#AUTO_MEASUREMENT_VCOM          = const(0x80)
#READ_VCOM_VALUE                = const(0x81)
VCM_DC_SETTING                 = const(0x82)
FLASH_MODE                     = const(0xE5)

BUSY = const(0)  # 0=busy, 1=idle

class EPD:
    def __init__(self, spi, cs, dc, rst, busy):
        self.spi = spi
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.busy = busy
        self.cs.init(self.cs.OUT, value=1)
        self.dc.init(self.dc.OUT, value=0)
        self.rst.init(self.rst.OUT, value=0)
        self.busy.init(self.busy.IN)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT

    def _command(self, command, data=None):
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([command]))
        self.cs(1)
        if data is not None:
            self._data(data)

    def _data(self, data):
        self.dc(1)
        self.cs(0)
        self.spi.write(data)
        self.cs(1)

    def init(self):
        print("started restart")
        self.reset()
        print("finished restarting")
        self._command(POWER_SETTING, b'\x37\x00')
        self._command(PANEL_SETTING, b'\xCF\x08')
        self._command(BOOSTER_SOFT_START, b'\xC7\xCC\x28')
        self._command(POWER_ON)
        print("waiting until idle")
        self.wait_until_idle()
        self._command(PLL_CONTROL, b'\x3C')
        self._command(TEMPERATURE_CALIBRATION, b'\x00')
        self._command(VCOM_AND_DATA_INTERVAL_SETTING, b'\x77')
        self._command(TCON_SETTING, b'\x22')
        self._command(TCON_RESOLUTION, ustruct.pack(">HH", EPD_WIDTH, EPD_HEIGHT))
        self._command(VCM_DC_SETTING, b'\x1E') # decide by LUT file
        self._command(FLASH_MODE, b'\x03')

    def wait_until_idle(self):
        while self.busy.value() == BUSY:
            sleep_ms(100)

    def reset(self):
        self.rst(0)
        sleep_ms(200)
        self.rst(1)
        sleep_ms(200)

    # draw the current frame memory
    def display_frame(self, frame_buffer):
        self._command(DATA_START_TRANSMISSION_1)
        for i in range(0, self.width * self.height // 8):
            temp1 = frame_buffer[i]
            j = 0
            while (j < 8):
                if (temp1 & 0x80):
                    temp2 = 0x03
                else:
                    temp2 = 0x00
                temp2 = (temp2 << 4) & 0xFF
                temp1 = (temp1 << 1) & 0xFF
                j += 1
                if (temp1 & 0x80):
                    temp2 |= 0x03
                else:
                    temp2 |= 0x00
                temp1 = (temp1 << 1) & 0xFF
                self._data(bytearray([temp2]))
                j += 1
        self._command(DISPLAY_REFRESH)
        sleep_ms(100)
        self.wait_until_idle()

    # to wake call reset() or init()
    def sleep(self):
        self._command(POWER_OFF)
        self.wait_until_idle()
        self._command(DEEP_SLEEP, b'\xA5')

from machine import Pin, SPI
import framebuf

print("creating objs")
spi = SPI(0, sck=Pin(18), mosi=Pin(19), miso=Pin(16), baudrate=2000000)
cs = Pin(17, Pin.OUT)
dc = Pin(20, Pin.OUT)
rst = Pin(21, Pin.OUT)
busy = Pin(22, Pin.IN)

print("initializing")
epd = EPD(spi, cs, dc, rst, busy)
#self, spi, cs, dc, rst, busy
print("epd instance created")
epd.init()
print("initialized")
buffer = bytearray(epd.width * epd.height // 8)
fb = framebuf.FrameBuffer(buffer, epd.width, epd.height, framebuf.MONO_HLSB)
fb.fill(0)
epd.display_frame(buffer)

print("ready to hello, world!")
fb.text("Hello, World!", 0, 0, 1)
epd.display_frame(buffer)

I thought I maybe had the wrong type of board. I also tried the 4.2" e-paper display using the example code and fixing the wiring, and nothing happened. Partway through I noticed that the screen had become red and there were some gray specks, but I couldn't get anything to be controlled. I realized that I had all of the ribbon cables upside down, but they still didn't work when I corrected them. I even tried a different Pico and asked ChatGPT about the wiring, but it was all failing.

Milling The Board

Moving On

I decided to move on from the e-paper display for right now to focus on the servo and come back to the display later. I realized that the footprint for the SLIDE-SWITCH component in the fab library had the same SMD pads as I needed for three headers pins.

New Schematic New

When routing I realized that there were holes in the slide-switch footprint but I simply designed my routes around them and will simply not mill them when I cut out my board.

New Layout

New 3D PCB

I was going to mill this board on the Genmitsu 3020-Pro Max milling machine, so I went to the Manufacturing workspace and created a new Setup. I selected a boxpoint on the top of the stock to where the x and y axes were hugging the stock. I selected all the traces and the top face of the board to be the Model, changed the Stock Top Offset to 0mm.

I went back and made the traces larger in the layout then made sure to deselect Solder Masks after I pressed Push to 3D PCB.

I then created a 2D Contour. When I selected the tool, I went to Milling Tools (Metric) and copied the smallest Flat Endmill I could find (3mm Flat Endmill). I then copied and pasted it into my Local > Library tools and right-clicked it and selected Edit tool. I changed the Description to 0.8mm Flat Endmill, Diameter to 0.8mm in the Cutter menu, Spindle speed to 12000 rpm in the Cutting data menu, Cutting feedrate to 100 mm/min in the same menu, and Plunge feedrate to 100 mm/min in the same menu.I then pressed the blue Accept button. I selected the new tool and set the Coolant setting to Disabled. Then for the Contour Selection I pressed the Chain icon and selected one of the traces. I repeated this for the top outline of every trace I wanted milled, which took a fairly large amount of time.

Chain Selection & Chain Button

Next, under Top Height I set Offset to 0mm. I checked the Multiple Depths option (scroll down under the Passes menu) and set Maximum Roughing Stepdown to 0.4mm. I then pressed OK and activated the 2D Contour tool again. I selected the bottom outline of the board and used all the same other settings as the previous contour.

As I zoomed in I noticed that there were no blue lines around the second and third pads of the slide-switch component so I had to go back to the layout editor, decrease the DRC rules for minimum distance between a pad and a wire, then move the middle route in between the two switch holes. I also made all of the traces thicker. I then Pushed to 3D PCB again and made sure to uncheck Solder Mask. I got errors under the 2D Contour, so to recalculate I

Finally I right-clicked the previously-created Setup in the hierarchy and pressed Post Process. I made sure Post was set to Grbl / grbl and pressed Post.

The milling process was very smooth! I moved the z-axis high and zeroed it, then pressed Send to do an air cut. Everything looked OK so I moved the z-axis down until a piece of paper couldn't move in between the copper and the mill then zeroes the z-axis and moved the bit higher. I moved the x and y axes to the bottom left corner of the copper and zeroed them, as well. Then I pressed Reset and Send, and it worked! I occasionally vaccumed throughout the milling process.

Here's the result after rinsing in water!

The soldering process was very smooth.

Unfortunately I realized that the order of the wires didn't match up with the servo so connecting it directly like this wouldn't work - I'll correct this in the next iteration of the design. For now I'll connect the servo like this.

The next day when I took the board out of my bag to test I noticed the traces ripped! These were thinner than other traces I'd milled so that might be why.

I tried resoldering with a lot of solder to reach what was left of the traces, but this failed.

I then tried to desolder mistakes and failed again - I needed to make a new board.

Redesigning Again

Just to be sure everything will work OK I made the traces' width 50mil.

New New Layout

I milled the board, deburred it, washed it in soap and water, soldered it (very few connections to the pico so I could always unsolder if needed), and connected it to a servo motor. The only learning I had was that when I install a new tool I have to select the new tool button in the Bantam software then re-zero it. Also, I'd originally tried to only solder the corners and test the conections, but even though the other legs were touching, they weren't connected, so I soldered all of the legs that were connected to pin headers.

I tried plugging the board into my computer and nothing happened! I became very worried that I wasted another Pico, but tried a different chord, and it worked! I installed MicroPython using Thonny then ran the code from this website to operate a servo motor (I modified it to use GPIO 21). I copied and pasted both files into Thonny then saved them in the base directory of the Pico.

servo.py

from machine import Pin, PWM


class Servo:
    """ A simple class for controlling a 9g servo with the Raspberry Pi Pico.

    Attributes:

        minVal: An integer denoting the minimum duty value for the servo motor.

        maxVal: An integer denoting the maximum duty value for the servo motor.

    """

    def __init__(self, pin: int or Pin or PWM, minVal=2500, maxVal=7500):
        """ Creates a new Servo Object.

        args:

            pin (int or machine.Pin or machine.PWM): Either an integer denoting the number of the GPIO pin or an already constructed Pin or PWM object that is connected to the servo.

            minVal (int): Optional, denotes the minimum duty value to be used for this servo.

            maxVal (int): Optional, denotes the maximum duty value to be used for this servo.

        """

        if isinstance(pin, int):
            pin = Pin(pin, Pin.OUT)
        if isinstance(pin, Pin):
            self.__pwm = PWM(pin)
        if isinstance(pin, PWM):
            self.__pwm = pin
        self.__pwm.freq(50)
        self.minVal = minVal
        self.maxVal = maxVal

    def deinit(self):
        """ Deinitializes the underlying PWM object.

        """
        self.__pwm.deinit()

    def goto(self, value: int):
        """ Moves the servo to the specified position.

        args:

            value (int): The position to move to, represented by a value from 0 to 1024 (inclusive).

        """
        if value < 0:
            value = 0
        if value > 1024:
            value = 1024
        delta = self.maxVal-self.minVal
        target = int(self.minVal + ((value / 1024) * delta))
        self.__pwm.duty_u16(target)

    def middle(self):
        """ Moves the servo to the middle.
        """
        self.goto(512)

    def free(self):
        """ Allows the servo to be moved freely.
        """
        self.__pwm.duty_u16(0)

main.py

import utime
from servo import Servo

s1 = Servo(21)       # Servo pin is connected to GP21

def servo_Map(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def servo_Angle(angle):
    if angle < 0:
        angle = 0
    if angle > 180:
        angle = 180
    s1.goto(round(servo_Map(angle,0,180,0,1024))) # Convert range value to angle value

if __name__ == '__main__':
    while True:
        print("Turn left ...")
        for i in range(0,180,10):
            servo_Angle(i)
            utime.sleep(0.05)
        print("Turn right ...")
        for i in range(180,0,-10):
            servo_Angle(i)
            utime.sleep(0.05)

It worked! However, the servo movement was very jittery. To make sure this was a software problem and not a hardware problem, I modified main.py, and this reduced the jitteriness!

import utime
from servo import Servo

s1 = Servo(21)       # Servo pin is connected to GP21

def servo_Map(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def servo_Angle(angle):
    if angle < 0:
        angle = 0
    if angle > 180:
        angle = 180
    s1.goto(round(servo_Map(angle,0,180,0,1024))) # Convert range value to angle value

if __name__ == '__main__':
    while True:
        print("Turn left ...")
        for i in range(0,180,1):
            servo_Angle(i)
            utime.sleep(0.001)
        print("Turn right ...")
        for i in range(180,0,-10):
            servo_Angle(i)
            utime.sleep(0.001)

I tried making it even more smooth, but the servo wouldn't turn 180 deg, which I suspect is because 0.001sec is too short of a time for the servo to turn.

I modified the code to the following to test a functionality more similar to what I'll actually use.

import utime
from servo import Servo

s1 = Servo(21)       # Servo pin is connected to GP21

def servo_Map(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def servo_Angle(angle):
    if angle < 0:
        angle = 0
    if angle > 180:
        angle = 180
    s1.goto(round(servo_Map(angle,0,180,0,1024))) # Convert range value to angle value

if __name__ == '__main__':
    while True:
        try:
            servo_Angle(float(input(">> Angle? ")))
        except:
            print("Error: NaN")

This was a critical mistake! The program worked very well, and it moved up until 180 deg and wouldn't go below 0 deg, but I couldn't exit the program! Even when I tried to soft reboot in Thonny my program simply rejected the message since it wasn't a float. I tried re-entering bootloader mode and reinstalling MicroPython but the program simply started up again. Next I had an idea that if I installed a different version of MicroPython that wasn't compatible with the board it wouldn't know how to run my program, so I installed the Pico WH version of MicroPython and the program stopped! I then reinstalled the correct one and the problem was solved!

Redesigning The Driver-Side Board

I want to redesign my board from Week 8 to where I can use one of the pins with a built in pulldown resistor, D4. I'll come back to this if I have time this week and if not in the future.

A New Display

I accidentally ripped the ribbon cable when opening the box - I learned I should always unplug the HAT Driver from the ribbon cable when I put the display away! I ordered a new one.

3.7" Display

Code

Pico_ePaper.py

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
# LUTs have been copied from original example for Waveshare Pico e-Paper 3.7,
# which can be found here:
# https://github.com/waveshare/Pico_ePaper_Code/blob/main/python/Pico-ePaper-3.7.py
#
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


EPD_3IN7_lut_4Gray_GC = bytes([
    0x2A, 0x06, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 1
    0x28, 0x06, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 2
    0x20, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 3
    0x14, 0x06, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 4
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 5
    0x00, 0x02, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x08, 0x02,  # 6
    0x00, 0x02, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 8
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 10
    0x22, 0x22, 0x22, 0x22, 0x22
])

EPD_3IN7_lut_1Gray_GC = bytes([
    0x2A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 1
    0x05, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 2
    0x2A, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 3
    0x05, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 4
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 5
    0x00, 0x02, 0x03, 0x0A, 0x00, 0x02, 0x06, 0x0A, 0x05, 0x00,  # 6
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 8
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 10
    0x22, 0x22, 0x22, 0x22, 0x22
])

EPD_3IN7_lut_1Gray_DU = bytes([
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 1
    0x01, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x0A, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 3
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 5
    0x00, 0x00, 0x05, 0x05, 0x00, 0x05, 0x03, 0x05, 0x05, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x22, 0x22, 0x22, 0x22, 0x22
])

EPD_3IN7_lut_1Gray_A2 = bytes([
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 1
    0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 2
    0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 3
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 4
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 5
    0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 6
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 8
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  # 10
    0x22, 0x22, 0x22, 0x22, 0x22
])
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from machine import Pin
import framebuf
from utime import ticks_ms, ticks_diff, sleep_ms
from ustruct import pack
import gc
import micropython


def profile(func):
    def wrapper(*args, **kwargs):
        gc.collect()
        start_mem = gc.mem_free()
        start_t = ticks_ms()
        func(*args, **kwargs)
        fin_t = ticks_ms()
        fin_mem = gc.mem_free()
        print(f'{func.__name__} took: {ticks_diff(fin_t, start_t)} ms to finish')
        print(f'{func.__name__} used around {start_mem - fin_mem} B of memory')

    return wrapper


class EinkBase:
    black = 0b00
    white = 0b11
    darkgray = 0b01
    lightgray = 0b10

    RAM_BW = 0b01
    RAM_RED = 0b10
    RAM_RBW = 0b11

    def __init__(self, rotation=0, cs_pin=None, dc_pin=None, reset_pin=None, busy_pin=None):
        if rotation == 0 or rotation == 180:
            self.width = 280
            self.height = 480
            buf_format = framebuf.MONO_HLSB
            self._horizontal = False
        elif rotation == 90 or rotation == 270:
            self.width = 480
            self.height = 280
            buf_format = framebuf.MONO_VLSB
            self._horizontal = True
        else:
            raise ValueError(
                f"Incorrect rotation selected ({rotation}). Valid values: 0, 90, 180 and 270.")

        self._rotation = rotation

        if reset_pin is None:
            self._rst = Pin(12, Pin.OUT, value=0)
        else:
            self._rst = reset_pin
            self._rst.init(Pin.OUT, value=0)

        if dc_pin is None:
            self._dc = Pin(8, Pin.OUT, value=0)
        else:
            self._dc = dc_pin
            self._dc.init(Pin.OUT, value=0)

        if cs_pin is None:
            self._cs = Pin(9, Pin.OUT, value=1)
        else:
            self._cs = cs_pin
            self._cs.init(Pin.OUT, value=1)

        if busy_pin is None:
            self._busy = Pin(13, Pin.IN, Pin.PULL_UP)
        else:
            self._busy = busy_pin
            self._busy.init(Pin.IN)

        self._luts = {0: EPD_3IN7_lut_4Gray_GC,
                      1: EPD_3IN7_lut_1Gray_GC,
                      2: EPD_3IN7_lut_1Gray_DU,
                      3: EPD_3IN7_lut_1Gray_A2}

        self._buffer_bw = bytearray(self.width * self.height // 8)
        self._buffer_red = bytearray(self.width * self.height // 8)
        self._bw = framebuf.FrameBuffer(self._buffer_bw, self.width, self.height, buf_format)
        self._red = framebuf.FrameBuffer(self._buffer_red, self.width, self.height, buf_format)

        self.fill()

        self._init_disp()
        sleep_ms(500)

    def _reset(self):
        self._rst(1)
        sleep_ms(30)
        self._rst(0)
        sleep_ms(3)
        self._rst(1)
        sleep_ms(30)

    def _send_command(self, command):
        raise NotImplementedError

    def _send_data(self, data):
        raise NotImplementedError

    def _send(self, command, data):
        self._send_command(command)
        self._send_data(data)

    def _read_busy(self):
        while self._busy.value() == 1:
            sleep_ms(10)
        sleep_ms(200)

    def _load_LUT(self, lut=0):
        self._send(0x32, self._luts[lut])

    def _set_cursor(self, x, y):
        self._send(0x4e, pack("h", x))
        self._send(0x4f, pack("h", y))

    def _set_window(self, start_x, end_x, start_y, end_y):
        self._send(0x44, pack("2h", start_x, end_x))
        self._send(0x45, pack("2h", start_y, end_y))

    def _clear_ram(self, bw=True, red=True):
        if red:
            self._send(0x46, 0xf7)
            self._read_busy()
        if bw:
            self._send(0x47, 0xf7)
            self._read_busy()

    def _init_disp(self):
        # HW reset.
        self._reset()

        # SW reset.
        self._send_command(0x12)
        sleep_ms(300)

        # Clear BW and RED RAMs.
        self._clear_ram()

        # Set gate number.
        self._send(0x01, pack("hB", 479, 0))

        # Set gate voltage.
        self._send(0x03, 0x00)

        # Set source voltage.
        self._send(0x04, pack("3B", 0x41, 0xa8, 0x32))

        # Set Data Entry mode.
        if self._rotation == 0:
            seq = 0x03
        elif self._rotation == 180:
            seq = 0x00
        elif self._rotation == 90:
            seq = 0x06
        elif self._rotation == 270:
            seq = 0x05
        else:
            raise ValueError(f"Incorrect rotation selected")

        self._send(0x11, seq)

        # Set border.
        self._send(0x3c, 0x03)

        # Booster Soft-start Control.
        self._send(0x0c, pack("5B", 0xae, 0xc7, 0xc3, 0xc0, 0xc0))

        # Internal sensor on.
        self._send(0x18, 0x80)

        # Set VCOM.
        self._send(0x2c, 0x44)

        # Set window.
        if self._rotation == 0:
            self._set_window(0, self.width - 1, 0, self.height - 1)
        elif self._rotation == 180:
            self._set_window(self.width - 1, 0, self.height - 1, 0)
        elif self._rotation == 90:
            self._set_window(self.height - 1, 0, 0, self.width - 1)
        elif self._rotation == 270:
            self._set_window(0, self.height - 1, self.width - 1, 0)
        else:
            raise ValueError(f"Incorrect rotation selected")

        # Set Display Update Control 2
        self._send(0x22, 0xcf)

    # --------------------------------------------------------
    # Public methods.
    # --------------------------------------------------------

    def show(self, lut=0):
        if self._rotation == 0:
            self._set_cursor(0, 0)
        elif self._rotation == 180:
            self._set_cursor(self.width - 1, self.height - 1)
        elif self._rotation == 90:
            self._set_cursor(self.height - 1, 0)
        else:
            self._set_cursor(0, self.width - 1)

    def sleep(self):
        self._send(0x10, 0x03)

    # --------------------------------------------------------
    # Drawing routines (wrappers for FrameBuffer methods).
    # --------------------------------------------------------

    def fill(self, c=white):
        self._bw.fill(c & 1)
        self._red.fill(c >> 1)

    def pixel(self, x, y, c=black):
        self._bw.pixel(x, y, c & 1)
        self._red.pixel(x, y, c >> 1)

    def hline(self, x, y, w, c=black):
        self._bw.hline(x, y, w, c & 1)
        self._red.hline(x, y, w, c >> 1)

    def vline(self, x, y, h, c=black):
        self._bw.vline(x, y, h, c & 1)
        self._red.vline(x, y, h, c >> 1)

    def line(self, x1, y1, x2, y2, c=black):
        self._bw.line(x1, y1, x2, y2, c & 1)
        self._red.line(x1, y1, x2, y2, c >> 1)

    def rect(self, x, y, w, h, c=black):
        self._bw.rect(x, y, w, h, c & 1)
        self._red.rect(x, y, w, h, c >> 1)

    def fill_rect(self, x, y, w, h, c=black):
        self._bw.fill_rect(x, y, w, h, c & 1)
        self._red.fill_rect(x, y, w, h, c >> 1)

    def text(self, text, x, y, c=black):
        self._bw.text(text, x, y, c & 1)
        self._red.text(text, x, y, c >> 1)

    def blit(self, fbuf, x, y, key=-1, palette=None, ram=RAM_RBW):
        if ram & 1 == 1:
            self._bw.blit(fbuf, x, y, key, palette)
        if (ram >> 1) & 1 == 1:
            self._red.blit(fbuf, x, y, key, palette)


class Eink(EinkBase):
    from machine import SPI

    def __init__(self, spi=None, *args, **kwargs):
        if spi is None:
            self._spi = self.SPI(1, baudrate=20_000_000)
        else:
            self._spi = spi
        super(Eink, self).__init__(*args, **kwargs)

    def _send_command(self, command):
        self._dc(0)
        self._cs(0)
        if isinstance(command, int):
            self._spi.write(bytes([command]))
        elif isinstance(command, (bytes, bytearray)):
            self._spi.write(command)
        else:
            raise ValueError  # For now
        self._cs(1)

    def _send_data(self, data):
        self._dc(1)
        self._cs(0)
        if isinstance(data, int):
            self._spi.write(bytes([data]))
        elif isinstance(data, (bytes, bytearray)):
            self._spi.write(data)
        else:
            raise ValueError  # For now
        self._cs(1)

    @micropython.viper
    def _reverse_bits(self, num: int) -> int:
        result = 0
        for i in range(8):
            result = (result << 1) | ((num >> i) & 1)
        return result

    # --------------------------------------------------------
    # Public methods.
    # --------------------------------------------------------

    @profile
    def show(self, lut=0):
        super().show()
        # Load BW buffer to BW RAM and RED buffer to RED RAM.
        if not self._horizontal:
            self._send(0x24, self._buffer_bw)
            self._send(0x26, self._buffer_red)
        else:
            self._send(0x24, bytes(map(self._reverse_bits, self._buffer_bw)))
            self._send(0x26, bytes(map(self._reverse_bits, self._buffer_red)))

        self._load_LUT(lut)
        self._send_command(0x20)
        self._read_busy()


class EinkPIO(EinkBase):
    from machine import mem32

    def __init__(self, sm_num=0, dma=5, *args, **kwargs):
        self._sm_num = sm_num
        self._dma = int(dma * 0x40 + 0x50000030)
        self._sm = None
        self._sm_shiftctrl = (0x502000d0 + 0x100000 * (self._sm_num // 4)
                              + 0x18 * (self._sm_num % 4))
        self._dma_write_addr = (0x50200010 + 0x100000 * (self._sm_num // 4)
                                + 0x4 * (self._sm_num % 4))
        dreq = self._sm_num % 4 + 8 * (self._sm_num // 4)
        self._dma_ctrl = dreq << 15 | 1 << 4 | 1
        self._pio_setup()
        super(EinkPIO, self).__init__(*args, **kwargs)

    def _pio_setup(self):
        from rp2 import asm_pio, PIO, StateMachine

        @asm_pio(out_init=PIO.OUT_LOW,
                 sideset_init=PIO.OUT_LOW,
                 autopull=True,
                 pull_thresh=8,
                 out_shiftdir=PIO.SHIFT_LEFT)
        def pio_serial_tx():
            out(pins, 1).side(0)
            nop().side(1)

        self._sm = StateMachine(self._sm_num, pio_serial_tx, freq=40_000_000,
                                sideset_base=Pin(10), out_base=Pin(11))
        self._sm.active(1)

    def _reversed_output(self):
        self.mem32[self._sm_shiftctrl + 0x2000] = 1 << 19

    def _normal_output(self):
        self.mem32[self._sm_shiftctrl + 0x3000] = 1 << 19

    def _send_command(self, command):
        self._dc(0)
        self._cs(0)
        if isinstance(command, int):
            self._sm.put(command, 24)
        elif isinstance(command, (bytes, bytearray)):
            for cmd in command:
                self._sm.put(cmd, 24)
        else:
            raise ValueError
        self._cs(1)

    def _send_data(self, data):
        self._dc(1)
        self._cs(0)
        if isinstance(data, int):
            self._sm.put(data, 24)
        elif isinstance(data, (bytes, bytearray)):
            for cmd in data:
                self._sm.put(cmd, 24)
        else:
            raise ValueError
        self._cs(1)

    @micropython.viper
    def _dma_start(self, buffer):
        dma_ptr = ptr32(self._dma)
        dma_ptr[0] = int(self._dma_ctrl)
        dma_ptr[1] = int(self._dma_write_addr)
        dma_ptr[2] = int(len(buffer))
        dma_ptr[3] = int(ptr32(buffer))

    @micropython.viper
    def _check_dma_busy(self, a: ptr32) -> int:
        return (a[0] >> 24) & 1

    def _send_buffer(self, buffer):
        if self._horizontal:
            self._reversed_output()

        self._dc(1)
        self._cs(0)

        self._dma_start(buffer)
        dma_ctrl = self._dma

        start = ticks_ms()
        while self._check_dma_busy(dma_ctrl) and ticks_diff(ticks_ms(), start) < 5000:
            pass
        self._cs(1)
        if ticks_diff(ticks_ms(), start) >= 5000:
            print('loading data took too long')

        if self._horizontal:
            self._normal_output()

    # --------------------------------------------------------
    # Public methods.
    # --------------------------------------------------------

    @profile
    def show(self, lut=0):
        super().show()
        self._send_command(0x24)
        self._send_buffer(self._buffer_bw)
        self._send_command(0x26)
        self._send_buffer(self._buffer_red)

        self._load_LUT(lut)
        self._send_command(0x20)
        self._read_busy()


if __name__ == "__main__":
    epd = EinkPIO(rotation=270)
    epd.fill()

    epd.text("test", 10, 10)
    epd.fill_rect(0, 19, 52, 10, epd.lightgray)
    epd.text("test", 10, 20, epd.darkgray)
    epd.fill_rect(0, 29, 52, 10, epd.darkgray)
    epd.text("test", 10, 30, epd.lightgray)
    epd.fill_rect(0, 39, 52, 10)
    epd.text("test", 10, 40, epd.white)
    epd.rect(0, 8, 52, 41)

    epd.hline(5, 60, 50)
    epd.hline(5, 160, 50)
    epd.vline(5, 60, 100)
    epd.vline(55, 60, 100)
    epd.line(5, 60, 55, 160)
    epd.line(55, 60, 5, 160)
    epd.show()

    sleep_ms(5000)

    epd.fill_rect(100, 20, 50, 50)
    epd.fill_rect(100, 70, 50, 50, epd.darkgray)
    epd.fill_rect(100, 120, 50, 50, epd.lightgray)
    epd.fill_rect(100, 170, 50, 50)
    epd.rect(100, 20, 50, 200)
    epd.show()

    epd.sleep()

IMG_0182_gs_d.py

width = 184
height = 135
img_bw = bytearray(b'\x02\x92\xaa\xaa\xf7~\x01\xf0\x02x\x00A?\xf8\x0b\x11\x00\x14"G\xc2\xa9\x0fQJUU/\xbc\x03\xbc\x02x \x01\xff\xe4\x058\x04>\x087\x82\x14\x0fP\xe1UT\xae\xc2\x01\xbfP\xf0\x00a\xb0\xe1`\x1d\x00\x15\x10\x1f\xb6\x00\x0f\x15\x12\x14\xaa\x15\xb9\xf7\xff\xfap\x00@\xf0\xe6 ?\x80\x84\n\x00\xac\x08\x0f\x90XUUJ\xef\xff\xff\xf0w\x88\x00i\xf9\x00\x7f\xc3e\x0f\x01r`\x0f\xa8\xaa\xaa\xaa\xab7\xf3\xf9\xf0/\xc1\x00`\xdf\xad\xff\xf10\xdf\xc0\xaa\x90/D\x15J\xabA\xd5\xc1\xaa\xd1o\x80\x048-\xad\xfe\xf8r\xde\xe0\xb1@_\xa9J%UJk\xc3\x97\xb0\x7f\x00\x00\x00\xdfO\xe0?Z\x0f\xe0j\x00\x0fT\xa1\x95UP\xaa\xe2p\xf0\xf0\x00\x08\x00\xfe\x9c\xf9\x0f\xfe,\xb1\xd4\x80/R\x01A*\xa8U\x7f\xf0{\xc0\x80P\x01\xfa\xc6<\x07\x97>\xb1J \x1fU\x00B\x15TR\xff\xfe\x08\xdd\x1a\x00\x13\xf6\x0b\n\x07\xbe48\xe8\x00\x0fZ\x00\x92\xaa\xa0\xa2\x9f\xff\x07\x1c\x89\x04\x07\xfd\xa9\x00\x07[\xabxP@\x0f*\x80AJ\x98\x14\xaf\xff\x00}\x10\x00\x05\xf5\xa0\n\x0f\x0fGYu\xa0\x0fUQT\xa5TE_\xff\xc0\x02`\x90\x0b\xdb\x04\x04\x0fOS\xb0\x8a\x80\x0f\x15()U*\x14\x0f\xff\xf0\x80\xea\x1c\x17\xbf\xb0\x00\xbfO\xafP\x13\x00\x0fJ\x85(ET\x02\x8f\xff\xe2\xaa|\x84\xf6\xfe!0\xc7\x17\x93\xc1)\x00\x0f%@T\xa9J\x80\xbf\xff\xfdZ\x1d\xc1\xa7\xfdQ\xc0\x02\x10w\xea(\x00\x0f\x15@(T\xaaP\xf7\xff\xfdI\x0f\xbe\xeb\xfd$@\x00\x14\x0f\xd0 \x00O\x08\xa1\n\xa2\xa5@\xdf\xff\xefe\x03\xff\xc1\xf6\x98\xc0\x10\x10\x07\xf0)\x02\x0f\x05T\nUT#\xff\xff\xef\xb5\x7f\xcf\xc1\xfa| \x00\x00\'\x80\x80\x00\x0fJ\xa8\x15(\xa8\x87\x8f\xbfQ\xcf\xf7\xff\x00H\x9d\x08\x00\x00/\xa0@\x00\x0f%Q\x02\x95\x00(\x07\xda\x80G\xdb\xe4\xc0eq\x06\x00\x8d\x1f\x1a\x00\x8a\x0fP\xaa\x15H\x100\x03\xc6\x00\xc7\xfd\xb6@\xd0\xf4\x04 \xe8?`\x00\x00\x0f\n\xa9\x01T\x00 \x03\xeb\xc0#\xf5WTEt\x00\xb0p\x7fP\x00\x00_)J\x80(\x00j\x83\xf3\xf0G\xe8\xbe\xe8\x00\x04\x00|\xfd\xff@\x00\x00\xaf\x04)$\x05\x00\xff\x83\xf1\xf0\xc2\xf5\xfa\x04\x01$\x02\x7f\xff\xff\x80\x01\x00O\x05J\x90\x00C\xbf\x03\xf9\xfe\x95\xb5\x89\t\x00\x06\x04\xbf\xff\xff\x00\x00 \x0f \xa2D\x00\x07\x01\x05\xdc\xff\xc2\xfb\x80\x03\x00\x04!_\xff\xfe\x00\x02\xb5\x0fA \xa2\x00\x0f@\x03\xef\xfeUq\xc0 `\x06\x00\x04\x7f\xfe\xa0\x05l\x0f\x04\x12@\x00\x7f\xc0\x01\xfb\xfez\xf7\x80$\x00\x04\x00\x05\x8f\xfc\x00\x1f\xb8\x0f\x12@ \xa0\xfb\xf0\x01\xbf\xf1\x7f{\x80\x08\x00\x04\x00\x05\xf3\xf8\x00\x05\x00_H\x00\x00\x03\xff\xfc\x00\xbf\xbc~\xbf\xc0P\x00\x04\x01\x80\xd8\xf5\x00\x02\x03\xef \x00\x00G\xff\xfc\x00\xff\xee\xff_\xc0\x10\x00\x08\x02\x01\xf4\xfe\x90\x00\n\x0f\x00E\x00\x07\xff\xff\x01\x7f\xf3\xff_\xc0\xaa\x00\x08\x06\x01\xfbm@\x00(\x0f@\x00@\x03\xff\xff\x00\xfe\xb7\xff\xff\xa6T\x00\x08\x06\x01\xd81 \x00\xc0\x0f\x00\n\x00\x00\xff\xff\x80\xfek\xff\xf5\xe2u\x00\x18\x00C\xdb@\x80\x01 \x0f\x80 \x00\x00?\xffA\xcf_\xf9\xffd7\x00\x10\x00\x01\xf6\x00\x10\x04\x10\x0f@\x08\x00\x00?\xff\xa0\xe3\xdf\xfa\xef\xb0.\x00\x10\x00a\xfc\x02 \x08\x10\x0f@ \x00\x00_\xff@B?\x7f\xf7`\x12\x80\x10\x00\xab\xd8\x01\x00\x10(\x0f@\x00\x00\x00\x03\xfd H=\xfeg\x10\x05\x000\x7f\xffQ@\x80\x00,/ \x00\x00\x01\x07\xcb\xb5`\x1f\xfbj@\x00\x00\x10?\xd7\xe0\x02\x00\x00\xb7\xff \x00\x00\x01_\xbdz1\x7f\xff\xdf`\x00\x007\xdf8\x90\x00\x90\x80\xdf\xff\x00\x00\x00\x00\xff\xff\xdc\xb5_\xbc\xeb\xc0\x0f\x00\'\x83@\x00\x00\x00\x10\x16\xdf\x00\x08\x00\x00C\xc5\x8e\xbd\x7f\xf7\xff\xa0\'\x00/\x07\xf1\x01\n\x08\x00\x05\xef\x10\x00\x00\x00\xa7\xfcg\x8f\xf6\xf2\x7f\xc0G\x00 \x1f\xfc\x00%\x00\x00\x00\x0f\x00\x00\x03\xc0\xc0\xed;\xa7\xff7\x0f\xc0g@aG\xfe\x10@\x82\x00\x00\x0f\x00\x00/\xb0\xff\xae\xcf\x8b\xbb\xb1\xc7\xe0?\x80 ?\xccP\x1aP\x00\x00\x1f@\x00g\xf3\xff\xffRB\x1b\xd7\x82@7\x00h\x7f\xe6\x04\x81\x08\x00\x00_\x00\x00w\xe7\xfb\xdd\xa4\x00\x0f\xcbR`\x00\x00@?\xff\xba A\x19\xfa\xbf\x00\x00\xc7\xed~\xa5\xf4\x00\x0e\xf9\xf2@\x00\x00@?\xfe\xc5\x03\xcb\x7f\xfe\xbf\x00\x0b\xe3\xe8\x7f\x92\xb8\x00E\x7f\xf6 \x00\x00O\xff\xfb\x90\n\xc3\xff\xff\xff\x00\x07\xfd\xcc\x0f\xe4\xb8\x01f\x05\xd6`\x00\x00\x9f\xff\xfdm\x17\xd7\xff\xff\xff\x00\x07\xff\x83\xd7\xf04!\x97\x80\x7f\xc0\x00\x00\x1f\xff\xea\xa4G\xc7\xff\xff\x7f\x00\x0f\xeb\xd5\xffp\n!G \x1f\xe0\x00\x00}\xff\xc9X\xbf\xd7\xff\xff\xff\x00\x0f\xff\xfa\x99\xd0\t\x05S\xc0\xc7\xc0\x00\x00\xcf\xfc\xca\xf9\xcf\xc7\xff\xff\xff\x00?\xdf\xe0\x06\xe8\x00\x04\xa3\xb6\x1f\xc0\x00\x00\x9f\x10\xff\xf3\xff\xc7\xff\xff\xff\x00?\n\x00\xbf\xfc\x00@\xd1\xe9S\xe0\x00\x00\xbf \xff\xf3\xff\x87\xff\xff\xff\x00\x00\x00\x0f\xff\xfc\x04\x10\xa9\xd6\xac`\x00\x00?B\x7f\xe7\xff\x87\xff\xff\xff\x00\x00\x01\x7f\xfd>\x00\x00\xc1\xfe\xe60\x00\x00\xbf!\xff\xe7\xff\x97\xef\xff\xff\x00\x00\x1f\xff\xe0\x1e\x00\x82 \xef\xbc0\x00\x00\\\xa2\x7f\xe7\xff\x07\xcf\xff\xff\x00\x02\xff\xff\xa8\x9f\x00\x00\x01#\xef\xf8\x00\x01`\xe0\x7f\xf3\xff\x17\xdf\xff\xff\x00\xaf\xff\xeaU/\x00 \x04\xaf\xb5\xbf\x00\x00\x10d\xff\xe1\xff\x07\x9e?\xff\x06\xff\xfe\xaa\x88\x9f\x82\x00\x07\xf3\xff\x0f\xc0\x00L\xe4\xff\xe6:\x83\x9c\x7f\xff?\xff\xf9\x00%O\x80\x82\x0b\xf5\xfe\x03\xe0\x00\x06/\xff\x8e\x02\xa1\x00\xbf\xff\xff\xff\xf5P\x00/\x80\x00\x05\xf8\xfe\x03\xe0@B-\xfeq\xc9\xacp\x7f\xff\xff\xff\xa9\x04\x80\x87\xc8\x00\x03\xf0?\t\xa2\x00\x11\r\xee\xc09~x\xff\xff\xff\xda\xa4\xa2\x00\x0b\xc0\x00\x01\xfa\x15\x18!@\x01\xc3\xcc0yv\xb3\xff\xff\xfdm)\x10@\x07\xc0\x00\x00\xfc!RA\x80\x00r\x88\xc0\x10B>\xff\xcf\xf5\x15B\x04\x08\x01` \x03>\xb1\x87\xc2@\x00b\xf9\xff\xfd\x80\x1c\xff\xbf\xaa\xca(Q\x00\x01P\x00\x03\x8f\x90\xcd\x06\x80\x00 \r\xf8 \x01@<O\xaa\xa1B\x00\x00\x01`\x00\x03\xc7\xea\x18\n\x80\x004\xfd\x80\x03\x90\x03\x88\x9f\xd5T\x08\x90\x00\x00\xb0@\x07\xe7\xe4\xfdE\x80\x00\x15\xbc\x1c\x12\xdc\x08>\xbfUB\x80\x02\x00\x01x\x00\x06\xf9\xf1~\xb3\x00\x00\x01\xd8\xfe_\xc8\x18\xc0\x7f\xaa\xa8\x00\x00\x00\x00\\\x00\n\xf8\xfc\xfe\xfa\x00\x00\x08\xfd\xfe\xff\xa0\x12\x00\x0fT\x92\x10\x00\x00\x00 \x00\x11\xfc??l\x00\x00\x00\x07\xff\xee\xbc \x80\x1f\xa2H\x80\x00\x00\x00\x1c\x00\x02\xfe\x8d\x7f\xf4\x00\x00\x06\xc9\xbf\xf6\x94\x10\x81\x1f\xad"\x02\x00\x00\x00\x06\x00&~\xe0\xff\xf8\x00\x00\x02\xfe\xfe\xebh \x80\xaf\xb2\x08\x00@\x00\x00\n\x00\x17\x7f\x82\xff\xf0\x00\x00\x02~?\xea\xf8\x01\x00\x1fI\x00\x00\x00\x00\x00\x07\x00G\xff{\xf3\xe0\x00\x00\x01~\x04\xb5\xa8\x00\x80O\xaa\xa9\x00\x00\x00\x00\x01\x80\'g\xdaB\xda\x00\x04\x01>\x07\x1a\xa0\x01\x00OTD\xa0\x00\x00\x00\x00\xa2\x0f\xf8\x80\x00=@\x06\x00\x9fO\x00\xa8\x02\x00\x8f\xadU(\x00\x00\x00\x10P\x8f\xbe \x88}\x00\x02\x00\x8b\x06\x1e\x14\x00\x00\x0fUT\x92\x00\x10\x00HP\x9f\xbe\x04q\xfe\x00\x04\x00\xf5\x06\xff\x8a\x14\x01\x8f\xb5R\xa0 \x00* \x08\x9f\xae\x01\xc2\xfe\x80\x00\x00_\xc1\xff\xf1\xb4\x01\x8fT\x8a\t\x00\x00\x01\x15\x00?\x9a\x0f\xf8\xfe\x00\x00\x00/\xc1\xff\xfe\x07\xee\x0f\x95QD\x00\x00\x08\x80\x80?\xbd\x1e\xe6\x7f\x00\x00\x007\xe7\xff\xff\xf0\xfdORJ \x00\x00\x04R\xa5?\xe3\x0f\xe9\x15 \x00\x00\x1f\xff\xff\xff\xfc;\x9f\xa9(\x00\x00\n"\x02\x08\x1f\x96\xcd\xf8\x8a@\x00\x00\x07\xff\xff\xff\xff\x82\xffT\x80\x00\x04\x00P\tU>\xe3\xf1\xf0B\x00\x00\x00\x0b\xff\xff\xff\xff\xfco\x02 \x00\x00\x10\x01P\t\x1f\x17\xf9\x88p\x00\x00\x00\x03\xff\xff\xff\xff\xff\xcfT\x84\x00\x08\x00\x00@H?V\xd0\x068\x00\x00\x00\x04S\xff\xff\xff\xff\xff\x01\x10\x00\x00\x00\x00\x10%\x1eR\xa4\x01\x1e\x00\x00\x00\x04\x7f\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x80\x01\x11\x1f\xa9u\x00\x9f\xc0\x00\x00\x00\xbf\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00T\x00\x1f*q\x00F\x00\x00\x00\x03\xdf\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\xa0\x87@a\x81\xb1\x00\x00\x00\x02\xab\xff\xff\xff\xff\xff\x10\x00\x02\x00\x00\x00\xa0\x00\x0fA3\x83\x9d\x80\x00\x00\x02\x00?\xff\xff\xff\xff\x05$\x00\x80\x00\x00(@\x87\x001\x00\x8f\x00\x00\x00\x03\x08\x0f\xff\xff\xff\xff\x10\x00\x80\x00\x00\x00\x01\x06G\xc0\x11\x00O\x00\x00\x00\x02\xa4\x03\xff\xff\xff/\x04\x90\x10\x01@\x14\x10\x0e\x07\x80\x00\x00?\x00\x00\x00\x02J\x01\xff\xff\xfe?\x91\x04\x00\x00\x00\x00\x04\n\x07\x00\x00\x00\x8a\x80\x00\x00\x02 \x02\x1f\xff\xff\xffJQ@\x00\x00\x00\x10\x1fG\x00\x00\x00o\x00\x00\x00\x02\xe0\x00\x1f\xff\xff\xff\xa0\x88\x00\x00\x08\x04A\x1e\x07\x00\x00\x005\x80\x00\x00\x03\x18\x00\x03\xff\xff\xffzU\x00\x00\x00\x00\x10>O\x00!\x00\x1e@\x00\x00\x07\x84\x00\x00\x03\xff\xff\xa9\x04 \x00\x00\x01\x00~\x07\x00\x80\x00\x0b\x00\x00\x00\x03c\x00\x00\x03\xff\xffn\x95\x00\x00\x00\x01\x00~O\x00\x00\x00\x15\x00\x00\x00\x07\xa9\xe2\x00\x03\xff\xff\xf5B\x80\x00\x00\x00\x84\x7fN\x04\x00h\x1e\x80\x00\x00\x07\xf0\xf2`Q\xf0o\xcb\xa8\x90\x00\x00\x00@>\x0e\x00\x00\x0en\xc0\x00\x00\x06\xbf\xbd-T \x0f\xf2\xeaB\x00\x00@ \x13\x1c\x00\x00\x0f7 \x00\x00\x0f\xfd~\xd0\t@\x0f\xf1\xb4\x90\x00\x00\x00\x10,\x0e\x04\x00\x1f\x8d\x80\x00\x00\x0e\xaa?\xea\xa2(\x0f\xfe\xf9\x08\x00\x00\x08\x08\x10\x1f\x00\x00\x0f\xe8\x00\x00\x00\x15X\x8f\xea\x08@\x0f\xff*@\x00\x01\x00\x02!\x1e@\x00\x0f\xb4\x00\x00\x00\x14\x80\x0f\xf4\x01\x10\x0f\xf7\xdd\x80\x00\x00\x00@\x10\x1a\x02\x00\x0f;\x80\x00\x00\x00\x01\xe2PL\x00\x0f\xb5\xe6\xa0\x00\x00\x15\n*\x1d\x00\x00\x17\x00@\x00\x00\x00>\x80\n\x80\x08\x0f\xff\xfb\xa8\x02\x00\x08\x01\n\x9c\x82\x00\x0e7\xe0\x00\x00\x00`\x00\x06@\x02/\xee\xbd\xb0\x02\x00P\x92\x00\x0f\x00\x00\x14Z\xa0\x00\x00\x01\xc0\x10\x016\xa1_\xbc\x01\x08\x05\xc1\x00\t\x80\x0e\x80\x00BO\xd0\x00\x00\x07\xa0\x05\x00\xa9T\xbf\x1f\xff4\x15\xe8\x15\'D\x03\x80\x00\x08\x8d0\x00\x00\x1d\x80\x05P[\xaa\xaf\xfc\x07\x8a\x14\xb5@\x93\xc11\xc0\x00"\x00\x88\x00\x00\xf0\x00\x03\xe4\xaf\xd7\x7f=\xff\xdc\x07|\x04\x05@\x07\xc0\x00\x00\x00\x00\x00\x03\xea\xb0\x05\xf3o{\xff\xff\x90>\x07\xafQC\x83\x03\xc0\x000\x04 \x00\x06\t\x08\x03~\xb7\xff\xff\x83\xff\xc3\x81\xff\xa0\x02\x04!\xe0\x01\x02{\xc0\x00\x08\x05L\x01\xfd\xdb\xfb\xff>\x01\x1c@\xff\xc0\x05\x86\x01\xe0\x00!\xad\xc0\x00\n\x11#\xa8\x0f\xef\xff\xff\xe7j\xff\xa0\xff\xf0\x01E!\xf0\x00\x81^\x80\x00\x08J\xdd\xdc\x9f\xff\xff\xff\xfd-\x80\x08\x7f\xf8\x01\n\x00\xf8\x00\x01\xf7@\x00\x0c?~\xf7\xff\xff\xfd\x7f-\xe0\xff\xfe\x9f\xf9\xfc\x8f\x03\xf0\x00\x03\xdf\x80\x00\x0e/\xff\xda\xff\xaf\xff\xff\xc1\xff\xff\xff\x07\xfb\xf8\xc5\x07\xf0\x00\x01\xff\xc0\x00\x06\x9f\xff\xff\xfd\xfe\xbb\xef\xfb\xff\xff\xff\xcb\xf3\xdc\x87\x0f\xb0\x00\x03\xff\x80\x00\x07\xcf\xbb\xff\xfd\xbf\xfd\xbf\xff\xff\xff\xfc\xf5\xce6E\x83\xf0\x00\x01{\xc0\x00\x03\xf7\xff\xff\xff\xf6\xf6\xff\xfe\x7f\xff\xfcx\x08\x06\x07O\xd0\x00\x01+ \x00\x03\xff\xfa\xf7_\xdd\xbf\xff\xff\xff\xff\xff\xfc8\x06E\x8b\xc0\x00\x02[\x90\x00\x02\xea\xd6\x9a\xed\xae]\x7f\xff\xff\xff\xff\xff:\xbc\x0b\x97\x80\x00\x00\x7f\xa0\x00\x03\x00\x00\x0b\xfe\xab\xef\xbf\xff\xaf\xff\xff\xff\x97\xe0\x05\x87\x80\x00\x04\xdf\x80\x00\x00\x00\x00\x10\xaf\xb6\xaf\xdf\xff\xe7\xff\xff\xff\xc0\x00\x83\x87\x80\x18\x04\xff\x80\x00\x00\x00\x00\x00U\xdf\xff_\xbf\xff\xff\xff\xff\xe0\x00\x03\x0f\xc0\x08\r\xff\xa0\x00\x00\x00\x00\x00\x0f\xef\xd5\x7f\x7f\xfb\xff\xff\xff\xf06\x01\xc7\x80\r\xc9\xff@\x00\x00\x00\x00\x00\x07\xd2\xb5\x9f')
img_red = bytearray(b'\x00\x00\x00\x00\x00\xff\xfe\x0f\xfd\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x7f\xfc\x03\xfd\xff\xff\xfe\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00=\xfe\x00\xaf\xff\xff\xfe\x0f\xfe\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x06\x08\x00\x07\xff\xff\xff\x0f\xf8\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xf7\xff\x9f\xe0\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x06\x0f\xff\xfe\xff\x9f\xe0\x1f\xff\xff\xff\xff\xff\xff\xff\xdf\x00\x00\x00\x00\x00\x00\x00\x05.\xff\xff\xff\xc7\xc0\x1f\xff\xff\xff\xff\xff\xff\xff\xaf\x00\x00\x00\x00\x00\x00\x00\x00O\xff\xff\xff\xff\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\x7f\xbf\xfe\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xef\x00\x00\x00\x00\x00\x00\x00\x00\x07\xe2\xe5\xff\xec\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xf6\xff\xf8\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xef\xff\xf8\x00\x07\xf5\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x9fo\xf0\x00\x03\xfb\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\xe3\xe0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03{\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02>@\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x07\xff\xff\xff\xff\xff\xfe\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x03\xff\xff\xff\xdf\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00p@\xae\x00\x08\x00\x00\x00\x02\xff\xff\xff\xdf\xff\xff\xff\xff\x00\x00\x00\x00\x00\x07\xf8%\x7f\x80$\x18\x00\x00\x06\xff\xff\xff\xff\xff\xffu\xff\x00\x00\x00\x00\x00\x0f\xfc9\xff\x00\x02H\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x1f\xfc\x14?\x80\n\xa8\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xaf\x00\x00\x00\x00\x00\x15|\x0c\x0f\x80\x17@\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff_\x00\x00\x00\x00\x00\x00|\x0e\x0f\x00\n\x00\x00\x00\x03\xff\xff\xff\xff\xff\xfe\xff\xbf\x00\x00\x00\x00\x00@\xfc\x06\x01\x00\n\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xdf\xff\x00\x00\x00\x00\x00\xfe\xfa#\x00\x00\x04\x00\x00\x00\x03\xdf\xff\xff\xff\xff\xfdJ\xff\x00\x00\x00\x00\x00\xbf\xfc\x10\x01\x80\x0e\x00\x00\x00\x01\xff\xff\xff\xff\xff\xfa\x93\xff\x00\x00\x00\x00\x00?\xfe\x04\x01\x80\x08\x00\x00\x00\x03\xff\xfe\x7f\xff\xff\xe0G\xff\x00\x00\x00\x00\x00\x0f\xfe@\x0f\x80\x04\x00\x00\x00\x03\xff\xfe\x0f\xff\xff\xfa\xff\xaf\x00\x00\x00\x00\x00\x03\xff@\x03\x80\x00\x00\x00\x00\x03\xff\xff\x07\xff\xff\xfd\xfc\x1f\x00\x00\x00\x00\x00\x03\xff\x00\x01\x00\x00\x00\x00\x00\x07\xff\xfe\x03\xff\xff\xff\xf5\xff\x00\x00\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x07\xff\xfe\x00\xff\xff\xff\xd7\xff\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x07\xff\xfe\x00\xff\xff\xff?\xff\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x02\x00\x00\x00\x07\xff\xbc\x00\xff\xff\xfe\xdf\xff\x00\x00\x00\x00\x00\x00\xbe\x00\x00\x06\x00\x00\x00\x00\x0f\xff\xfe\x01\xff\xff\xfb\xef\xff\x00\x00\x00\x00\x00\x00_\x00\x00\x05\x00\x00\x00\x00\x0f\xff\x9e\x03\xfd\xff\xf7\xef\xff\x00\x00\x00\x00\x00\x00\xbf\x80\x00\x80\x00\x00\x00\x00\x0f\xffT\x07\xfe\xff\xef\xd7\xff\x00\x00\x00\x00\x00\x02\xdf\x80\x02\x01\x80\x00\x00\x00\x0f\x80\x00\x0f\xff\x7f\xff\xd3\xdf\x00\x00\x00\x00\x004J\x80\x00\x00\x80\x00\x00\x00\x0f\xc0\x00\x1f\xfd\xff\xffH\x0f\x00\x00\x00\x00\x00B\x85\xc0\x00\x00\x00\x00\x00\x00\x0f\xe0\xc7\x7f\xff\x7f\x7f \x0f\x00\x00\x00\x00\x00\x00\x03@\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xe9/\x00\x00\x00\x00\x00\x02\x01@\x00\x08\x00\x00\x00\x00\x1f\xff\xff\xfe\xff\xff\xff\xfa\x1f\x00\x00\x00\x00\x00\x03\x80p\x01?\x80\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x02\xc0X\x00\xfb\xf0\x00\x00\x00\x1f\xff\xff\xef\xff\xfd\xff\xff\xff\x00\x00\x00@\x00\x010t@{\xb8\x00\x00\x00\x1f\xff\xff\xaf\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\xad\xbd\xe0;\xfd\x80\x00\x00\x17\xff\xff\xff\xff\xf7\xff\xff\xff\x00\x00\x00\x00\x04"[\xff\xf0?\xbd\x80\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x02\x81Z\x0b\xff\xf0\x07=\x80\x00\x00?\xff\xff\xff\xff\xf7\xff\xff\xff\x00\x00\x00\x07\x80mG\xff\xf8\x009\xc0\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x03\xf0\x1bG\xff\xf8\x00)\x80\x00\x00\x7f\xff\xff\xff\xff\xef\xff\xff\xff\x00\x00\x00\x00(\x0f\xcb\xff\xf8\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x14\x00\x00\x0f\xf5\xff\xf8\x00\x00\x00\x00\x00?\xff\xff\xff\xff\xef\xff\xff\xff\x00\x00\x00\x00\x00\x0f\xf6\xff\xfc\x00\x00\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x07\xff\xff\xfc\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x03\xff\xbf\xfe\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x03\xff\xef\xfe\x00\x03\x80\x00\x00\xff\xfd\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x02\xc1\xff\xff\xfe\x00\x01\xc0\x00\x00\x7f\xfe\xff\xff\xff\xef\xff\xff\xff\x00\x00\x00\x00\x1f\xe1\xff\xfd\xff\x10\x03\xc0\x00\x00?\xfd\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00W`\xff\xff\xfe\xdc\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xef\xff\xff\xff\x00\x00\x00\x15\xaa\xd0\xff\xff\xfbP\x00@\x00\x00\x0f\xfb\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01Uw`\x7f\xff\xf8\x0c\x00\xf0\x00\x00\x03\xfb\xff\xf9\xff\x7f\xff\xbf\xff\x00\x00\x06\xff\xda\xb0\x7f\xff\xf4\n\x01\xfc\x00\x00\x01\xf1\xff\xf1\xff\x7f\xff\x7f\xff\x00\x00\n\xaf\xff\xd0\x7f\xff\xfa\x07\x01\xfc\x00\x00\x01\xf3\xff\xfe>s\x8f\xff\xff\x00\x00V\xfb\x7fx?\xff\xfc\x0f\xc1\xfe@\x00\x00\xf3\xff\xff\xfe\xf1\x87\xff\xff\x00%[]\xff\xf4?\xff\xfe\x05\xeb\xff\xc0\x00\x00?\xff\xcf\xfe\xf9\xcf\xff\xff\x02\x92\xd6\xef\xbf\xf8?\xff\xff\x03\xdf\xfd\x80\x00\x00\x0f\xff\xff\xff\xfd\xff\xff\xff\n\xea\xbd\xfb\xf7\xfe\x9f\xff\xff\xc1O\xf8\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xcfU5\xd7\xae\xff\xfe\xaf\xff\xff\xf0o\xf0\x00\x00\x00\x1f\xf3\xff\xff\xff\xff\xff\xbfU^\xbd\xff\xff\xfe\x9f\xff\xff\xf8\x17\xe0\x00\x00\x00\x0b\x03\xff\xfco\xff\xff\x7f*\xab\xf7o\xff\xffO\xff\xff\xf8\x1b\x00\x00\x00\x00\n\x03\xe3\xed#\xf7\xff\xff\xaa\xbd\x7f\xfd\xff\xfe\x87\xff\xff\xfe\x0e\x80\x00\x00\x00\x0e\x07\x01\xa07\xe7?\xffUW\xff\xff\xff\xff\xa3\xff\xff\xff\x03\x00\x00\x00\x00\x07\x02\x01\x00_\xef\xff\xff\xabm\xef\xff\xff\xff\xdf\xff\xff\xff\xc0\xc0\x00\x00\x00\x07\xf8\x00\x11C\xdf\x7f\xef]\xb7\x7f\xff\xff\xff\xe3\xff\xfd\xff\xf2\x80\x00\x00\x00\x01\xfe\x00\tk\xef\x7f\xefR\xdd\xfd\xff\xff\xff\xf9\xff\xf9\xff\xff\x00\x00\x00\x00\x01\xff\x00\x14\x97\xdf\x7f\xdfM\xf7\xff\xbf\xff\xff\xf5\xff\xf8\xff}\x00\x00\x00\x00\x01\xff\xc0\x15\x07\xfe\xff\xef\xb6\xff\xff\xff\xff\xff\xf8\xff\xf8?\x84\x0c\x00\x00\x00\x00\xff\xfbJW\xff\x7f\xbfUV\xff\xff\xff\xff\xfe\x7f\xf8\x1f\xa5\xbc\x00\x00\x00\x00\xff\xff\xe5_\xfe\xff\xbf\xab\xbb_\xff\xff\xff\xff_\xf0\x07\xff\xfc\x00\x00\x00\x00\x7f\xbf\xffW\xfd\xff\x7fR\xaa\xd7\xff\xff\xff\xff\xaf\xf0\x01\xdf\xf0\x00\x00\x00\x00\x7f\xff\xff\xeb\xff\xff\xff\xaa\xabm\xff\xff\xff\xff\xaf\xe0\x01\xff\x80\x00\x00\x00\x00?\xff\xff\xf5\xeb\xfe\x7fJ\xad_\xdf\xff\xff\xff\xf7\xe0\x01\xfe\x00\x00\x00\x00\x00?\xff\xff\xfeK\xfe\x7f\xabu\xf6\xff\xff\xff\xff\xff\xc0\x01\xf0\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xf8\x11\xffj\xae\xbb\xff\xff\xff\xff\xff\xc0\x00\xe1\x08\x00\x00\x00\x00\x0f\xff\xff\xff\xff\x02\xbf\xad\xb5\xdf\xff\xff\xff\xff\xff\xc0\x00\xf0\x06\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xc0oV\xd7\xff\xff\xff\xff\xff\xff\xe0\x002\x07\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xfc\x0f\xab\x7f\xff\xff\xff\xff\xff\xff\xc0\x00\x0e\x0f\x80\x00\x00\x00\x07\xff\xff\xff\xff\xff\x8f\xfd\xdf\xff\xff\xff\xff\xff\xff\xe0\x00\x06\x07\x80\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xab{\xff\xff\xff\xff\xff\xff\xc0\x00\x0c\x01\xc0\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xfe\xef\xff\xff\xff\xff\xff\xff\xe0\x00\x18\x00\xe0\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x18\x00`\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x1c\x009\xc0\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x1c\x00\x0f\x80\x00\x00\x01\xff\xff\xff\xff\xff\xff\xef\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x0c\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xfa\xdb\xff\xff\xff\xff\xff\xff\xf8\x00\x0e\x00\x00\x00\x00\x00\x00\xf7\xff\xff\xff\xff\xff\xef\xff\x7f\xff\xff\xff\xff\xf9\xf8\x00\x00\x00\x00\x00\x00\x00\x01[\xff\xff\xff\xff\xff\xfbo\xef\xff\xff\xff\xff\xf1\xf8\x00\x00\x00\x00\x00\x00\x00\x01\xb5\xff\xff\xff\xff\xffn\xfb\xff\xff\xff\xff\xff\xf1\xf8\x00\x00\x00\x00\x00\x00\x00\x01\xdf\xff\xff\xff\xff\xff\xb5\xae\xbf\xff\xff\xff\xff\xe0\xf8\x00\x00\x00\x00\x00\x00\x00\x01\x1f\xff\xff\xff\xff\xff_w\xff\xff\xff\xff\xff\xe1\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xff\xff\xff\xff\xff\x85\xaa\xff\xff\xff\xff\xff\xc1\xf0\x00\x00\x00\x00\x00\x00\x00\x00{\xff\xff\xff\xff\xffV\xfb\xdf\xff\xff\xff\xff\x81\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xff\xff\xff\xff\xff\x91j\xff\xff\xff\xff\xff\x81\xf0\x00\x00\x00\x00\x00\x00\x00\x00V\x1d\xff\xff\xff\xff\n\xbd\x7f\xff\xff\xff\xff\x80\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x0f\r\x9f\xaf\xff\xff\x04Wo\xff\xff\xff\xff\xc1\xf0\x00\x00\x00\x00\x00\x00\x00\x01@B\xd2\xab\xff\xff\x01\x15\xbd\xff\xff\xff\xff\xec\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01/\xf6\xbf\xff\x00Ko\xff\xff\xff\xff\xd3\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15]\xd7\xff\x00\x06\xf7\xff\xff\xff\xff\xef\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\xf7\xbf\xff\x00\x15\xbf\xff\xff\xff\xff\xde\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xfe\xef\xff\x08\x02\x7f\xff\xff\xff\xff\xef\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xaf\xb3\xff\xffJ\x01_\xff\xff\xff\xff\xd5\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x01\x7f\xf5\x7f\xf7\xff\x00\x00W\xff\xff\xff\xff\xf5`\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xf9\xbf\xfd\xdf\x11@O\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00?\xef\xfe\xc9^\xafC\xff\xf7\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00_\xfa\xffV\xabO\xff\xff\xcb\xff\xff\xff\xff\xfb\xfc\x00\x00\x00\x00\x00\x00\x00\x02\x7f\xfa\xaf\xa4U_\xff\xf8\x05\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xfc\x1bP(\x8f\xc2\x00\x03\xff\xff\xff\xff\xff\xf8\x00\x00\x00\x00\x00\x00\x00\x15O\xfa\x0c\x90\x84\x0f\x00o\xff\xff\xff\xff\xff\xfc\xfc\x00\x00\x00\x00\x00\x00\x01\xf6\xf7\xfc\x81H\x00\x0f\x7f\xff\xfc\x7f\xff\xff\xff\xfb\xfe\x00\x00\x00\x00\x00\x00\x07\xfa\xb3\xfe\x02$\x04\x0f\xff\xfe\xe0?\xff\xff\xff\xf9\xfe\x00\x00\x00\x00\x00\x00\x05\xee\xdcW\xf0\x10\x00\x0f\x18\x95\x00\x1f\xff\xff\xff\xfa\xfe\x00\x00\x00\x00\x00\x00\x07\xb5"#`\x00\x00\x0f\x02\xd2\x7f\xff\xff\xff\xff\xf5\xff\x00\x00\x00\x00\x00\x00\x03\xc0\x81\x08\x00\x00\x00\x0f\xd2\x1f\xff\xff\xff\xfe\x03\xf0\xfc\x00\x00\x00\x00\x00\x00\x01\xd0\x00%\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xfc\x07\xfa\xf8\x00\x00\x00\x00\x00\x00\x01`\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xfc\x03\xf8\xf0\x00\x00\x00\x00\x00\x00\x000@\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x01\xfa|\x00\x00\x00\x84\x00\x00\x00\x08\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x01\xf8\xb0\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x01\xfat\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x03\xf4h\x00\x00\x03\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xe8\x1f\xfax\x00\x00\x03 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xfcx\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xfc\xf0\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x8f\xff\xff\xff\xff\xff\xff\xc9\xfe8\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00-Jo')

IMG_0182_gs.py

width = 184
height = 135
img_bw = bytearray(b'\x00\x00\x00\x00\xff\x7f\x01\xf0\x02x\x10\x01\xbf\xfc\x0f\x18\x00\x0c\x02\'\xc3\x10\x0f\x00\x00\x00\x00?\xbc\x01\xfc\x00x\x00\x01\xcf\xf0\x02\x18\x00\x1e\x00\x07\x83\x00\x0f\x00\x00\x00\x00\x0f\xc0\x03\xff\x00p\x00!\xf0\xe3\xe0\x1c\x00\x00\x00\x1f\x82\x00\x0f\x00\x00\x00\x00\x0f\xf9\xf1\xff\xf8p\x00 \xe0f ?\x80\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\xff\xff\xff\xf0s\x80\x00a\xff\x00\x7f\xc1 \x0e\x00\x00\x00\x0f\x80\x00\x00\x00\x00\x07\xf3\xf8\xf0g\x80\x00p\xdf\xad\xff\xf1`\x1f\xc0\x00\x00\x0f\x00\x00\x00\x00\x00\x03\x81\xfb\xf1o\x80\x008?\xad\xfc\xfc0_\xe0!\x00\x1f\x00\x00\x00\x00\x00a\xc3\xcf\xb0\x7f\x00\x00\x00\xff\x8f\xe0?\x1a\x0f\xe0V\x00\x0f\x00\x00\x00\x00\x00\x00\xf3\xf0\xf0\xf0\x00\x00\x00\xff\x9e\xf8\x0f\xfe\x0c\xf0B\x00\x0f\x00\x00\x00\x00\x00\x00\x7f\xfc3\xc8\x80@\x01\xfe\x06<\x07\xbf>0\x10\x00\x1f\x00\x00\x00\x00\x00\x00\x7f\xfe\x08\xd8\x14\x00\x13\xfe\x0f\x08\x07?>8\x00\x00\x0f\x00\x00\x00\x00\x00\x00?\xff\x03\x1c\x98\x00\x07\xff\x08\x00\x07\x1f\xbe8\x00\x00\x0f\x08\x00\x00\x00\x00\x00\x1f\xff\x80}0\x00\x07\xff\x80\x0c\x0f\x0f\x83\xf8\x00\x00\x0f\x00\x00\x00\x00\x10\x00\x0f\xff\xc0\x06\xe0\x10\x0f\xff\x80\x00\x0f\x0f\x83\x90\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x0f\xff\xe0\x00\xf0\x1c\x17\xff\x80\x00\x9f\x0f\x87\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x0f\xff\xf1\xf8x\x00\xe7\xff\x01\x00\x87\x0f\x83\xc0\x00\x00\x0f\x00\x00\x00\x00\x00\x00?\xff\xf8\xfc\x1d\xc1\xe7\xfe\x13\xc0\x00\x003\xc0\x00\x00\x0f\x00\x00\x00\x00\x00\x00\xff\xff\xfc\xef\x0f\xdf\xe7\xfe\x14@\x00\x00\x07\xc0 \x00\x0f\x00\x00\x00\x00\x00\x01\xff\xff\xff\xff\x8f\xff\xc1\xfe\x1c@\x00\x18\x07\x98\x10\x00\x0f\x00\x00\x00\x00\x00\x03\xff\xff\xe7\xff\xff\xdf\xc1\xf8<\x00\x00\x00\x07\x98@\x00\x0f\x00\x00\x00\x00\x00\x07\x8f\xff\xf0\xcf\xf7\xff\x00\x009\x04\x00\x00/\x80\xc0\x00\x0f\x00\x00\x00\x00\x00\x08\x07\xdf\x00g\xff\xe6\x00 y\x84\x00\x00_\x80\x00\x04\x0f\x00\x00\x00\x00\x00\x10\x07\xc7\x00G\xff\xa7\xc0`t\x04\x00\xe0?\x00\x00\x00\x0f\x00\x00\x00\x00\x00 \x03\xe7\xc0G\xfd\xb7\xfc@t\x008x\x7f`\x00\x00\x1f\x00\x00\x00\x00\x00c\x83\xe3\xf0g\xec\xff\xfc\x00$\x00|\xf9\xff\x00\x00\x00\xef\x00\x00\x00\x00\x00\xff\x83\xf1\xf8\xc7\xf9\xffL\x00\x04\x00\x7f\xff\xff\x00\x00\x00\x0f\x00\x00\x00\x00\x03\xff\x03\xf8\xff\xc7\xfb\xc8\r\x00\x04\x06?\xff\xff\x00\x00\x00\x0f\x00\x00\x00\x00\x07\x00\x07\xfc\xff\xc3\xf9\xc0\x13\x00\x04\x00\x1f\xff\xfe\x00\x007\x8f\x00\x00\x00\x00\x0f\x80\x01\xff\xfec\xfb\xc0"\x00\x04\x00\x00\x7f\xfc\x00\x03\xfc\x0f\x00\x00\x00\x00?\xe0\x01\xff\xfe\x7f\xf3\x80,\x00\x04\x02\x05\x8f\xf8\x00\x0f\xf8\x0f\x00\x00\x00\x00\xff\xf0\x01\xff\xf1\x7f\xf7\xc0\x08\x00\x04\x00\x05\xf3\xf8\x00\x0f\x80\x1f\x00\x00\x00\x01\xff\xf8\x01\x7f\xfc\x7f\xff\xc0P\x00\x04\x01\x81\xf8\xf0\x00\x00\x01\xff\x00\x00\x00\x07\xff\xfc\x01\xff\xfd\xff\xff\xc0p\x00\x08\x03\x01\xf4^\x00\x00\x0f\x8f\x00\x00\x00\x07\xff\xfe\x01\xff\xf3\xff\xff\xc0n\x00\x08\x06\x01\xfb|\x00\x008\x0f\x00\x00\x00\x03\xff\xff\x80\xff\xff\xff\xff\xe2|\x00\x08\x06\x01\xfcq\x00\x00\xc0\x0f\x00\x00\x00\x00\x7f\xff\x80\xfe\x7f\xff\xff\xe6\x7f\x00\x00\x00\x03\xfd\x00\x00\x01\x00\x0f\x00\x00\x00\x00?\xff\xc1\xe7\x1f\xfd\xfd\xf6\x7f\x00\x10\x00A\xfe\x00\x00\x00\x00\x0f\x00\x00\x00\x00?\xff\x80\xc3\xbf\xf9\xff\xf0?\x00\x10\x00a\xfc\x00\x00\x080\x0f\x00\x00\x00\x00\x1f\xff\x80@?\xff\xf7\xf0\x1f\x80\x10\x00\xf9\xf8\x00\x00\x108\x0f\x00\x00\x00\x00\x03\xff\x80@?\xfew0\x07\xc00\x7f\xff\xf0@\x00\x00\\\x0f\x00\x00\x00\x00\x07\xdf0`\x1f\xff\x7fp\x00\x00\x10?\xff\xe0\x00\x00\x00\xff\xff\x00\x00\x00\x00?\xff\xf8 ?\xff\xef\xe0\x00\x00\x17\xdc\x18\x00\x00\x00\x81\xff\xff\x00\x00\x00\x00\xef\xff\xdc0\x7f\xfe\xff\xe0\x0e\x00\'\xc1\x80\x00\x00\x00\x00\x1f\xff\x00\x00\x00\x00\xc3\xff\xc7\xbf\xff\xe3\xff\xe0\x07\x00\'\x07\xf0\x00\x00\x00\x00\x07\xef\x00\x00\x00\x00\xc3\xfcg\x8f\xfe\xd2\x7f\xc0g\x00 \x0f\xfc\x00\x02\x00\x00\x00\x0f\x00\x00\x03\xc0\xc4\xec\x1b\x87\xfe\xb5\xcf\xc0g\x00`\x07\xfc\x00\x01\x00\x00\x00\x0f\x00\x00\x07\xf0\xff\xff\xcf\x83\xbf\xb1\x87\xc0?\x80p?\xc4\x00\x08`\x00\x00\x0f\x00\x00/\xf3\xff\xff\xe2\x00\x1f\xd7\x82@?\x80`?\xe6\x04\x00 \x00\x00?\x00\x00w\xe7\xff\xff\xf0\x00\x0f\xe3R@\x02\x00@?\xff\xb8\x00\x01\x1f\xf8?\x00\x00\xe7\xcc\x7f\xc7\xfc\x00\x0f\xfb\xf2`\x00\x00@?\xff\xe0\x07\xc3\x7f\xf8\x7f\x00\x07\xe3\xe8?\x81\xf8\x00\x06\xff\xb6`\x00\x00G\xff\xff\x80\x07\xe7\xff\xff\xff\x00\x07\xfd\xcc\x0f\xe0x\x00\x06\x00\xce`\x00\x00\x9f\xff\xfc\x06\x07\xe7\xff\xff\xff\x00\x07\xff\x83\xc7\xe0\x18\x00\x07\x00\xfe\xc0\x00\x00\x9f\xff\xfc|\x1f\xc7\xff\xff\x7f\x00\x0f\xff\xf9\xff\xf0\x0e\x00\x07\xc0\x7f\xc0\x00\x00]\xff\x87\xfc\xdf\xc7\xff\xff\x7f\x00\x0f\xff\xfb\xc7\xf0\x00\x00\x03\xe0\x1f\xc0\x00\x00\x9f\xfc\xcf\xf9\xff\xc7\xff\xff\xff\x00?\xdf\xc0\x0f\xf8\x00\x00\x03\xf0\x0f\xe0\x00\x00\x9f\x10\xff\xf3\xff\xc7\xff\xff\xff\x00\x1f\x00\x00?\xfc\x00\x00\x01\xfe\x1f\xe0\x00\x00\xbf\x00\xff\xf3\xff\xc7\xff\xff\xff\x00\x00\x00\x03\xff\xfc\x00\x00\x01\xff\xfcp\x00\x00\xbf\x00\x7f\xe7\xff\x87\xff\xff\xff\x00\x00\x00\xff\xfc>\x00\x00\x01\xff\xfc8\x00\x00\xbe@\x7f\xe7\xff\x87\xef\xff\xff\x00\x00\x0f\xff\xe0\x1e\x00\x00\x00\xf7\xfcp\x00\x00\\@\x7f\xe7\xff\x87\xcf\xff\xff\x00\x00\xff\xff\xc0\x1f\x00\x00\x00\x03\xff\xf0\x00\x00``\xff\xe3\xff\x07\xcf\xff\xff\x00\x1f\xff\xfe\x00\x1f\x00\x00\x00\x1f\xff\x9f\x00\x00p`\xff\xe1\xff\x07\x9e?\xff\x03\xff\xff\x80\x00\x0f\x80\x00\x03\xff\xff\x0f\xc0\x00\x0cl\xff\xe6\xba\x83\x9c?\xff?\xff\xf8\x00\x00\x0f\x80\x00\x03\xf9\xfe\x03\xe0\x00\x06.\xff\x8e\x02\xa1\x80\xbf\xff\xff\xff\xfc\x00\x00\x0f\x80\x00\x07\xf8~\x03\xe0\x00\x02-\xffp\xcd\xbcp\x7f\xff\xff\xff\xf0\x00\x00\x07\xc0\x00\x03\xf8=\t\xe0\x00\x01\r\xee\xc0;\xfep\xff\xff\xff\xff\x80\x00\x00\x07\xc0\x00\x01\xf8\x05\x08\x00\x00\x00\xeb\xcc0xv\xb3\xff\xff\xff\xfe\x00\x00\x00\x03\xe0\x00\x00\xfc\x01\x00@\x80\x00s\x8c@\x00Q>\xff\xcf\xff\x0c\x00\x00\x00\x03\xe0\x00\x03>1\xc7\x81\xc0\x00`\xf9\xff\xff\x80\x1c\xff\xbf\xff\x04\x00\x00\x00\x01`\x00\x03\x8f\x98\xd8\x03\x80\x00 \x05\xf8 \x00\x84\xbe\x7f\xf0\x00\x00\x00\x00\x00p\x00\x03\xc7\xe8\x18\x0f\x80\x00<\xfd\xc0\x03\x98\x03\xec?\xf0\xc0\x00\x00\x00\x00\xf8\x00\x07\xe3\xe0\xff\x0f\x00\x00\x15\xfc\x1c\x13\xd8\x00\x1f\xff\xf0\xe0\x00\x00\x00\x00\xf8\x00\x02\xf9\xf1\xff\xff\x00\x00\x11\xf8\xfe?\xc0\x18\xc0\x7f\xc0@\x00\x00\x00\x00|\x00\x02\xfc\xfc\xff\xfe\x00\x00\x08y\xfe\xff\xc0\x10\xc0\x0f\x00\x00\x00\x00\x00\x00\x1c\x00\x01\xfe??\xf4\x00\x00\x0c\x07\xff\xff\xcc0\x80\x1f\x80\x00\x00\x00\x00\x00\x08\x00\x01\xfe\x8f\xbf\xfc\x00\x00\x04\xcd\xff\xef\x9c \x80\x1f\xec\x00\x00\x00\x00\x00\x0e\x00\x07~\xc0\xff\xf8\x00\x00\x02\xfe\xff\xff\xf8\x01\x80\x0f\xf0\x00\x00\x00\x00\x00\x07\x00\x07~\x00\x7f\xf0\x00\x00\x02\xfe\x1f\xf3\xf8\x00\x80/\xe0\x00\x00\x00\x00\x00\x07\x00\x07\xff\x7f\xf3\xe0\x00\x00\x01~\x00y\xf0\x01\x00O\xc0\x00\x00\x00\x00\x00\x01\xc0\x07\xf7\xdaB\x9e\x00\x04\x01>\x07>\xf0\x00\x00O\x8c\x00\x00\x00\x00\x00\x00\xc0\x0f\xfc\x00\x02?\x80\x06\x01\x9f\x0e\x00\x00\x00\x00\x8f\x1c\x00\x00\x00\x00\x00\x00p\x0f\xfc\x00\x80\x7f\x00\x06\x00\x83\x07\x1e\x00\x00\x00\x8f:\x00\x00\x00\x00\x00\x00p\x1f\xfe\x00p\xff\x00\x04\x00\xcd\x06\x7f\xce\x10\x01\x8f8\x00\x00\x00\x00\x00\x00\x00\x1f\xbe\x01\xc3\xff\x00\x00\x00_\x81\xff\xf1\xb8\x03\x8f\x1c\x00\x00\x00\x00\x00\x00\x00?\x9e\x07\xd8\xfe\x00\x00\x00/\xc1\xff\xfe\x07\xf7\x0f\xcc\x00\x00\x00\x00\x00\x00\x00?\xdf\x1eb\x7f\x00\x00\x00\x17\xe7\xff\xff\xf1\xfe\x0f\xc0\x00\x00\x00\x00\x00\x00\x00?\xfb\x07\xe9\x1f\x00\x00\x00\x17\xff\xff\xff\xfc\x1b\x8f\x80\x00\x00\x00\x00\x00\x00\x00?\xc3\xcd\xf0\x8e@\x00\x00\x07\xff\xff\xff\xff\x83\xff\x00\x00\x00\x00\x00\x00\x00\x00?\x87\xf1\xf0`\x00\x00\x00\x0b\xff\xff\xff\xff\xfe\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x1f7\xf9\x880\x00\x00\x00\x03\xff\xff\xff\xff\xff\xcf\x00\x00\x00\x00\x00\x00\x00\x00?\x03\xf2\x02\x18\x00\x00\x00\x04C\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x1fE\xe4\x05\x1e\x00\x00\x00\x04\x1f\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00u\x00\x8f\xc0\x00\x00\x04\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00Q\x00F \x00\x00\x02\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00d\x81\xb0\x00\x00\x00\x02\xc9\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xc03\x83\x9d\x80\x00\x00\x02\x00?\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x07\xc01\x80\x8f\x00\x00\x00\x02\x00\x0f\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x06\x07\x80\x1e\x00o\x80\x00\x00\x02@\x03\xff\xff\xff/\x00\x00\x00\x00\x00\x00\x00\x0e\x07\x80\x00\x00?\x80\x00\x00\x02d\x01\xff\xff\xfe?\x00\x00\x00\x00\x00\x00\x00\x1e\x07\x00\x00\x00\x1f\x00\x00\x00\x02 \x00\x1f\xff\xff\xff\x80\x00\x00\x00\x00\x00\x00\x1f\x07\x00\x00\x00o\x00\x00\x00\x03\xe0\x00\x0f\xff\xff\xff\xe0\x00\x00\x00\x00\x00\x00>\x07\x00\x00\x00?\x80\x00\x00\x03\x00\x00\x03\xff\xff\xffp\x00\x00\x00\x00\x00\x00>\x07\x00 \x00?\xc0\x00\x00\x07\x84\x00\x00\x03\xff\xff\xfc\x00\x00\x00\x00\x00\x00~\x07\x00\x00\x00/\x00\x00\x00\x07\xe3\x00\x00\x03\xff\xff\x7f\x00\x00\x00\x00\x00\x00~\x0f\x00\x00\x00\x1f\x00\x00\x00\x07\xe1\xe2\x00\x03\xff\xff\xf7\x80\x00\x00\x00\x00\x00\x7f\x0e\x00\x00 \x1e\x80\x00\x00\x07\xf0\xf0\x00\x01\xf8?\xcf\xc0\x00\x00\x00\x00\x00?\x0e\x00\x00\x0e?\xe0\x00\x00\x0f\xff\xf8\x00@ \x0f\xe3\xf0\x00\x00\x00\x00\x00\x13\x1c\x00\x00\x0f\xbf\xa0\x00\x00\x0f\xff\xff\xe0\x00\x00\x0f\xf1\xf8\x00\x00\x00\x00\x00>\x1c\x00\x00\x0f\xcf\x80\x00\x00\x0f\xfe?\xf0\x00\x00\x0f\xfex\x00\x00\x00\x00\x00\x10\x1f\x00\x00\x0f\xe4\x00\x00\x00\x0f\xe0\x1f\xfc\x00\x00\x0f\xff6\x00\x00\x00\x00\x000\x1e\x00\x00\x0f\xfe\x00\x00\x00\x1f\x00\x0f\xf0\x00\x00\x0f\xff\xdf\x80\x00\x00\x00\x00\x00\x1e\x02\x00\x0f\xbf\x80\x00\x00\x00\x01\xe0`\x00\x00\x0f\xfd\xe7\xc0\x00\x00\x00\x002\x1e\x02\x00\x1f\x80\xc0\x00\x00\x00>\x00\x00\x00\x00\x0f\xff\xfb\xe0\x00\x00\x00\x00\x00\x0c\x00\x00\x0f\x1f\xe0\x00\x00\x00`\x00\x06\x00\x00\x0f\xff\xfd\xb0\x00\x00\x00\x00\x00\x1e\x00\x00\x1e\x1f\xf0\x00\x00\x01\x80\x00\x00 \x00\x7f\xfc\x00 \x00\x00\x00\x00\x00\x07\x80\x00 _\xf0\x00\x00\x0f\x80\x00\x001\xc0\x1f\x1f\xff0\x00@\x00\x00\x00\x01\x80\x00\x00\x8fx\x00\x00\x1c\x80\x03\x00{\xe4\x7f\xfc\x03\x88\x000\x00\x01\x00\x01\xc0\x00 \x00\x18\x00\x00\xf0\x00\x03\xe0\x1f\xff\xff?\xff\xf8\x06\x1c\x00\x03\x80\x07\xc0\x00 \x00`\x00\x03\xc0\x10\x01\xf3\xef\xff\xff\xff\xc0>\x03\x8e\x00\x01\x01\x07\xc0\x00\x10\x040\x00\x06\t\x00\x03\xff\x7f\xff\xff\x81\xff\xc3\x81\xff\x80\x01\x06\x03\xe0\x00 ?\xc0\x00\x08\x00\x04\x01\xff\xff\xff\xff>\x00\x1e@\xff\xc0\x00\x06\x01\xe0\x00!\xff\xc0\x00\x08\x00\x01\xe0\x1f\xff\xff\xff\xe7\xf1\xff\xa0\x7f\xe0\x00\x06\x01\xf8\x00\x81\xff\xc0\x00\x0c\x08\xe7\xde\x9f\xff\xff\xff\xff/\x80\x08\x1f\xf0\x10\x0f\x01\xf8\x00A\xff\xc0\x00\x0c?\xff\xff\xdf\xff\xff\xff\x0f\xe0\xff\xfc\x0f\xfb\xf8\x8f\x03\xf8\x00\x01\xff\x80\x00\x0c\x1f\xff\xff\xff\xff\xff\xff\xc0\xff\xff\xff\x07\xfb\xfc\x0f\x07\xf0\x00\x03\xff\xc0\x00\x06\x1f\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff\xc1\xf3\xfc\x07\x8f\xf0\x00\x03\xff\xc0\x00\x07\xdf\xff\xff\xff\xff\xff\xff\xf3\xff\xff\xfc\xe0\xcf\xfe\x03\x87\xf0\x00\x01{\xc0\x00\x03\xf7\xff\xff\xff\xff\xff\xff\xfe\x7f\xff\xfcx\x1c\x06\x07\x07\xd0\x00\x00{\x80\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc8\x06\x07\x8b\xc0\x00\x02?\xc0\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe8|\t\x8b\xc0\x00\x00\x7f\xe0\x00\x03\xc0\x00\x1f\xff\xff\xff\xff\xff?\xff\xff\xff\x87\xc0\x07\x87\xc0\x00\x04\xff\x80\x00\x00\x00\x00\x1b\xff\xff\xff\xff\xff\xef\xff\xff\xff\xc0\x00\x03\x87\x80\x08\x04\xff\xe0\x00\x00\x00\x00\x00\xff\xff\xff\xff?\xff\xff\xff\xff\xe0\x00\x03\x87\xc0\x1c\r\xff\xc0\x00\x00\x00\x00\x00\x1f\xff\x80\xff\x7f\xfb\xff\xff\xff\xf0>\x03\x87\xc0\x0f\xe9\xff\xc0\x00\x00\x00\x00\x00\x07\xc1\xfd\x8f')
img_red = bytearray(b"\x00\x00\x00\x00\x00\xff\xfe\x0f\xfd\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x7f\xfe\x03\xff\xff\xff\xfe?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00?\xfc\x00\xff\xff\xff\xfe\x0f\xfc\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x06\x0e\x00\x07\xff\xff\xff\x1f\xf8\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\x9f\xe0\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x07\x0f\xff\xff\xff\x8f\xe0\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x04\x0e\xff\xff\xff\xc7\xc0\x1f\xff\xff\xff\xff\xff\xff\xff\xef\x00\x00\x00\x00\x00\x00\x00\x00O\xff\xff\xff\xff\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf7\x7f\xbf\xfe\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xef\x00\x00\x00\x00\x00\x00\x00\x00\x07\xe7\xeb\xff\xec\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xe7\xff\xf8\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xcf\xff\xf8\x00\x07\xf3\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x1f\xef\xf0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xe3\xe0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02>\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00p\x00\x0f\x00\x08\x00\x00\x00\x06\xff\xff\xff\xdf\xff\xff\xff\xff\x00\x00\x00\x00\x00\x07\xf8 \xff\x80\x00\x18\x00\x00\x06\x7f\xff\xff\xbf\xff\xff\xfb\xff\x00\x00\x00\x00\x00\x0f\xf88\xff\x80\x00X\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x1f\xfc\x18?\x80\x02H\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xef\x00\x00\x00\x00\x00\x1c|\x1c\x0f\x80\x13\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\x1f\x00\x00\x00\x00\x00\x00|\x0e\x07\x00\x06\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\xfc\x07\x00\x00\x04\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\xff\xf8\x03\x00\x00\x06\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xc8\x7f\x00\x00\x00\x00\x00\x7f\xfe\x00\x01\x80\x04\x00\x00\x00\x03\xff\xff\xff\xff\xff\xfc\x03\xff\x00\x00\x00\x00\x00\x1f\xfe\x00\x01\x80\x0c\x00\x00\x00\x03\xfd\xfe\x7f\xff\xff\xf0\x07\xff\x00\x00\x00\x00\x00\x0f\xfe\x00\x0f\x80\x08\x00\x00\x00\x03\xff\xfe\x0f\xff\xff\xf0\x7f\xef\x00\x00\x00\x00\x00\x07\xfe\x80\x03\x80\x00\x00\x00\x00\x03\xff\xfe\x07\xff\xff\xff\xfe\x0f\x00\x00\x00\x00\x00\x03\xfe\x00\x02\x00\x00\x00\x00\x00\x07\xff\xfe\x03\xff\xff\xff\xf0\x7f\x00\x00\x00\x00\x00\x01\xfe\x00\x00\x00\x00\x00\x00\x00\x07\xff\xfe\x00\xff\xff\xff\xc7\xff\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x07\xff\xfe\x00\xff\xff\xff?\xff\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xfc\x00\xff\xff\xfe\xff\xff\x00\x00\x00\x00\x00\x00>\x00\x00\x02\x02\x00\x00\x00\x0f\xff\xbe\x01\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x06\x00\x00\x00\x00\x0f\xff\x9e\x03\xff\xff\xf7\xcf\xff\x00\x00\x00\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x00\x00\x0f\xff\x06\x07\xff\xff\xef\xc7\xff\x00\x00\x00\x00\x00\x00\x7f\x80\x00\x01\x80\x00\x00\x00\x0f\x80\x00\x0f\xff\xff\xff\xa3\xff\x00\x00\x00\x00\x00 \xcf\x80\x00\x00\x80\x00\x00\x00\x0f\xc0\x00\x1f\xff\xff\xff\x00\x0f\x00\x00\x00\x00\x00\x00\x07\xc0\x00\x00\x00\x00\x00\x00\x0f\xe3\xe7\xff\xff\xff~\x00\x0f\x00\x00\x00\x00\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xe0\x0f\x00\x00\x00\x00\x00\x00\x00@\x00\x1c\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xf8\x1f\x00\x00\x00\x00\x00\x03\x80p\x01?\x80\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x03\xe0x\x01{\xb0\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x000|@{\xf8\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x1d\xff\xe0;\xfd\x80\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x0f\xff\xf0\x1f\xbd\x80\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x03\x808\x03\xff\xf0\x07=\x80\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x07\xc0~\x07\xff\xf8\x00y\x80\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x03\xf0\x1f\x87\xff\xf8\x001\x80\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x008\x1f\xe7\xff\xf8\x00\x01\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x0f\xf1\xff\xf8\x00\x00\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x0f\xff\xff\xfc\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x07\xff\xff\xfc\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x03\xff\xff\xfe\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x03\xff\xff\xfe\x00\x03\x80\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x03\xc1\xff\xff\xfe\x00\x03\xc0\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x1f\xe1\xff\xff\xff\x08\x03\x80\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00?\xe0\xff\xff\xff\xfc\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x01\xff\xe0\xff\xff\xff\xe0\x00`\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x7f\xff\xf0\x7f\xff\xfc\x00\x00\xf0\x00\x00\x03\xf3\xff\xf9\xff\x7f\xff\xff\xff\x00\x00\x07\xff\xff\xf0\x7f\xff\xfc\x06\x01\xfc\x00\x00\x01\xf1\xff\xf1\xff\x7f\xff\x7f\xff\x00\x00\x03\xff\xff\xf0\x7f\xff\xf8\x07\x81\xfc\x00\x00\x01\xf3\xff\xff>s\x8f\xff\xff\x00\x00\x0f\xff\xff\xf8?\xff\xfc\x07\xc3\xfe\x00\x00\x00\xf3\xff\xff\xfcq\x8f\xff\xff\x00\x00\x7f\xff\xff\xf8?\xff\xfe\x07\xfb\xff\xc0\x00\x00\x17\xff\xcf\xff\xf9\xcf\xff\xff\x00\x01\xff\xff\xff\xfc\x1f\xff\xff\x03\xff\xff\x80\x00\x00\x0f\xff\xff\xff\xfe\xff\xff\xff\x00\xf3\xff\xff\xff\xfc\x1f\xff\xff\xc1\xcf\xf8\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xcf\x00\xfb\xff\xff\xff\xfe\x9f\xff\xff\xf0g\xe0\x00\x00\x00\x1f\xfb\xff\xff\xff\xff\xff\x9f\x0f\xff\xff\xff\xff\xff\x8f\xff\xff\xf8\x17\xe0\x00\x00\x00\x03\x03\xff\xfcg\xff\xff\xff\x0f?\xff\xff\xff\xff\x07\xff\xff\xfc\x1f\x00\x00\x00\x00\n\x03\xe3\xec\'\xff\xff\xff\x0f\x1f\xff\xff\xff\xff\x07\xff\xff\xfe\x0e\x00\x00\x00\x00\x0e\x07\x01\xc0?\xe7?\xff?\xbf\xff\xff\xff\xff\x83\xff\xff\xff\x03\x00\x00\x00\x00\x07\x86\x01\x00?\xef?\xff\xff\xff\xff\xff\xff\xff\xe3\xff\xff\xff\xc0\xc0\x00\x00\x00\x03\xf8\x00\x003\xcf\x7f\xef\x7f\xff\xff\xff\xff\xff\xf7\xff\xff\xff\xf0@\x00\x00\x00\x03\xfe\x00\x10c\xdf\x7f\xef\x13\xff\xff\xff\xff\xff\xf1\xff\xf8\xff\xff\x00\x00\x00\x00\x01\xff\x00\x00\x07\xfe\x7f\xff\x0f\xff\xff\xff\xff\xff\xf8\xff\xf8\xff\xff\x80\x00\x00\x00\x01\xff\xe0\x0c\x07\xff\x7f\xdf\x1f\xff\xff\xff\xff\xff\xf8\xff\xf8?\x80\x0c\x00\x00\x00\x00\xff\xff\x86\x0f\xfe\xff\xbf?\xff\xff\xff\xff\xff\xfe?\xf8\x0f\xa5\xbc\x00\x00\x00\x00\xff\xff\xc1\x0f\xff\xff\xbfs\xff\xff\xff\xff\xff\xff?\xf0\x03\xff\xfc\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\x7f\xe3\xff\xff\xff\xff\xff\xff\x8f\xf0\x03\xff\xf8\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\x7f\xc5\xff\xff\xff\xff\xff\xff\x8f\xe0\x01\xff\x80\x00\x00\x00\x00?\xff\xff\xf1\xef\xfe\x7f\xc7\xff\xff\xff\xff\xff\xff\xff\xe0\x01\xfe\x00\x00\x00\x00\x00?\xff\xff\xfeG\xfc\x7f\xe3\xff\xff\xff\xff\xff\xff\xff\xc0\x01\xf8\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xf8\x08\xff3\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xe1\x8c\x00\x00\x00\x00\x0f\xff\xff\xff\xfe\x01\xff?\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xf8\x06\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xe0\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xc0\x002\x0f\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xfc\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x0e\x0f\x80\x00\x00\x00\x07\xff\xff\xff\xff\xff\x8f\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x06\x07\xc0\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x0c\x01\xe0\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x18\x00\xe0\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x18\x00p\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00<\x009\xc0\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x18\x00\x0f\x80\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x0c\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x0e\x00\x00\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf9\xf8\x00\x00\x00\x00\x00\x00\x00\x01\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\xf8\x00\x00\x00\x00\x00\x00\x00\x01\x9b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe1\xf8\x00\x00\x00\x00\x00\x00\x00\x01\xdf\xff\xff\xff\xff\xff\x7f\xff\xff\xff\xff\xff\xff\xe0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\x1f\xff\xff\xff\xff\xff\xff\xc1\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x8f\xff\xff\xff\xff\xff\xff\xc1\xf8\x00\x00\x00\x00\x00\x00\x00\x00{\xff\xff\xff\xff\xff\x03\xff\xff\xff\xff\xff\xff\x81\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xff\xff\xff\xff\xff\x80\xff\xff\xff\xff\xff\xff\x81\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x1d\xff\xff\xff\xff\x08\x7f\xff\xff\xff\xff\xff\x80\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\xff\xff\xff\xff\x00?\xff\xff\xff\xff\xff\xc0\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\xbf\xff\xff\x00\x0f\xff\xff\xff\xff\xff\xec\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xc1\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xef\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xff\xff\xff\x00\t\xff\xff\xff\xff\xff\xcf\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\x00\x00\x7f\xff\xff\xff\xff\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x9f\xff\xff\xff\x02\x00?\xff\xff\xff\xff\xcd\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xff\xff\xff\xff\x00\x00\x1f\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xf9\xff\xff\xff\x00\x00O\xff\xff\xff\xff\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xdf\xff\x8f\x03\xff\xdf\xff\xff\xff\xff\xff\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xce?\xef\xff\xff\xcf\xff\xff\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x03\x7f\xfc\xff\x84\x1b\x8f\xff\xfc\x07\xff\xff\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xfc\x1f\xe0\x00\x0f\xc0\x00\x07\xff\xff\xff\xff\xff\xf8\x00\x00\x00\x00\x00\x00\x00?\xef\xfe\x0c\x10\x00\x0f\x00?\xff\xff\xff\xff\xff\xfe\xf8\x00\x00\x00\x00\x00\x00\x01\xf6\xff\xfc\x00\x80\x00\x0f\x7f\xff\xfc\x7f\xff\xff\xff\xf9\xfc\x00\x00\x00\x00\x00\x00\x07\xff\xfb\xfe\x00\x00\x00\x0f\xff\xff\xe0?\xff\xff\xff\xf9\xfe\x00\x00\x00\x00\x00\x00\x07\xff\xfe\x1f\xe0\x00\x00\x0f\x18\x0e\x00\x1f\xff\xff\xff\xf9\xfe\x00\x00\x00\x00\x00\x00\x03\xf7\x18!`\x00\x00\x0f\x00\xd0\x7f\xff\xff\xff\xef\xf0\xfe\x00\x00\x00\x00\x00\x00\x03\xc0\x00\x00 \x00\x00\x0f\xf0\x1f\xff\xff\xff\xfc\x07\xf0\xfc\x00\x00\x00\x00\x00\x00\x03\xe0\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xfc\x03\xf0\xf8\x00\x00\x00\x00\x00\x00\x01\xe0\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xfc\x03\xf8p\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x01\xfcx\x00\x00\x00\x84\x00\x00\x00\x08\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xe0\x01\xf8\xf8\x00\x00\x01\x84\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x01\xf8t\x00\x00\x01\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x03\xf6t\x00\x00\x03\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xf8?\xf8x\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xfcx\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xfcx\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x0f\xff\xff\xff\xff\xff\xff\xc1\xfcx\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00>\x02\x7f")

IMG_0182_bw_d.py

width = 184
height = 135
img_bw = bytearray(b'\x00\x00\x00\x00"\xff\xb5\x15\xaa\xfd\xbb\xda\xbf\xff\x7f\xbd\xdd\xde\xf7\xf7\xef\xde\xdf%UUU\x14z\xd5J\xb5\xba\xedm?\xf5J\xf6\xaa\xbb]_Z\xb5_\x08\x00\x00\x00\x81\x15,*\xab{U\xb5E\xea7]\xdfn\xd6\xed\xefwoAR\xaa\xaa*J\xabA-\xf5\xb6\xed-t\x9a\xbfU\xb7{[z\xda\xbf\x10\x04\x00\x00\x80\x95Q,\x96\xbf\xd5V\xb7\xe2\x16\xff\xeb\xed\xae\xed\xafm_D\x90\x95T$"\x04\x86\xaa\xee\xd5{J\xd4\xad\xff\xfd{\xdf\xb5\xfa\xdbO\x10\x04\x00\x02\x82\x89A)Uo\xda\x95\xaa\x82\x1f\xed\xfb\xae\xf6\xebW\xb5\x7fBQUP( \x88\x84\xaa\xfbon\xb6\xa9[\xf6\xbe\xfb_\xbd\xfdm\x8f\x10\x04\x00\x05\x01\n"!+\xadR\xbbU$\x0e\xfb_\xaf\xb5\xf6\xaf\xb5\x7fE!$\x90\xa4@\x91T\x0e\xea\xad\xad\xea\x92\x9f]\xaf\xfa\xfe\xbb\xf5k\xaf\x10\x08A\n\x01)*!%\xd5j\xb5,P\x05\xb6\xd6\xbfWm^\xda\xafD\xa2\x12@\xa8\x00\x04\x94\x02S\xd5]\xb5J\xa7[o\xd7\xfd\xfb\xf5\xb5\xbf\x11\x00\x80\x14\x02J\xa9UHJ\xaa\xd6\xd1A\x05\xe5_}Wm[n\xdfD\x12*\x81P\x10\x04$\x80\x02\xadUU*%Z\xef\xaf\xed\xbb\xef\xb5o\x11@@$\x04\x82B\x92R\xa8UUR\x10\x96\xeb\xbe\xef{\xedZ\xdb\xbf\x04\t\x12A" \x14\xaa\x80\x02\x15j\xa1U\x03\xbd\xd7_\xaf[\xbfmOQ \x04\x14H\tB\xa4UQ%UH\xa0V\xd5k\xb5\xf7\xf6\xea\xab\x7f\x04\x04\xa1A\x02\x80\x14\x95P\x08\x82U"U\x05\xebz\xbd[\xbbZ\xb5O!P\x08\x08P%J\xaa\xadR\x11D\x89B&\xb6\xadko\xddv\xd5\x7f\x08\x02"B\x04\x80!RU\tM\x12\x80\x90\x92\xed\xb6\xb6\xaf\xeb\xaa\xad\xafB\xa8\x84\x10\x90\n\xdc\xaa\xaa\xa4\xaaJ$\n\x15^\xd5\xdb\xbf]\xf6\xb5_\x10\x00\x11D\x01%\xb2UUB\xa9h\x81@\xa5kkn\xbf\xf6\xaa\xd5\xbfEJ@\x11H\x16\xd9Un\x89%T$(\x15\xae\xdb\xbb\x7f[[V\xcf\x00\x10\x05\x04\x00[l\xaa\xb5D\x9a\xaa\x90\x82\xa2\xb5\xbc\xed\xfb\xed\xadj\xbf*\x82\x90P$*\xb5\x1aO"\xa5TD\x10\x0bZ\xfb\xfd\xffUj\xadO\x00(\x01\x01\x01D\xac\xab)\x88\x9a\x82\x12D\xa2\xd7\x7f\xff\xff\xdbZ\xb6\xbfI\x02H\x10$\xb2\xb5UU"JP\x81\x00\x05]\xdf\xff\xfdj\xaa\xca\xaf\x00P\x02B\x02\xadT\xaa\x8a\x88\xaa\x84("\x12\xab{\xef\xff\xabmU_)\x05P\x00IV\xea\xaa\xa5B\x15\x01\x05\x08C\xd6\xd6\xbf\xfa\xed\xaa\xaa\xbf\x00@\x02H\x12Z\xaeT\x15\xa9UP @\n\xba\xad_\xfdUT\xa5\xcfI\x11\x08\x01A+uJ\xaa\x92*\x04\x89\x04\x85\xd5\xb6%\xb6\xdbj\xb6_\x00\x04 \x84TJ\xaa\xa8KI\x11\x90 \x10\x05^\xda\x96\xfbm\xaa\xd5_$@\x02\x11I%\xb6\xa5\x05T\xac\x82\x92\x01\x15\xab\xadCo\xb6\xdbU_\x01\x02H\x02\xa4\x95Z\x90\xa8\x92\x02H$@\x06\xde\xb5(\xfa\xdbmUo$\x10\x00A*%mJ"IU"@\x08Kk\\\x81_u\xb5V\xaf\x00B"\x04IJ\xab$\x89U%D*\x81\n\xb6\xd5T\xe9\xde\xd6\xab\x7fH\x00\x00\x00$)Z\x88%J\x92!\x12 \r\xabZ#V\xb5\xb5Z\x9f\x01\x12H\x11\x15\xa5mB\x92\xaaJ\x90H\x84+]UMZ\xdbU\xaa\xdfD\x00\x00@D\x95U *UQ%\x04\x10\x15\xa5U%\xeam\xaa\xd5_\x10D\x01\x02\x02\xaa\xab\x89\x15B\x84\x00"\x81\x15U$\x9b[V\xaf*\xaf\x00\x00\x90\x00\x92UU@\x8a*\xa2\xa8\x08HV\xa0\x89-\xaa\xbbt\xaa\xafD\x90\x00\n)UJ\xaa!QJ\x01 \x00\x1f\xde\xd6\xf6\xb5mV\xa4\x9f\x10\x02\x00 \x85%%@\x95\x08$\xa0\nD\x8be\xb5\xaa\xdb\xb6\xb5UO\x00\x00\x02\x00BE\n\xb5$\xb6\x92I"\x00>\xbf\xfbZ\xae\xda\xdbj_\x02H\x08\x89\x11%\xc2\xd4\x92\xbbU\x00E)\x15\xd6\xde\xd5wj\xad\xb5\xafH\x00! D\x951*R\xf7\xa9D\x12\x80W{\xf6\xab\xda\xbbv\xad\x7f\x00\x00\x04\xa4\x92EUUI9\xed@\x84\t*\xaf]V\xbf\xd5\xabV\xaf\x02D\xa5QU*\xadj\xe4\xf7\xb5 )@+\x7f\xf7\xbd\xd5v\xdd\xdb\xdf \x00\x12\xa4*\xa9U\xb6\xb2\x1b*\x89\x02\x12Z\xff\xfd\xebm\xd5\xb7u\x7f\x00\x01E\x07\x85UU[T\xa7{@\x08\x00V\xbd\xefv\xdbk}\xde\xdf\t\x14P\xa9qUK\xad\xe9\x10\xb5P\x80\x92_\xef\xfb\xafw\xd7\xdf\xfb\xbf \x02\x8aE\xaaV\xaa\xebtDR\x82\x10\x00\xbb\xbf\xdd{\xadov\xfe\xff\x00\ti\x02T\x9a\xab[\xaa\x11\n\xa0\x02\x94n\xff\xb7\xad\x7f\xed\xff\xdb\xbf\x05$\x95(\x92*\xd5v\xf5@R\x88@\x01;\xfe\xed\xfb\xab\xd7\xf6\xff\x7f\x00\x05J\xa2\x08\x8e\xaa\xbbZ\x14\x84@\x08Ho{\xbb]\xffo\xdf\xff\xff\x014\x89\x08\xa2Su\xad\xea\xa0"\xa1\x02\x02_\xac\xef\xf7\xaf\xdf{\xfb\x7f\x10B  \tE\xae\xab]\n\x8a\x84 \x90\xfdu\xfd\xb6\xfd\xd7\xffo\xdf\x01\x08\x04\x05U*\xb5\xad\xea\xa0%P\x02\x04\x7f\xd6\xdf\xf7\xff\xaf\xed\xff\x7f\x00\x00\x11Q*\xd2\xd6\xd5u\x15K\xa0\x88A^\xb9{\xef\xef\xdd\xb7\xff\xff\x08\x01B*\xadU[u\xadT\x91J\x00\x146\xeb\xff\xb6\xbd\xaf\xdf\xfe\xff\x01(\x14\xa5U\xa9m\xadj\xdaD\xa0"A[l\xef\xfb\xefU\xef_\xdf \x05J\x95UT\xb5v\xb5U)U\x00\x08\n\xf5\xfe\xeb}\xaf]\xbf\x7f\n\xa9)j\xaa\xaa\xd6\xab\xaa\xaa\x84\xd4\x92\x82E\xaa\xfb\xe9\xabu\xfa\xbf\xff@\x92\xaa\xadj\xd2[\xddU\x14\xa9\xb5@(\x12\xf3\xff\xaa\xb6\xabN\xbd\xff*JUU\xadYmk\xb4\xabR\xdd$\x81B\xaa\xee\xfa\xadu%\x7f\xdf\x95UU\xaa\xb6\xaa\xaa\xadmUK\xb6\x82\x10\x11s\xf7U|\xb2\xd6\xf7\xffR\xaa\xaa\xb6\xd5\xaa]\xd5\xb6\x95\xb5\xda\xd0BD\x97\xda\xab\xd5y\xab\xffoJ\xaa\xadUZ\xea\xabz\xda\xa5W{B\x00\x00J\xad\xddz\xd6\xfe\xdd\xdf\xaa\xaa\xb5\xabWZ\xadWWUU\xd4\x88\x92\xa47\xfb\xf7\xaf\xba\x9b\xf7_UUU]j\xb5U\xaa\xb7\xa9V\xe0\x02\x00\x01\x1aJ\xdduov\xbe\xaf\xaa\xaa\xd6\xaa\xb5Z\xae\xfa\xdb\xe9WU \x84HK%\xea\xaa\x91\xad\xd5\x7fUmZ\xd5\xae\xedR\x96\xae\xf5) \x8a\x10\x00\x14\x96\x95T\xaa\xd6\xbf\xbf\xabU\xabmkUV\xeb[\xba\x96\x95 AI\nJ\xa2\xaaWSUoUV\xb5V\xb5\xb6\xabZ\xb6\xfdUH\n\x00\x00ORJ\x92\xa9\xad5\xbf\xaa\xaa\xdb\xbb\xde\xdb\xa9m\xdb\xf7Ue@\t$\x01\xaa\x92IV\xaa\xda\xcfZ\xb5UUR\xadU\xaa\xb5\xde\xd5R(\x80\x00\x95\xfcI*\xa2\xd6m\xaf\xabV\xadj\xbd\xb5\xaa\xd6\xd5\x7f\xea\xa8\x92\x04\x92\x02\xdf$\xaaU[V\xdfUZ\xd5\xad\xd6\xda\xd5kt\xfaUE@ \x00!\xfe\xd2UK\xac\xbb_\xaa\xd5z\xb6\xaa\xafj\xbd\xaa?\x95\x14"\x02H\x84\xffm\x95-UUOUV\xad\xd5[uZ\xaa\xe9N\xad\xad\x08\x88\x02\x01[_\xaa\xa5\xb5{_\xaa\xaa\xa6\xae\xed\xabmWT%\xf6\xb4R \xa4\x10\xbfV\xd5Z\xd5\xadoV\xb5\xb5kUm\xb6\xaa\xd5UJ\xd0I\x00\x00DU\xbf\x7fUUj\xbf\xaa\xd5U\xb5{\xb6\xdbU\xaa\x05o%$I\x12\x01\x7f\xd6\xff\xea\xaa\xb5OU*\xaa\xad\xadm\xb6\xab\xd1R\xd4\x80\xaa\x00@\x10-k\xff\xf5U\xaa\x7f\xaa\xd5[V\xab\xb6\xdb\xddT\tRRQI\x08\x84\x9f\xd5\xff\xff\xaaUOkV\xd5j\xdd[mkR\xa2\xd9H$\x00\x02\x00\x17\xff\xff\xff\xfa\x8a\xbf\xadZ\xad\xb7km\xb7\xb6\xc9\x11eG\n\xa4H$\x9d\xef\xff~\xffaOUUv\xda\xdd\xb6\xda\xdd\xa8\x88\xaaZ\x80\x01\x00\x00\x07\x7f\xff\xff\xfd\xdc/\xaa\xab\xabm\xb6\xdbm\xb7U"-\x0e\xa5$!"M\xdd\xff\xef\xef\xff\x9fU\xb5Z\xaa\xd5m\xb6\xda\xd2\tFE@\x00\x04\x08\x07\xff\xff\xfd\xbf\xff\xef\xb6\xadm\xb7o\xb6\xdboT\xa2\x14\x12\xa8\x91 \x00\x92\xab\x7f\xff\xff\xf7\xff\xaa\xb5\xaa\xda\xb4\xdbm\xb9\xa2\x08\xa9\x00\xd2\x04\x01"\x02\xff\xf7\xff\x7f\x7f\xff\xb6\xd6\xb6\xad\xdbm\xb6\xee\xd8\xa24\ni@\x90\x08%\xb7\xff\xff\xfb\xff\x7f\xdb[kj\xad\xb6\xdbU\xa5\x089 *\xa4\x02 \x82\xfd\xbe\xfd\xef\xed\xffUj\xdd\xb6\xd6\xdbm\xf6\xd8A\x14\x81\x17\x00\x88\x00\x03\xaf\xfb\xf7\xff\xbf\xef\xad\xadj\xd5uj\xb6\x9bj\x10\x8a\x05%H \x84 \xd4\xbf\xff\xff\xff\x7f\xb5U\xaf[\xae\xad\xdbj\xd5D*\x80H\x02\x00\x10\x8bU\xaf\xbf\xbf\xfd\xff\xaa\xda\xa9\xb6\xb5\xd6\xb6\xd5i\x00\x80\x00\x05 \x84@\x00\xaa\xb5\xfe\xf6\xef_\xb6\xabV\xdbZ\xbb\xdbi\xb4\x90\x14I(\x88!\x02\x05\xaa\xdfo\xff\xfd\xbfUZ\xda\xad\xefmm\xa5U\x02A\x00E\x02\x00\x08QUU\xbf\xff\xff\xff\xaa\xd5m\xb5)\xb5\xb6\xd2\xea \x00\x12" \x88 \x02\xae\xda\xdb\xdd\xdf\xff[V\xaa\xd6\xee\xd6\xdbUX\x82\x92@\x94\x88!\x01\x05Skn\xff\xfd\xbf\xaa\xaa\xd6\xb5U[UB\xea\x08\x00\x08\t\x02\x00\x00!Z\xb5U\xab\xff\xffU[[[\xbbm\xbbUU!"\x92DP\x84H\x85UV\xb6\xaf\xf7\xef\xaa\xd4\xb5\xedm\xb6\xd5J\xe8\x00\x08\x00"\x02 \x00\t*\xaa\xd5U\xbf\x7f\x15V\xd6V\xd6\xd5n\xa5UJAQ\x14\x90\x01\x02"\xaa\x95Uk\xfa\xff\x85Z\xab\xabk[\xb5\xa9h\x00\x10\nJD\x88\x10\n\xa5J\xaa\xaa\xd5OR\xa5Z\xb5]\xb6\xde\xad\xaaI\x04$\x11\x10 \x01$\x90%U\xaa\xaf\x7f@\xaa\xaa\xdbj\xdbkR\xa8\x00 \x8a\x88B\x00\x84\x02%\x12\x96\xadR\xafZU\xb6\xad\xb7m\xb5\xadeT\x82\x02E\x08\x82\x00I\x08HUU\xad\xafT\x15U\xb6\xaa\xb6\xae\xab\xa8\x00\x00)( \x10\x10\x10\xa0\x0bUj\xaa\xbf\x92\x8a\xadZ\xdd\xdbwl\xa5$\x08\x84\x82\x82@\x02D\x02\xb5U\xaa\xd6\xafUR\xb6\xedkm\xad\xabh\x02@\x12(\x10\x00@\x00)Z\xaa\xb7Z\xdfUB\xabW\xb6\xb6\xf6\xaa\xa4\x88\x02E\x05D\x84\x01\x10\xafm\xda\x95k_\xaa\xa8\xaa\xfa\xdbm\xad\xd5r \x08\x10P\x90\x00\x08\x05U\xaa\xb5j\xaa\xafE_UWm\xb6\xdbv\xa9\x02@\x85\nB \x80\x91Z\xb5Z\xaa\xaa\xaf\xbf\xfb\xabm\xdbmn\xda\xed@\x02 D(\x82\x04\n\xabUUUU_\xfa\xaa\n\xbb}\xb7\xb7\xabZ\x10\x88\x14\x91\x00\x00\x10\xadU\xb5V\xaaUO\x8a\x91U\xaf\xb6\xda\xda\xf5u\x82\x00\x80\x00\xa4 \x02\xaa\xae\xd5)QJ_d\xae\xfe\xda\xefmo\xaa\xd4@\x10*J\x11\x02%USZ\x95U)O[\xff\xa9W\xbd\xdb\xb5\xb5kPB\x80\x10\x80\x08\x05\xaa\xb5UUT\x95/\xfe\xa9P:\xf7\xed[j\xbd\x02\x00"\xa5H@\x15mUV\xa2\x95H\xaf\x12\xaa\xaa\x8d\xfe\xf6\xed\xd5\xd5h \x80D\x01\x00\x8a\xaa\xaa\xa9Y$\xa5\x1fJ\xaa\xad\xf6\xaf\xbbV\xd5j\x80\x82\x12\x92\xa0\x12\x05\xa5RUT\x92\x92O\xb4\xab\xff\xfd\xbb\xec\x8bj\xaa\xa8\x00A*\x04@\x15T\x95UBI)_\xd7\xff\x7f\xff\xd6\xbaU\xb5jP\x08\x04\x85P\x00B\xaaH\x92Y$\x94\x8f\xfb\xff\xfb\xff\x7f\xfa\x92\xd4\xb5\x04 \x11i\x01\x12\tQRI$\x92B_\xee\xff\xff\xfa\xd5\xa4Kj\xaa\xa0\x81\x01*\x90@"\xadIT\x92I)/\xbb\xbf\xff\xff}h\x01\xb5TH\x00\x05\xaa"\x01\x00\x90\x92\x02I$\x94\x8f\xff\xff\xff\xfd\xfe\xa1\x15Uj\x80\x08@\xaa\x80\x10\nE$\xa9$\x92B_\xff\x7f\xff\xef\xffTE\xea\xaa\x12!\x0bR)\x02A\x10\x00\x14\x92I)/\xdf\xef\xff\xff\xff\xaa\xb6\xb5U@\x04\x02\xaa\x80@\x04\x00\x81\x01)$D\x8f\xff\xbf\xff\xff\xff\xeb[T\xa9\x00\x10E$H\x08 \x00\x08PD\x89*_\xbf\xf7\xff\xff\xff\xfd\xed\xda\xb4\x92D\x95R\x82\x01\x00\x84\x00\x02\x12UU\xaf\xfe\xfd\xef\xff\xff\xea\x92mU\x00\t\x06\x89 @\x12\x00 \x00\x05UU_')

IMG_1028_bw.py

width = 184
height = 135
img_bw = bytearray(b'\x01\x82{\xf1\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\xc0\x02\x08\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00`\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00 \x08\x06\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xfe?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\xcf\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\x9f\xff\xff\xff\xff\xff\xff\xff\xff\x80\x08\x00O\x01\xff\xf3\xff\xff\xff\xff\xff\xff\xff\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x04\x00?\x81\xe7\x81\xff\xff\xff\xff\xff\xff\xff\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x02\x00\x01\x80\xe3\xc3\xef\xff\xff\xff\xff\xff\xff\x9f\xff\xff\xff\xff\xff\xff\xff\xff`\x00\x00\x00\xc0q\xe3\xf0\xff\xff\xff\xff\xff\xff\x9f\xff\xff\xff\xff\xff\xff\xff\xff0\x00\x00\x00\xc00\xff\xfc\x7f\xff\xff\xff\xff\xff\x1f\xff\xff\xff\xff\xff\xff\xff\xff0\x00\x00\x07@\x00\x7f\xfe\x0f\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\x18\x00\x00\x06 \x00\x7f\xff\x03\xff\xff\xff\xff\xff\x8f\xff\xff\xff\xff\xff\xff\xff\xff\x0c\x00\x00\x000\x00?\xff\x80\x7f\xff\xff\xff\xff\x87\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x00\x000\x00\x07\xff\xc0\x07\xff\xff\xff\xff\xa7\xff\xff\xff\xff\xff\xff\xff\xff\x06\x00\x00\x00\x00\x00\x07\xff\xe0\x00\xff\xff\xf7\xff\xa7\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\x10\x00\x08\x00\x0f\xff\xf1\xf8\x7f\xff\xf7\xff7\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x04\x00\x1f\xff\xfd\xfc\x1f\xff\xe7\xff7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00@\x00\x7f\xff\xfe\xff\x0f\xff\xe7\xfe7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00@\x00\xff\xff\xff\xff\x8f\xff\xc3\xfe?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x01\xff\xff\xff\xff\xff\xdf\xc1\xfc?\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x00\x07\xff\xff\xff\xef\xff\xff\x80\xd0?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x0f\xff\xff\xff\xe7\xff\xfe@`\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xc7\xff\xff\xc0`\xf7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x80\x00\x00\x00?\xff\xff\xff\xc7\xff\xff\xfc@w\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xe7\xff\xff\xfc\x00\'\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe7\xff\xffL\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x01\xff\xff\xff\xff\xc7\xff\xc8\x0f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x03\xff\xff\xff\xff\xc3\xff\xc0\x13\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x0f\xff\xff\xff\xff\xf7\xff\xc0"`\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xff\xff\xff\xff\x80,\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00{\xff\xff\xff\xff\xff\xff\xc0\x08\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xc0P\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xc0p\x00\x0f\xff\xff\xf7\xff\xff\xff\xff\xff\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xc0n\x00\x0f\xff\xff\xfb\xff\xff\xff\xff\xff\x00\x00\x00\x03\xff\xff\xff\xfe\xff\xff\xff\xe2|\x00\x0f\xff\xff\xf8\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xfe\x7f\xff\xff\xe6\x7f\x00\x0f\xff\xff\xfd\xff\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xef\x7f\xff\xff\xf6\x7f\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xc7?\xff\xff\xf0?\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x7f\xff\xff\xc0?\xff\xf7\xf0\x1f\x80\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x03\xff\xff\xc0?\xff\xf7\xb0\x07\xc0?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x01\x07\xff\xff\xe0?\xff\xffp\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x01?\xff\xff\xe0?\xff\xff\xf0\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xdf\xf2\xff\xff\xff\xe0\x0e\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xe3\xef\xc7\xff\xff\xff\xff\xe0\x07\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xc7\xff\xe7\xff\xff\xff\xff\xc0g\x00?\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x03\xc0\xc4\xef\xfb\xff\xff\xff\xff\xc0g\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x07\xf0\xff\xff\xff\xff\xff\xfb\xff\xe0?\x80\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x7f\xf3\xff\xff\xff\xff\xff\xff\xff\xe0?\x80\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xf7\xe7\xff\xff\xff\xff\xff\xff\xff\xc0\x02\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xe7\xef\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xe3\xef\xff\xff\xff\xff\xfe\xff\xff\xe0\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xcf\xff\xff\xff\xff\xfe\x00\xff\xe0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xc3\xff\xff\xff\xff\xff\x00\xff\xc0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xff\xf9\xff\xff\xff\xff\xff\xc0\x7f\xe0\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xff\xff\xef\xff\xff\xff\xff\xe0\x1f\xe0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00?\xdf\xe0\x0f\xff\xff\xff\xff\xfc\x1f\xe0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00?\x00\x00?\xff\xff\xff\xff\xfe\x7f\xe0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xff\xff\xff\xff\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\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x01\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x81\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe3\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe6\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffd\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00\x00\x07\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\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x8e\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe?\x80\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x7f\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\xff\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xbf\xff\xc3\xff\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdf\xff\xd1\xfe\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x7f\x80\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xef\x1f\x00\x00\x00\x1f\xff\xff\xff\xff\xfb\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd3\xff\xff\x8e@\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe7\xff\xff\xc0\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff7\xff\x9f\xf0\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x17\xfe\x07\xf8\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffE\xfc\x04\xfe\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff,=\x00\xff\xc0\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x08?\x80\x7f\xc0\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00?\x81\xbf\x80\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\xbf\x83\x9f\x80\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x1f\x00\xcf\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x08\x00o\x80\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x00?\x80\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x1f\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00o\x00\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x7f\x80\x00\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00 \x00?\xc0\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00/\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x1f\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x000\x1e\x80\x00\x00\x07\xff\xff\xff\xff\xff\xff\xcf\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x00\x1f?\xe0\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xf3\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x00\x1f\xff\xa0\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xf1\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x00\x1f\xcf\x80\x00\x00\x0f\xff?\xff\xff\xff\xff\xff\x7f\xff\xff\xff\xff\xff\xff\xff\x00\x00\x0f\xe4\x00\x00\x00\x1f\xf4\x1f\xff\xff\xff\xff\xff?\xff\xff\xff\xff\xff\xff\xff\x02\x00\x0f\xfe\x00\x00\x00\x1f\x00\x0f\xff\xff\xff\xff\xff\xdf\xff\xff\xff\xff\xff\xff\xfe\x02\x00\x0f\xbf\x80\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xff\xff\xfe\x02\x00\x1f\x82\xc0\x00\x00\x00?\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff\xff\xff\xff\xfc\x00\x00\x0f\x1f\xe0\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xfd\xff\xff\xff\xff\xff\xff\xff\x00\x00\x1e?\xf0\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00 _\xf0\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x00\xcfx\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\x8f\xff\xff\xff\xff\xff\xff\xc0\x00 \x80\x18\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00 \x00`\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x000\x040\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x00 \x7f\xc0\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xe0\x00\xa1\xff\xc0\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xbf\xff\xff\xff\xff\xff\xf8\x00\x81\xff\xc0\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00A\xff\xc0\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x01\xff\x80\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x03\xff\xc0\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x03\xff\xc0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x01\xff\xc0\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x07\xff\xff\xd0\x00\x01\xff\xa0\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x07\xff\xff\xc0\x00\x03\xff\xc0\x00\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x7f\xff\xff\xc0\x00\x03\xff\xe0\x00\x03\xc0\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x07\xff\xa0\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x08\x07\xff\xe0\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x1c\x0f\xff\xc0\x00\x00\x00\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x0f\xef\xff\xc0\x00\x00\x00\x00\x00\x0f\xff\xff\xff')

I got to move all of the files in the same directory and modify the import statements, as importing from files that aren't initiated as packages didn't work.

I got the code from this repo.

7.5" Pico Display

After wiring the display according to this picture, I ran the following code from this repo found from this tutorial in Thonny, and it worked!

7in5_test_2.py

from machine import Pin, SPI
import framebuf
import utime

# Display resolution
EPD_WIDTH       = 800
EPD_HEIGHT      = 480

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13

class EPD_7in5(framebuf.FrameBuffer):
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)

        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT

        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)

        self.buffer = bytearray(self.height * self.width // 8)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50) 
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)   

    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)

    def send_data1(self, buf):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi.write(bytearray(buf))
        self.digital_write(self.cs_pin, 1)

    def WaitUntilIdle(self):
        print("e-Paper busy")
        while(self.digital_read(self.busy_pin) == 0):    # Wait until the busy_pin goes LOW
            self.send_command(0x71)
            self.delay_ms(20)
        self.delay_ms(20) 
        print("e-Paper busy release")  

    def TurnOnDisplay(self):
        self.send_command(0x12) # DISPLAY REFRESH
        self.delay_ms(100)      #!!!The delay here is necessary, 200uS at least!!!
        self.WaitUntilIdle()

    def init(self):
        # EPD hardware init start     
        self.reset()

        self.send_command(0x01)  # POWER SETTING
        self.send_data(0x07)
        self.send_data(0x07)     # VGH=20V,VGL=-20V
        self.send_data(0x3f)     # VDH=15V
        self.send_data(0x3f)     # VDL=-15V

        self.send_command(0x04)  # POWER ON
        self.delay_ms(100)
        self.WaitUntilIdle()

        self.send_command(0X00)   # PANNEL SETTING
        self.send_data(0x1F)      # KW-3f   KWR-2F  BWROTP 0f   BWOTP 1f

        self.send_command(0x61)     # tres
        self.send_data(0x03)     # source 800
        self.send_data(0x20)
        self.send_data(0x01)     # gate 480
        self.send_data(0xE0)

        self.send_command(0X15)
        self.send_data(0x00)

        self.send_command(0X50)     # VCOM AND DATA INTERVAL SETTING
        self.send_data(0x10)
        self.send_data(0x00)

        self.send_command(0X60)     # TCON SETTING
        self.send_data(0x22)

        self.send_command(0x65)     # Resolution setting
        self.send_data(0x00)
        self.send_data(0x00)     # 800*480
        self.send_data(0x00)
        self.send_data(0x00)

        return 0;

    def Clear(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.TurnOnDisplay()

    def ClearBlack(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.TurnOnDisplay()

    def display(self,blackimage):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.TurnOnDisplay()


    def sleep(self):
        self.send_command(0x02) # power off
        self.WaitUntilIdle()
        self.send_command(0x07) # deep sleep
        self.send_data(0xa5)

if __name__=='__main__':
    epd = EPD_7in5()
    epd.Clear()

    epd.fill(0x00)

    epd.text("Waveshare", 5, 10, 0xff)
    epd.text("Pico_ePaper-7.5", 5, 40, 0xff)
    epd.text("Raspberry Pico", 5, 70, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.vline(10, 90, 60, 0xff)
    epd.vline(120, 90, 60, 0xff)
    epd.hline(10, 90, 110, 0xff)
    epd.hline(10, 150, 110, 0xff)
    epd.line(10, 90, 120, 150, 0xff)
    epd.line(120, 90, 10, 150, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.rect(10, 180, 50, 80, 0xff)
    epd.fill_rect(70, 180, 50, 80, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.fill_rect(250, 150, 480, 20, 0xff)
    epd.fill_rect(250, 310, 480, 20, 0xff)
    epd.fill_rect(400, 0, 20, 480, 0xff)
    epd.fill_rect(560, 0, 20, 480, 0xff)

    for j in range(0, 3):
        for i in range(0, 15):
            epd.line(270+j*160+i, 20+j*160, 375+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(375+j*160+i, 20+j*160, 270+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 20+j*160+i, 390+j*160, 125+j*160+i, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 125+j*160+i, 390+j*160, 20+j*160+i, 0xff)        
    epd.fill_rect(270, 190, 100, 100, 0xff)
    epd.fill_rect(270, 350, 100, 100, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.Clear()
    epd.delay_ms(2000)
    print("sleep")
    epd.sleep()

Unfortunately, the text was very small, and I tried to change its size via this forum, but it didn't work, also revealing that larger font sizes may take up too much memory. I tried changing self.width = EPD_WIDTH and self.height = EPD_HEIGHT to self.width = int(EPD_WIDTH/2) and self.height = int(EPD_HEIGHT/2) but the result was grainy and has text smaller than what it was before. I also tried multiplying by too, but I recieved an error about allocating too much memory.

I original decided to try to write my own font library by drawing lines and coordinates (and trying to find people who've done similar things with Desmos) but realized this approach is not time efficient. Here was what I had gotten before I quit.

from machine import Pin, SPI
import framebuf
import utime

# Display resolution
EPD_WIDTH       = 800
EPD_HEIGHT      = 480

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13

class EPD_7in5(framebuf.FrameBuffer):
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)

        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH 
        self.height = EPD_HEIGHT 

        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)

        self.buffer = bytearray(self.height * self.width // 8)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50) 
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)   

    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)

    def send_data1(self, buf):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi.write(bytearray(buf))
        self.digital_write(self.cs_pin, 1)

    def WaitUntilIdle(self):
        print("e-Paper busy")
        while(self.digital_read(self.busy_pin) == 0):    # Wait until the busy_pin goes LOW
            self.send_command(0x71)
            self.delay_ms(20)
        self.delay_ms(20) 
        print("e-Paper busy release")  

    def TurnOnDisplay(self):
        self.send_command(0x12) # DISPLAY REFRESH
        self.delay_ms(100)      #!!!The delay here is necessary, 200uS at least!!!
        self.WaitUntilIdle()

    def init(self):
        # EPD hardware init start     
        self.reset()

        self.send_command(0x01)  # POWER SETTING
        self.send_data(0x07)
        self.send_data(0x07)     # VGH=20V,VGL=-20V
        self.send_data(0x3f)     # VDH=15V
        self.send_data(0x3f)     # VDL=-15V

        self.send_command(0x04)  # POWER ON
        self.delay_ms(100)
        self.WaitUntilIdle()

        self.send_command(0X00)   # PANNEL SETTING
        self.send_data(0x1F)      # KW-3f   KWR-2F  BWROTP 0f   BWOTP 1f

        self.send_command(0x61)     # tres
        self.send_data(0x03)     # source 800
        self.send_data(0x20)
        self.send_data(0x01)     # gate 480
        self.send_data(0xE0)

        self.send_command(0X15)
        self.send_data(0x00)

        self.send_command(0X50)     # VCOM AND DATA INTERVAL SETTING
        self.send_data(0x10)
        self.send_data(0x00)

        self.send_command(0X60)     # TCON SETTING
        self.send_data(0x22)

        self.send_command(0x65)     # Resolution setting
        self.send_data(0x00)
        self.send_data(0x00)     # 800*480
        self.send_data(0x00)
        self.send_data(0x00)

        return 0;

    def Clear(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.TurnOnDisplay()

    def ClearBlack(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.TurnOnDisplay()

    def display(self,blackimage):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.TurnOnDisplay()


    def sleep(self):
        self.send_command(0x02) # power off
        self.WaitUntilIdle()
        self.send_command(0x07) # deep sleep
        self.send_data(0xa5)

def poly(epd, points):
    coordinates = [[]]
    for point in points:
        if len(coordinates[-1]) == 4:
            coordinates.append([])
            coordinates[-1] += [coordinates[-2][2], coordinates[-2][3]]
        coordinates[-1].append(point[0])
        coordinates[-1].append(point[1])
    print(coordinates)
    for c in coordinates:
        epd.line(c[0], c[1], c[2], c[3], 0xff)
    epd.line(coordinates[-1][2], coordinates[-1][3], coordinates[0][0], coordinates[0][1], 0xff)

if __name__=='__main__':
    epd = EPD_7in5()
    epd.Clear()

    epd.fill(0x00)

    poly(epd, [(0, 100), (100, 0), (90, 0)])
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """
    epd.text("Waveshare", 5, 10, 0xff)
    epd.text("Pico_ePaper-7.5", 5, 40, 0xff)
    epd.text("Raspberry Pico", 5, 70, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.vline(10, 90, 60, 0xff)
    epd.vline(120, 90, 60, 0xff)
    epd.hline(10, 90, 110, 0xff)
    epd.hline(10, 150, 110, 0xff)
    epd.line(10, 90, 120, 150, 0xff)
    epd.line(120, 90, 10, 150, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.rect(10, 180, 50, 80, 0xff)
    epd.fill_rect(70, 180, 50, 80, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.fill_rect(250, 150, 480, 20, 0xff)
    epd.fill_rect(250, 310, 480, 20, 0xff)
    epd.fill_rect(400, 0, 20, 480, 0xff)
    epd.fill_rect(560, 0, 20, 480, 0xff)

    for j in range(0, 3):
        for i in range(0, 15):
            epd.line(270+j*160+i, 20+j*160, 375+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(375+j*160+i, 20+j*160, 270+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 20+j*160+i, 390+j*160, 125+j*160+i, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 125+j*160+i, 390+j*160, 20+j*160+i, 0xff)        
    epd.fill_rect(270, 190, 100, 100, 0xff)
    epd.fill_rect(270, 350, 100, 100, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """

    epd.Clear()
    epd.delay_ms(2000)
    print("sleep")
    epd.sleep()

I tried original to use the epd.poly function based off of [this documentation](https://docs.micropython.org/en/latest/library/framebuf.html#:~:text=Given%20a%20list,outline%20is%20drawn, since EPD_7in5 inherents from framebuf.FrameBuffer, but I kept getting this error when using an array of points.

TypeError: object with buffer protocol required

Instead I found this example code%0Aoled.show()) and adapted it to the following, which worked!

from machine import Pin, SPI
import framebuf
import utime

# Display resolution
EPD_WIDTH       = 800
EPD_HEIGHT      = 480

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13

class EPD_7in5(framebuf.FrameBuffer):
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)

        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH 
        self.height = EPD_HEIGHT 

        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)

        self.buffer = bytearray(self.height * self.width // 8)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50) 
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)   

    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)

    def send_data1(self, buf):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi.write(bytearray(buf))
        self.digital_write(self.cs_pin, 1)

    def WaitUntilIdle(self):
        print("e-Paper busy")
        while(self.digital_read(self.busy_pin) == 0):    # Wait until the busy_pin goes LOW
            self.send_command(0x71)
            self.delay_ms(20)
        self.delay_ms(20) 
        print("e-Paper busy release")  

    def TurnOnDisplay(self):
        self.send_command(0x12) # DISPLAY REFRESH
        self.delay_ms(100)      #!!!The delay here is necessary, 200uS at least!!!
        self.WaitUntilIdle()

    def init(self):
        # EPD hardware init start     
        self.reset()

        self.send_command(0x01)  # POWER SETTING
        self.send_data(0x07)
        self.send_data(0x07)     # VGH=20V,VGL=-20V
        self.send_data(0x3f)     # VDH=15V
        self.send_data(0x3f)     # VDL=-15V

        self.send_command(0x04)  # POWER ON
        self.delay_ms(100)
        self.WaitUntilIdle()

        self.send_command(0X00)   # PANNEL SETTING
        self.send_data(0x1F)      # KW-3f   KWR-2F  BWROTP 0f   BWOTP 1f

        self.send_command(0x61)     # tres
        self.send_data(0x03)     # source 800
        self.send_data(0x20)
        self.send_data(0x01)     # gate 480
        self.send_data(0xE0)

        self.send_command(0X15)
        self.send_data(0x00)

        self.send_command(0X50)     # VCOM AND DATA INTERVAL SETTING
        self.send_data(0x10)
        self.send_data(0x00)

        self.send_command(0X60)     # TCON SETTING
        self.send_data(0x22)

        self.send_command(0x65)     # Resolution setting
        self.send_data(0x00)
        self.send_data(0x00)     # 800*480
        self.send_data(0x00)
        self.send_data(0x00)

        return 0;

    def Clear(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.TurnOnDisplay()

    def ClearBlack(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.TurnOnDisplay()

    def display(self,blackimage):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.TurnOnDisplay()


    def sleep(self):
        self.send_command(0x02) # power off
        self.WaitUntilIdle()
        self.send_command(0x07) # deep sleep
        self.send_data(0xa5)
"""
def poly(epd, points):
    coordinates = [[]]
    for point in points:
        if len(coordinates[-1]) == 4:
            coordinates.append([])
            coordinates[-1] += [coordinates[-2][2], coordinates[-2][3]]
        coordinates[-1].append(point[0])
        coordinates[-1].append(point[1])
    print(coordinates)
    for c in coordinates:
        epd.line(c[0], c[1], c[2], c[3], 0xff)
    epd.line(coordinates[-1][2], coordinates[-1][3], coordinates[0][0], coordinates[0][1], 0xff)
"""
fb_smile1 = framebuf.FrameBuffer(bytearray(b'\x00~\x00\x03\xff\xc0\x07\x81\xe0\x1e\x00x8\x00\x1c0\x00\x0c`\x00\x0ea\xc3\x86\xe0\x00\x07\xc0\x00\x03\xc0\x00\x03\xc0\x00\x02\xc0\x00\x03\xc0\x00\x03\xe0B\x07`<\x06`\x00\x060\x00\x0c8\x00\x1c\x1e\x00x\x07\x81\xe0\x03\xff\xc0\x00\xff\x00'), 24, 23, framebuf.MONO_HLSB)

if __name__=='__main__':
    epd = EPD_7in5()
    epd.Clear()

    epd.fill(0x00)

    epd.blit(fb_smile1, 100, 100)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """
    epd.text("Waveshare", 5, 10, 0xff)
    epd.text("Pico_ePaper-7.5", 5, 40, 0xff)
    epd.text("Raspberry Pico", 5, 70, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.vline(10, 90, 60, 0xff)
    epd.vline(120, 90, 60, 0xff)
    epd.hline(10, 90, 110, 0xff)
    epd.hline(10, 150, 110, 0xff)
    epd.line(10, 90, 120, 150, 0xff)
    epd.line(120, 90, 10, 150, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.rect(10, 180, 50, 80, 0xff)
    epd.fill_rect(70, 180, 50, 80, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.fill_rect(250, 150, 480, 20, 0xff)
    epd.fill_rect(250, 310, 480, 20, 0xff)
    epd.fill_rect(400, 0, 20, 480, 0xff)
    epd.fill_rect(560, 0, 20, 480, 0xff)

    for j in range(0, 3):
        for i in range(0, 15):
            epd.line(270+j*160+i, 20+j*160, 375+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(375+j*160+i, 20+j*160, 270+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 20+j*160+i, 390+j*160, 125+j*160+i, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 125+j*160+i, 390+j*160, 20+j*160+i, 0xff)        
    epd.fill_rect(270, 190, 100, 100, 0xff)
    epd.fill_rect(270, 350, 100, 100, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """

    epd.Clear()
    epd.delay_ms(2000)
    print("sleep")
    epd.sleep()

Now I just had to make my display image and convert it into a byte array. In the future I'll consider trying to get the text to write bigger so that I can change the text in real time from the app without generating a new byte array (which is also a possibility), but for now I'll leave it at this.

I used this website to create a byte array of this image.

But it was far too large and I got a memory allocation error (Thonny was very slow saving the program). I also noticed it had commas instead of slashes. I tried running this python code on my computer so I could decompress it on the RP2040, but this also failed as I crashed Thonny when copying the output from the terminal..

str_ = """THE BYTE ARRAY"""


items = []
for item_ in str_.split(","):
    item = item_.strip()
    if items and item == items[-1][0]:
        items[-1][1] += 1
    else:
        items.append([item, 1])
print(items)

I re-ran the byte array creation instead at a resolution of 100x100 but got a weird dot pattern when I run the program.

weird dot patter

I tried converting it with this, but it also failed.

str_ = """*the byte list*"""

print(str_.replace(" ","").replace(",", "").replace("0x", "\\x").replace("\n","").replace("\t",""))

Next I tried using this website to download a BMP file. I uploaded it to the Pico and changed the python to this, which gave a different, weird dot pattern.

with open('medical-symbol.bmp', 'rb') as f:
    fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()), 24, 23, framebuf.MONO_HLSB)

I tried every single one of the formats here and changed the dimensions to 100, 100, but nothing worked.

Finally, this forum, which I had used earlier, revealed that the MONO_HLSB is the same as a PBM file, so I used this website to convert my BMP to PBM and uploaded to the Pico. This time the result was much closer to what I wanted.

with open('medical-symbol.pbm', 'rb') as f:
    fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()), 100, 100, framebuf.MONO_HLSB)

The graininess was strange as the BMP file was not grainy whatsoever.

I tried using this python program to convert the BMP file instead, since maybe it was a problem with the converting website, but this created no change.

I tried using the original JPG size of 580x531 and still had the same problem. I even used this website to verify it wasn' a problem with the PBM file.

I decided to print out the bytes with print(f.read()) and the first 12 characters were P4\n580 531. I decided to try to cut these off by changing fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()), 100, 100, framebuf.MONO_HLSB) to fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()[12:]), 100, 100, framebuf.MONO_HLSB), and this worked! (I also had to restart Thonny and reinstall MicroPython everytime I printed out the bytes then tried to stop the program when it would get stuck). When I printed out f.read()[:13] there were two more characters than what I intended to cut off - I'm not sure what these were, but the program works so I'll leave it for now.

from machine import Pin, SPI
import framebuf
import utime

# Display resolution
EPD_WIDTH       = 800
EPD_HEIGHT      = 480

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13

class EPD_7in5(framebuf.FrameBuffer):
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)

        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH 
        self.height = EPD_HEIGHT 

        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)

        self.buffer = bytearray(self.height * self.width // 8)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50) 
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)   

    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)

    def send_data1(self, buf):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi.write(bytearray(buf))
        self.digital_write(self.cs_pin, 1)

    def WaitUntilIdle(self):
        print("e-Paper busy")
        while(self.digital_read(self.busy_pin) == 0):    # Wait until the busy_pin goes LOW
            self.send_command(0x71)
            self.delay_ms(20)
        self.delay_ms(20) 
        print("e-Paper busy release")  

    def TurnOnDisplay(self):
        self.send_command(0x12) # DISPLAY REFRESH
        self.delay_ms(100)      #!!!The delay here is necessary, 200uS at least!!!
        self.WaitUntilIdle()

    def init(self):
        # EPD hardware init start     
        self.reset()

        self.send_command(0x01)  # POWER SETTING
        self.send_data(0x07)
        self.send_data(0x07)     # VGH=20V,VGL=-20V
        self.send_data(0x3f)     # VDH=15V
        self.send_data(0x3f)     # VDL=-15V

        self.send_command(0x04)  # POWER ON
        self.delay_ms(100)
        self.WaitUntilIdle()

        self.send_command(0X00)   # PANNEL SETTING
        self.send_data(0x1F)      # KW-3f   KWR-2F  BWROTP 0f   BWOTP 1f

        self.send_command(0x61)     # tres
        self.send_data(0x03)     # source 800
        self.send_data(0x20)
        self.send_data(0x01)     # gate 480
        self.send_data(0xE0)

        self.send_command(0X15)
        self.send_data(0x00)

        self.send_command(0X50)     # VCOM AND DATA INTERVAL SETTING
        self.send_data(0x10)
        self.send_data(0x00)

        self.send_command(0X60)     # TCON SETTING
        self.send_data(0x22)

        self.send_command(0x65)     # Resolution setting
        self.send_data(0x00)
        self.send_data(0x00)     # 800*480
        self.send_data(0x00)
        self.send_data(0x00)

        return 0;

    def Clear(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.TurnOnDisplay()

    def ClearBlack(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.TurnOnDisplay()

    def display(self,blackimage):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.TurnOnDisplay()


    def sleep(self):
        self.send_command(0x02) # power off
        self.WaitUntilIdle()
        self.send_command(0x07) # deep sleep
        self.send_data(0xa5)
"""
def poly(epd, points):
    coordinates = [[]]
    for point in points:
        if len(coordinates[-1]) == 4:
            coordinates.append([])
            coordinates[-1] += [coordinates[-2][2], coordinates[-2][3]]
        coordinates[-1].append(point[0])
        coordinates[-1].append(point[1])
    print(coordinates)
    for c in coordinates:
        epd.line(c[0], c[1], c[2], c[3], 0xff)
    epd.line(coordinates[-1][2], coordinates[-1][3], coordinates[0][0], coordinates[0][1], 0xff)
"""
with open('medical-symbol-o-o.pbm', 'rb') as f:
    fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()[12:]), 580, 531, framebuf.MONO_HLSB)

if __name__=='__main__':
    epd = EPD_7in5()
    epd.Clear()

    epd.fill(0x00)

    epd.blit(fb_smile1, 0, -10)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """
    epd.text("Waveshare", 5, 10, 0xff)
    epd.text("Pico_ePaper-7.5", 5, 40, 0xff)
    epd.text("Raspberry Pico", 5, 70, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.vline(10, 90, 60, 0xff)
    epd.vline(120, 90, 60, 0xff)
    epd.hline(10, 90, 110, 0xff)
    epd.hline(10, 150, 110, 0xff)
    epd.line(10, 90, 120, 150, 0xff)
    epd.line(120, 90, 10, 150, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.rect(10, 180, 50, 80, 0xff)
    epd.fill_rect(70, 180, 50, 80, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    epd.fill_rect(250, 150, 480, 20, 0xff)
    epd.fill_rect(250, 310, 480, 20, 0xff)
    epd.fill_rect(400, 0, 20, 480, 0xff)
    epd.fill_rect(560, 0, 20, 480, 0xff)

    for j in range(0, 3):
        for i in range(0, 15):
            epd.line(270+j*160+i, 20+j*160, 375+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(375+j*160+i, 20+j*160, 270+j*160+i, 140+j*160, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 20+j*160+i, 390+j*160, 125+j*160+i, 0xff)
        for i in range(0, 15):
            epd.line(270+j*160, 125+j*160+i, 390+j*160, 20+j*160+i, 0xff)        
    epd.fill_rect(270, 190, 100, 100, 0xff)
    epd.fill_rect(270, 350, 100, 100, 0xff)
    epd.display(epd.buffer)
    epd.delay_ms(5000)

    """

    epd.Clear()
    epd.delay_ms(2000)
    print("sleep")
    epd.sleep()

Final Image

I created a new project in Adobe Premiere Pro and made a new, white Color Matte that is 800x480 pixels per this website to match the epaper display. After creating a frame with the desired image, I clicked the camera icon in the preview window and exported the frame as a BMP. I just ignored the .bmp.xmp file as I'm not sure of its purpose. I then converted it to a PBM file with the same website as above.

It worked perfectly!! I also removed the code that clears the screen at the end of the program.

from machine import Pin, SPI
import framebuf
import utime

# Display resolution
EPD_WIDTH       = 800
EPD_HEIGHT      = 480

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13

class EPD_7in5(framebuf.FrameBuffer):
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)

        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH 
        self.height = EPD_HEIGHT 

        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)

        self.buffer = bytearray(self.height * self.width // 8)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50) 
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)   

    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)

    def send_data1(self, buf):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi.write(bytearray(buf))
        self.digital_write(self.cs_pin, 1)

    def WaitUntilIdle(self):
        print("e-Paper busy")
        while(self.digital_read(self.busy_pin) == 0):    # Wait until the busy_pin goes LOW
            self.send_command(0x71)
            self.delay_ms(20)
        self.delay_ms(20) 
        print("e-Paper busy release")  

    def TurnOnDisplay(self):
        self.send_command(0x12) # DISPLAY REFRESH
        self.delay_ms(100)      #!!!The delay here is necessary, 200uS at least!!!
        self.WaitUntilIdle()

    def init(self):
        # EPD hardware init start     
        self.reset()

        self.send_command(0x01)  # POWER SETTING
        self.send_data(0x07)
        self.send_data(0x07)     # VGH=20V,VGL=-20V
        self.send_data(0x3f)     # VDH=15V
        self.send_data(0x3f)     # VDL=-15V

        self.send_command(0x04)  # POWER ON
        self.delay_ms(100)
        self.WaitUntilIdle()

        self.send_command(0X00)   # PANNEL SETTING
        self.send_data(0x1F)      # KW-3f   KWR-2F  BWROTP 0f   BWOTP 1f

        self.send_command(0x61)     # tres
        self.send_data(0x03)     # source 800
        self.send_data(0x20)
        self.send_data(0x01)     # gate 480
        self.send_data(0xE0)

        self.send_command(0X15)
        self.send_data(0x00)

        self.send_command(0X50)     # VCOM AND DATA INTERVAL SETTING
        self.send_data(0x10)
        self.send_data(0x00)

        self.send_command(0X60)     # TCON SETTING
        self.send_data(0x22)

        self.send_command(0x65)     # Resolution setting
        self.send_data(0x00)
        self.send_data(0x00)     # 800*480
        self.send_data(0x00)
        self.send_data(0x00)

        return 0;

    def Clear(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.TurnOnDisplay()

    def ClearBlack(self):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10)
        for i in range(0, wide):
            self.send_data1([0x00] * high)

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1([0xff] * high)

        self.TurnOnDisplay()

    def display(self,blackimage):

        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1

        self.send_command(0x10) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.send_command(0x13) 
        for i in range(0, wide):
            self.send_data1(blackimage[(i * high) : ((i+1) * high)])

        self.TurnOnDisplay()


    def sleep(self):
        self.send_command(0x02) # power off
        self.WaitUntilIdle()
        self.send_command(0x07) # deep sleep
        self.send_data(0xa5)

with open('TS_FINAL_IMG.pbm', 'rb') as f:
    fb_smile1 = framebuf.FrameBuffer(bytearray(f.read()[12:]), EPD_WIDTH, EPD_HEIGHT, framebuf.MONO_HLSB)

if __name__=='__main__':
    epd = EPD_7in5()
    epd.Clear()

    epd.fill(0x00)

    epd.blit(fb_smile1, 0, 0)
    epd.display(epd.buffer)

    print("sleep")
    epd.sleep()

I cleared the epaper before I finished working on it, and I'm considering simply drawing it one time then not writing to it anymore and only using the Pico for controlling the servo and BLE communication. Also that was I didn't have to worry about using the shield with other wiring, as well, and a power source. But this also wouldn't be any better than a piece of paper, so I'm leaning against it.

All of the code used MicroPython 1.20.0

Rechargeable Batteries

I want to use a rechargeable battery both for the cup holder and display electronics. I have a HW-357 module and a Lipo battery, and when I measured the output voltage of the battery, it was 1.7V, so I let it charge inside of a Derblue Lipo Safe Bag.

The potentiometer didn't work - even after charging always ~1.7v - soldered a different one called a TP4056 Lithium Battery Charger Module.

When I hooked up the servo, it worked!

wiring pic

Here's where I put it together!

Sometimes the servo motor would become jitery, but I believe this was the result of a bad connection in the wiring, as after combining the electronics this problem disappeared.

Combining With HAT

I put it in the e-paper HAT, and I couldn't connect to it in Thonny. I realized I placed it one too many over to the side, and after changing that, it worked!

This page leads me to believe that the e-paper uses SPI, so GP21 and UART 0 shouldn't be a problem!

I found switching between the angles 0 and 100 was optimal.

Now it was time to design the PCB board.

Display Electronics PCB

Designing in EagleCAD

Iteration 1

Note I used right-click > Mirror to mirror the pico footprints since I inserted the board from the back using through-hole milling.

I used these two different footprints for pads:

  • wirepad > SMD5
  • wirepad > SMD2

Schematic Draft

Layout Draft

3D PCB Draft

This didn't work until I soldered the wire on it because I realized that the VSYS pin only works when the board is powered via USB.

Iteration 2

I redesigned the board to fix the VSYS problem. I played with milling different routing patterns, some of which failed to mill because of too-small trace widths (see below).

In terms of milling bits, I ended up using a 0.8mm flat end mill.

v2 Board Layout

VBUS didn't completely solve the problem.

I redid it. It stripped when I tried to unsolder a couple of times, so I had to re-mill the board. Then it worked!

Iteration 3

To modify the wiring, I had to add a 0ohm resistor to jump one trace over another. Now the design was fully functional!