Created
December 25, 2022 07:22
-
-
Save dnywh/7a56db9b077843e5926ff594c7ecd375 to your computer and use it in GitHub Desktop.
A random design based on Kōhei Sugiura's stamps for the 1972 Olympics, rendered on a Raspberry Pi Pico and Waveshare e-ink display
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # A random design based on Kōhei Sugiura's stamps for the 1972 Olympics | |
| # https://commons.wikimedia.org/wiki/File:Stamps_of_Germany_(BRD),_Olympiade_1972,_Blockausgabe_1971,_Markenblock.jpg | |
| from machine import Pin, SPI | |
| import framebuf | |
| import utime | |
| import random | |
| import math | |
| # Display resolution | |
| EPD_WIDTH = 648 | |
| EPD_HEIGHT = 480 | |
| RST_PIN = 12 | |
| DC_PIN = 8 | |
| CS_PIN = 9 | |
| BUSY_PIN = 13 | |
| # Waveshare driver | |
| # Forked from Waveshare's Pico ePaper-5.83py | |
| class EPD_5in83(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_data2(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 ReadBusy(self): | |
| print("e-Paper busy") | |
| while self.digital_read(self.busy_pin) == 0: # 1: idle, 0: busy | |
| self.delay_ms(10) | |
| print("e-Paper busy release") | |
| def TurnOnDisplay(self): | |
| self.send_command(0x12) | |
| self.delay_ms(100) | |
| self.ReadBusy() | |
| 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.ReadBusy() # waiting for the electronic paper IC to release the idle signal | |
| self.send_command(0x00) # PANEL SETTING | |
| self.send_data(0x1F) # KW-3f KWR-2F BWROTP 0f BWOTP 1f | |
| self.send_command(0x61) # tres | |
| self.send_data(0x02) # source 648 | |
| self.send_data(0x88) | |
| 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(0x07) | |
| self.send_command(0x60) # TCON SETTING | |
| self.send_data(0x22) | |
| # EPD hardware init end | |
| return 0 | |
| def display(self, image): | |
| if image == None: | |
| return | |
| self.send_command(0x13) # WRITE_RAM | |
| self.send_data2(image) | |
| self.TurnOnDisplay() | |
| def Clear(self, color): | |
| self.send_command(0x13) # WRITE_RAM | |
| for j in range(0, self.height): | |
| for i in range(0, int(self.width / 8)): | |
| self.send_data(color) | |
| self.TurnOnDisplay() | |
| def sleep(self): | |
| self.send_command(0x02) # DEEP_SLEEP_MODE | |
| self.ReadBusy() | |
| self.send_command(0x07) | |
| self.send_data(0xA5) | |
| self.delay_ms(2000) | |
| self.module_exit() | |
| # Circle function | |
| # By Tony Goodhew: | |
| # https://www.instructables.com/Computer-Graphics-101-With-Pi-Pico-and-Colour-Disp/ | |
| def circle(x, y, r, c): | |
| epd.hline(x - r, y, r * 2, c) | |
| for i in range(1, r): | |
| a = int(math.sqrt(r * r - i * i)) # Pythagoras! | |
| epd.hline(x - a, y + i, a * 2, c) # Lower half | |
| epd.hline(x - a, y - i, a * 2, c) # Upper half | |
| # Begin rendering | |
| if __name__ == '__main__': | |
| # Tell Python that I want to use the Waveshare ePaper thing as my screen | |
| epd = EPD_5in83() | |
| # Clear screen | |
| epd.Clear(0) | |
| # Set cols and rows (grid size) | |
| cols = 24 | |
| rows = 24 | |
| # Set up sizing | |
| cellSize = 16 | |
| # Size weighting | |
| # Increase frequency of a number to increase chance of rendering | |
| choices = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, | |
| 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16] | |
| # Center grid | |
| offsetX = int((EPD_WIDTH - (cols * cellSize)) / 2) | |
| offsetY = int((EPD_HEIGHT - (rows * cellSize)) / 2) | |
| # Prepare variables | |
| gridIndex = 0 | |
| valueX = 0 | |
| valueY = 0 | |
| # Traverse through rows top to bottom | |
| for kk in range(rows): | |
| # Traverse through cols left to right | |
| for jj in range(cols): | |
| # Calculate circle scale | |
| # Use a simple series of if statements to try to encourage small radius choice | |
| # Makeshift weighting in place of unavailable random.choices() | |
| radius = random.choice(choices) | |
| # Place circle in center of cell | |
| circle((valueX + offsetX), (valueY + offsetY), radius, 1) | |
| # Move to the next column in the row | |
| valueX += cellSize | |
| # Store what gridIndex we're up to | |
| gridIndex += 1 | |
| # Go to next row down | |
| valueY += cellSize | |
| # Go to first column on left | |
| valueX = 0 | |
| # Render all of the above to screen | |
| epd.display(epd.buffer) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment