diff --git a/init_sample.py b/init_sample.py index 62cde2a..f7a9a32 100644 --- a/init_sample.py +++ b/init_sample.py @@ -3,6 +3,7 @@ class PrintHWInfo: #Basic script to print module family, variant, and IP address from network import WLAN as wlan, STA_IF as staif from time import sleep_ms + #TODO support LCD and ePaper displays here if hw.features.display.oled: oled = hw.oled.handle oled.text("uPyConfig!",0,0) diff --git a/main.py b/main.py index a2f1e7e..0d9958c 100644 --- a/main.py +++ b/main.py @@ -38,3 +38,15 @@ sleep_ms(40) tft.fill(tft.PURPLE) sleep_ms(40) tft.fill(tft.WHITE) +sleep_ms(800) + +from fonts import terminal +from network import WLAN as wlan, STA_IF as staif + +print(hw.family) +print(hw.variant) +print(wlan(staif).ifconfig()[0]) + +tft.text((4,4),hw.family,terminal.data) +tft.text((4,14),hw.variant,terminal.data) +tft.text((4,24),wlan(staif).ifconfig()[0],terminal.data) \ No newline at end of file diff --git a/uPaper.py b/uPaper.py new file mode 100644 index 0000000..5addc02 --- /dev/null +++ b/uPaper.py @@ -0,0 +1,73 @@ +import framebuf + +class fbuf(framebuf.FrameBuffer): + filled=0 + clear=1 + def __init__(self, width, height): + self.width=width + self.height=height + self.buffer=bytearray(width*height//8) + super().__init__(self.buffer, width, height, framebuf.MONO_HLSB) + self.fill(self.clear) + +class epaper: + def __init__(self, width, height, refresh_delay=7800, pin_mosi=23, pin_miso=19, pin_sck=18, pin_cs=2, pin_dc=4, pin_rst=0, pin_busy=15, spi_device=2): + self.width=width + self.height=height + self.refresh_delay=refresh_delay + self.black=fbuf(width, height) + self.red=fbuf(width, height) + from epaper1in54b import EPD + from machine import Pin, SPI + self.mosi=Pin(pin_mosi) + self.miso=Pin(pin_miso) + self.sck=Pin(pin_sck) + self.cs=Pin(pin_cs) + self.dc=Pin(pin_dc) + self.rst=Pin(pin_rst) + self.busy=Pin(pin_rst) + self.spi=SPI(spi_device,baudrate=200000,polarity=0,phase=0,mosi=self.mosi,miso=self.miso,sck=self.sck) + self.epd=EPD(self.spi,cs=self.cs,dc=self.dc,rst=self.rst,busy=self.busy) + #only needs to be run once upon startup, unless the display is placed into low-power mode + #using epd.sleep(), then you need to run either epd.init() or epd.reset() + self.epd.init() + + def show(self): + #reset() appears not to put the display into a state where it will accept new input + self.epd.init() + self.epd.display_frame(self.black.buffer, self.red.buffer) + #display_frame returns as soon as data is sent to the display and the refresh has been initiated + #so if we immediately sleep(), the display is never refreshed + #thus we wait 7 seconds (manufacturer specified redraw time) + self.sleep_ms(self.refresh_delay) + self.epd.sleep() + + def sleep_ms(self, time): + from time import sleep_ms + sleep_ms(time) + +#confusingly, a 1 (interpreted in the display as 0xff) is the "off", or "empty" state for the pixel +#whereas a 0 is the "on", or "filled" state + +#set up framebuffers and backing buffers +#because we have a display with three colours (red, white, black), this is presented logically +#as two separate monochrome "frames" of equal size +#so when rendering, the display_frame function will take as many frames as there are non-white colours +#this could be used for easy inversion by just swapping the order of arguments to display_frame(buf,buf) +#some documentation suggests that framebuffer should be initialised directly +#using FrameBuffer(bytearray(size..)) +#however this causes problems when trying to use the fb as a buffer +#because it is not "subscriptable" +#thus the underlying buffer MUST be separated, as it cannot be directly read from inside the fb + +#set up SPI, then set up the ePaper display +#i'm using a WaveShare ePaper SPI 1.54in. display model (B) with a third colour (red) +#this example code will work identically for the model (C) with yellow as its third colour +#but is easily adaptable for other waveshare displays +#TODO make this configurable +#SPI is one of the more poorly documented parts of the micropython esp32 port +#i wish i could make this prettier + +#for power saving niceness, we reset before drawing, and sleep afterwards. +#result of this is that the display may redden a bit but will draw less power +#TODO figure out if there's a way to have the display only redraw the red or black, at present it redraws both