Initial
This commit is contained in:
commit
abadccf612
7
LICENSE
Normal file
7
LICENSE
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright 2024 Frederick Boniface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
720
Pico_ePaper_2_13_v4.py
Normal file
720
Pico_ePaper_2_13_v4.py
Normal file
@ -0,0 +1,720 @@
|
||||
# *****************************************************************************
|
||||
# * | File : Pico_ePaper-2.13_V3.py
|
||||
# * | Author : Waveshare team
|
||||
# * | Function : Electronic paper driver
|
||||
# * | Info :
|
||||
# *----------------
|
||||
# * | This version: V1.0
|
||||
# * | Date : 2021-11-01
|
||||
# # | Info : python demo
|
||||
# -----------------------------------------------------------------------------
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
from machine import Pin, SPI
|
||||
import framebuf
|
||||
import utime
|
||||
|
||||
|
||||
EPD_WIDTH = 122
|
||||
EPD_HEIGHT = 250
|
||||
|
||||
RST_PIN = 12
|
||||
DC_PIN = 8
|
||||
CS_PIN = 9
|
||||
BUSY_PIN = 13
|
||||
|
||||
class EPD_2in13_V4_Portrait(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)
|
||||
if EPD_WIDTH % 8 == 0:
|
||||
self.width = EPD_WIDTH
|
||||
else :
|
||||
self.width = (EPD_WIDTH // 8) * 8 + 8
|
||||
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()
|
||||
|
||||
'''
|
||||
function :Change the pin state
|
||||
parameter:
|
||||
pin : pin
|
||||
value : state
|
||||
'''
|
||||
def digital_write(self, pin, value):
|
||||
pin.value(value)
|
||||
|
||||
'''
|
||||
function : Read the pin state
|
||||
parameter:
|
||||
pin : pin
|
||||
'''
|
||||
def digital_read(self, pin):
|
||||
return pin.value()
|
||||
|
||||
'''
|
||||
function : The time delay function
|
||||
parameter:
|
||||
delaytime : ms
|
||||
'''
|
||||
def delay_ms(self, delaytime):
|
||||
utime.sleep(delaytime / 1000.0)
|
||||
|
||||
'''
|
||||
function : Write data to SPI
|
||||
parameter:
|
||||
data : data
|
||||
'''
|
||||
def spi_writebyte(self, data):
|
||||
self.spi.write(bytearray(data))
|
||||
|
||||
'''
|
||||
function :Hardware reset
|
||||
parameter:
|
||||
'''
|
||||
def reset(self):
|
||||
self.digital_write(self.reset_pin, 1)
|
||||
self.delay_ms(20)
|
||||
self.digital_write(self.reset_pin, 0)
|
||||
self.delay_ms(2)
|
||||
self.digital_write(self.reset_pin, 1)
|
||||
self.delay_ms(20)
|
||||
|
||||
'''
|
||||
function :send command
|
||||
parameter:
|
||||
command : Command register
|
||||
'''
|
||||
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)
|
||||
|
||||
'''
|
||||
function :send data
|
||||
parameter:
|
||||
data : Write data
|
||||
'''
|
||||
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)
|
||||
|
||||
'''
|
||||
function :Wait until the busy_pin goes LOW
|
||||
parameter:
|
||||
'''
|
||||
def ReadBusy(self):
|
||||
print('busy')
|
||||
self.delay_ms(10)
|
||||
while(self.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
|
||||
self.delay_ms(10)
|
||||
print('busy release')
|
||||
|
||||
'''
|
||||
function : Turn On Display
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplay(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xf7)
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Turn On Display Fast
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplay_Fast(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xC7) # fast:0x0c, quality:0x0f, 0xcf
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Turn On Display Part
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplayPart(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xff) # fast:0x0c, quality:0x0f, 0xcf
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Setting the display window
|
||||
parameter:
|
||||
Xstart : X-axis starting position
|
||||
Ystart : Y-axis starting position
|
||||
Xend : End position of X-axis
|
||||
Yend : End position of Y-axis
|
||||
'''
|
||||
def SetWindows(self, Xstart, Ystart, Xend, Yend):
|
||||
self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
|
||||
self.send_data((Xstart >> 3) & 0xFF)
|
||||
self.send_data((Xend >> 3) & 0xFF)
|
||||
|
||||
self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0xFF)
|
||||
self.send_data(Yend & 0xFF)
|
||||
self.send_data((Yend >> 8) & 0xFF)
|
||||
|
||||
'''
|
||||
function : Set Cursor
|
||||
parameter:
|
||||
Xstart : X-axis starting position
|
||||
Ystart : Y-axis starting position
|
||||
'''
|
||||
def SetCursor(self, Xstart, Ystart):
|
||||
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
|
||||
self.send_data(Xstart & 0xFF)
|
||||
|
||||
self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0xFF)
|
||||
|
||||
'''
|
||||
function : Initialize the e-Paper register
|
||||
parameter:
|
||||
'''
|
||||
def init(self):
|
||||
print('init')
|
||||
self.reset()
|
||||
self.delay_ms(100)
|
||||
|
||||
self.ReadBusy()
|
||||
self.send_command(0x12) # SWRESET
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x01) # Driver output control
|
||||
self.send_data(0xf9)
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x11) #data entry mode
|
||||
self.send_data(0x03)
|
||||
|
||||
self.SetWindows(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x3C) # BorderWaveform
|
||||
self.send_data(0x05)
|
||||
|
||||
self.send_command(0x21) # Display update control
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x80)
|
||||
|
||||
self.send_command(0x18) # Read built-in temperature sensor
|
||||
self.send_data(0x80)
|
||||
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Initialize the e-Paper fast register
|
||||
parameter:
|
||||
'''
|
||||
def init_fast(self):
|
||||
print('init_fast')
|
||||
self.reset()
|
||||
self.delay_ms(100)
|
||||
|
||||
self.send_command(0x12) #SWRESET
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x18) # Read built-in temperature sensor
|
||||
self.send_command(0x80)
|
||||
|
||||
self.send_command(0x11) # data entry mode
|
||||
self.send_data(0x03)
|
||||
|
||||
self.SetWindow(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x22) # Load temperature value
|
||||
self.send_data(0xB1)
|
||||
self.send_command(0x20)
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x1A) # Write to temperature register
|
||||
self.send_data(0x64)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x22) # Load temperature value
|
||||
self.send_data(0x91)
|
||||
self.send_command(0x20)
|
||||
self.ReadBusy()
|
||||
|
||||
return 0
|
||||
|
||||
'''
|
||||
function : Clear screen
|
||||
parameter:
|
||||
'''
|
||||
def Clear(self):
|
||||
self.send_command(0x24)
|
||||
self.send_data1([0xff] * self.height * int(self.width / 8))
|
||||
|
||||
self.TurnOnDisplay()
|
||||
|
||||
'''
|
||||
function : Sends the image buffer in RAM to e-Paper and displays
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def display(self, image):
|
||||
self.send_command(0x24)
|
||||
self.send_data1(image)
|
||||
self.TurnOnDisplay()
|
||||
|
||||
def display_fast(self, image):
|
||||
self.send_command(0x24)
|
||||
self.send_data2(image)
|
||||
self.TurnOnDisplay_Fast()
|
||||
|
||||
'''
|
||||
function : Refresh a base image
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def Display_Base(self, image):
|
||||
self.send_command(0x24)
|
||||
self.send_data1(image)
|
||||
|
||||
self.send_command(0x26)
|
||||
self.send_data1(image)
|
||||
|
||||
self.TurnOnDisplay()
|
||||
|
||||
'''
|
||||
function : Sends the image buffer in RAM to e-Paper and partial refresh
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def displayPartial(self, image):
|
||||
self.reset()
|
||||
|
||||
self.send_command(0x3C) # BorderWavefrom
|
||||
self.send_data(0x80)
|
||||
|
||||
self.send_command(0x01) # Driver output control
|
||||
self.send_data(0xF9)
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x11) # data entry mode
|
||||
self.send_data(0x03)
|
||||
|
||||
self.SetWindows(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x24) # WRITE_RAM
|
||||
self.send_data1(image)
|
||||
self.TurnOnDisplayPart()
|
||||
|
||||
'''
|
||||
function : Enter sleep mode
|
||||
parameter:
|
||||
'''
|
||||
def sleep(self):
|
||||
self.send_command(0x10) #enter deep sleep
|
||||
self.send_data(0x01)
|
||||
self.delay_ms(100)
|
||||
|
||||
|
||||
class EPD_2in13_V4_Landscape(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)
|
||||
if EPD_WIDTH % 8 == 0:
|
||||
self.width = EPD_WIDTH
|
||||
else :
|
||||
self.width = (EPD_WIDTH // 8) * 8 + 8
|
||||
|
||||
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.height, self.width, framebuf.MONO_VLSB)
|
||||
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 reset(self):
|
||||
self.digital_write(self.reset_pin, 1)
|
||||
self.delay_ms(20)
|
||||
self.digital_write(self.reset_pin, 0)
|
||||
self.delay_ms(2)
|
||||
self.digital_write(self.reset_pin, 1)
|
||||
self.delay_ms(20)
|
||||
|
||||
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 ReadBusy(self):
|
||||
print('busy')
|
||||
self.delay_ms(10)
|
||||
while(self.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
|
||||
self.delay_ms(10)
|
||||
print('busy release')
|
||||
|
||||
'''
|
||||
function : Turn On Display
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplay(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xf7)
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Turn On Display Fast
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplay_Fast(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xC7) # fast:0x0c, quality:0x0f, 0xcf
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Turn On Display Part
|
||||
parameter:
|
||||
'''
|
||||
def TurnOnDisplayPart(self):
|
||||
self.send_command(0x22) # Display Update Control
|
||||
self.send_data(0xff) # fast:0x0c, quality:0x0f, 0xcf
|
||||
self.send_command(0x20) # Activate Display Update Sequence
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Setting the display window
|
||||
parameter:
|
||||
Xstart : X-axis starting position
|
||||
Ystart : Y-axis starting position
|
||||
Xend : End position of X-axis
|
||||
Yend : End position of Y-axis
|
||||
'''
|
||||
def SetWindows(self, Xstart, Ystart, Xend, Yend):
|
||||
self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
|
||||
self.send_data((Xstart >> 3) & 0xFF)
|
||||
self.send_data((Xend >> 3) & 0xFF)
|
||||
|
||||
self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0xFF)
|
||||
self.send_data(Yend & 0xFF)
|
||||
self.send_data((Yend >> 8) & 0xFF)
|
||||
|
||||
'''
|
||||
function : Set Cursor
|
||||
parameter:
|
||||
Xstart : X-axis starting position
|
||||
Ystart : Y-axis starting position
|
||||
'''
|
||||
def SetCursor(self, Xstart, Ystart):
|
||||
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
|
||||
self.send_data(Xstart & 0xFF)
|
||||
|
||||
self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0xFF)
|
||||
|
||||
'''
|
||||
function : Initialize the e-Paper register
|
||||
parameter:
|
||||
'''
|
||||
def init(self):
|
||||
print('init')
|
||||
self.reset()
|
||||
self.delay_ms(100)
|
||||
|
||||
self.ReadBusy()
|
||||
self.send_command(0x12) # SWRESET
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x01) # Driver output control
|
||||
self.send_data(0xf9)
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x11) #data entry mode
|
||||
self.send_data(0x07)
|
||||
|
||||
self.SetWindows(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x3C) # BorderWaveform
|
||||
self.send_data(0x05)
|
||||
|
||||
self.send_command(0x21) # Display update control
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x80)
|
||||
|
||||
self.send_command(0x18) # Read built-in temperature sensor
|
||||
self.send_data(0x80)
|
||||
|
||||
self.ReadBusy()
|
||||
|
||||
'''
|
||||
function : Initialize the e-Paper fast register
|
||||
parameter:
|
||||
'''
|
||||
def init_fast(self):
|
||||
print('init_fast')
|
||||
self.reset()
|
||||
self.delay_ms(100)
|
||||
|
||||
self.send_command(0x12) #SWRESET
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x18) # Read built-in temperature sensor
|
||||
self.send_command(0x80)
|
||||
|
||||
self.send_command(0x11) # data entry mode
|
||||
self.send_data(0x07)
|
||||
|
||||
self.SetWindow(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x22) # Load temperature value
|
||||
self.send_data(0xB1)
|
||||
self.send_command(0x20)
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x1A) # Write to temperature register
|
||||
self.send_data(0x64)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x22) # Load temperature value
|
||||
self.send_data(0x91)
|
||||
self.send_command(0x20)
|
||||
self.ReadBusy()
|
||||
|
||||
return 0
|
||||
|
||||
'''
|
||||
function : Clear screen
|
||||
parameter:
|
||||
'''
|
||||
def Clear(self):
|
||||
self.send_command(0x24)
|
||||
self.send_data1([0xff] * self.height * int(self.width / 8))
|
||||
|
||||
self.TurnOnDisplay()
|
||||
|
||||
'''
|
||||
function : Sends the image buffer in RAM to e-Paper and displays
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def display(self, image):
|
||||
self.send_command(0x24)
|
||||
for j in range(int(self.width / 8) - 1, -1, -1):
|
||||
for i in range(0, self.height):
|
||||
self.send_data(image[i + j * self.height])
|
||||
self.TurnOnDisplay()
|
||||
|
||||
def display_fast(self, image):
|
||||
self.send_command(0x24)
|
||||
for j in range(int(self.width / 8) - 1, -1, -1):
|
||||
for i in range(0, self.height):
|
||||
self.send_data(image[i + j * self.height])
|
||||
self.TurnOnDisplay_Fast()
|
||||
|
||||
'''
|
||||
function : Refresh a base image
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def Display_Base(self, image):
|
||||
self.send_command(0x24)
|
||||
for j in range(int(self.width / 8) - 1, -1, -1):
|
||||
for i in range(0, self.height):
|
||||
self.send_data(image[i + j * self.height])
|
||||
|
||||
self.send_command(0x26)
|
||||
for j in range(int(self.width / 8) - 1, -1, -1):
|
||||
for i in range(0, self.height):
|
||||
self.send_data(image[i + j * self.height])
|
||||
|
||||
self.TurnOnDisplay()
|
||||
|
||||
'''
|
||||
function : Sends the image buffer in RAM to e-Paper and partial refresh
|
||||
parameter:
|
||||
image : Image data
|
||||
'''
|
||||
def displayPartial(self, image):
|
||||
self.reset()
|
||||
|
||||
self.send_command(0x3C) # BorderWavefrom
|
||||
self.send_data(0x80)
|
||||
|
||||
self.send_command(0x01) # Driver output control
|
||||
self.send_data(0xF9)
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x00)
|
||||
|
||||
self.send_command(0x11) # data entry mode
|
||||
self.send_data(0x07)
|
||||
|
||||
self.SetWindows(0, 0, self.width-1, self.height-1)
|
||||
self.SetCursor(0, 0)
|
||||
|
||||
self.send_command(0x24) # WRITE_RAM
|
||||
for j in range(int(self.width / 8) - 1, -1, -1):
|
||||
for i in range(0, self.height):
|
||||
self.send_data(image[i + j * self.height])
|
||||
self.TurnOnDisplayPart()
|
||||
|
||||
'''
|
||||
function : Enter sleep mode
|
||||
parameter:
|
||||
'''
|
||||
def sleep(self):
|
||||
self.send_command(0x10) #enter deep sleep
|
||||
self.send_data(0x01)
|
||||
self.delay_ms(100)
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
epd = EPD_2in13_V4_Landscape()
|
||||
epd.Clear()
|
||||
|
||||
epd.fill(0xff)
|
||||
epd.text("Waveshare", 0, 10, 0x00)
|
||||
epd.text("ePaper-2.13_V4", 0, 20, 0x00)
|
||||
epd.text("Raspberry Pico", 0, 30, 0x00)
|
||||
epd.text("Hello World", 0, 40, 0x00)
|
||||
epd.display(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.vline(5, 55, 60, 0x00)
|
||||
epd.vline(100, 55, 60, 0x00)
|
||||
epd.hline(5, 55, 95, 0x00)
|
||||
epd.hline(5, 115, 95, 0x00)
|
||||
epd.line(5, 55, 100, 115, 0x00)
|
||||
epd.line(100, 55, 5, 115, 0x00)
|
||||
epd.display(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.rect(130, 10, 40, 80, 0x00)
|
||||
epd.fill_rect(190, 10, 40, 80, 0x00)
|
||||
epd.Display_Base(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.init()
|
||||
for i in range(0, 10):
|
||||
epd.fill_rect(175, 105, 10, 10, 0xff)
|
||||
epd.text(str(i), 177, 106, 0x00)
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
print("sleep")
|
||||
epd.init()
|
||||
epd.Clear()
|
||||
epd.delay_ms(2000)
|
||||
epd.sleep()
|
||||
|
||||
|
||||
|
||||
epd = EPD_2in13_V4_Portrait()
|
||||
epd.Clear()
|
||||
|
||||
epd.fill(0xff)
|
||||
epd.text("Waveshare", 0, 10, 0x00)
|
||||
epd.text("ePaper-2.13_V4", 0, 30, 0x00)
|
||||
epd.text("Raspberry Pico", 0, 50, 0x00)
|
||||
epd.text("Hello World", 0, 70, 0x00)
|
||||
epd.display(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.vline(10, 90, 60, 0x00)
|
||||
epd.vline(90, 90, 60, 0x00)
|
||||
epd.hline(10, 90, 80, 0x00)
|
||||
epd.hline(10, 150, 80, 0x00)
|
||||
epd.line(10, 90, 90, 150, 0x00)
|
||||
epd.line(90, 90, 10, 150, 0x00)
|
||||
epd.display(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.rect(10, 180, 50, 40, 0x00)
|
||||
epd.fill_rect(60, 180, 50, 40, 0x00)
|
||||
epd.Display_Base(epd.buffer)
|
||||
epd.delay_ms(2000)
|
||||
|
||||
epd.init()
|
||||
for i in range(0, 10):
|
||||
epd.fill_rect(40, 230, 40, 10, 0xff)
|
||||
epd.text(str(i), 60, 230, 0x00)
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
print("sleep")
|
||||
epd.init()
|
||||
epd.Clear()
|
||||
epd.delay_ms(2000)
|
||||
epd.sleep()
|
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# PicoWidget
|
||||
|
||||
PicoWidget is a basic program written for a Raspberry Pi Pico W paired with a Waveshare 2.13" (v4) ePaper display. Note that the program is written for the black/white display which supports partial updates.
|
||||
|
||||
## Use
|
||||
|
||||
Install the MicroPython u2f file on to your Pico, then use Thonny or VSCode to upload the `.py` files and create an `ico` directory and upload the `bin` files there.
|
||||
|
||||
Adjust the values in `config.py`:
|
||||
- WIFI_SSID = Your WiFi SSID
|
||||
- WIFI_PASS = Your WiFi Password
|
||||
- LATLONG = (lat,long).
|
||||
|
||||
Then just power the Pico and you'll have tour very own PicoWidget.
|
||||
|
||||
## License
|
||||
|
||||
This project incorporates files from `ezFBfont` which is licensed under the MIT license.
|
||||
|
||||
This project incorporates font data from `ezFBfont` which was originally sourced from `Frederic Cambus` under the BSD-3-Clause license.
|
||||
|
||||
Files sourced from other projects all contain licensing details within the files.
|
||||
|
||||
All other files are released under the MIT license.
|
5
config.py
Normal file
5
config.py
Normal file
@ -0,0 +1,5 @@
|
||||
WIFI_SSID = ""
|
||||
WIFI_PASS = ""
|
||||
|
||||
WEATHER_URL = "https://api.open-meteo.com/"
|
||||
LATLONG = (0.00,0.00)
|
179
ezFBfont.py
Normal file
179
ezFBfont.py
Normal file
@ -0,0 +1,179 @@
|
||||
# ezFBfont.py() : a simple string writer for small mono displays and user selected fonts.
|
||||
# See MARQUEE.md for documentation
|
||||
|
||||
# Extensively re-worked from the 'writer' class by
|
||||
# Peter Hinch:
|
||||
# https://github.com/peterhinch/micropython-font-to-py
|
||||
# - Released under the MIT License (MIT). See LICENSE.
|
||||
# - Copyright (c) 2019-2021 Peter Hinch
|
||||
|
||||
import framebuf
|
||||
|
||||
# Basic string writing class
|
||||
class ezFBfont():
|
||||
|
||||
def __init__(self, device,
|
||||
font,
|
||||
fg = 1,
|
||||
bg = 0,
|
||||
tkey = -1,
|
||||
halign = 'left',
|
||||
valign = 'top',
|
||||
vgap = 0,
|
||||
hgap = 0,
|
||||
split = '\n',
|
||||
cswap = False,
|
||||
verbose = False):
|
||||
|
||||
self._device = device
|
||||
self._font = font
|
||||
self.name = self._font.__name__
|
||||
|
||||
# font and color; only monochrome HLSB fonts are supported
|
||||
self._font_format = framebuf.MONO_HLSB
|
||||
self._font_colors = 2
|
||||
self._palette_format = framebuf.RGB565 # support up to 65536 colors when blitting
|
||||
# byte order for 16bit colors
|
||||
self._cswap = cswap
|
||||
# inform
|
||||
if verbose:
|
||||
fstr = '{} : initialised: height: {}, {} width: {}, baseline: {}'
|
||||
print(fstr.format(self.name, self._font.height(),
|
||||
'fixed' if self._font.monospaced() else 'max',
|
||||
self._font.max_width(), self._font.baseline()))
|
||||
# apply init color and alignment as default
|
||||
self.set_default(fg, bg, tkey, halign, valign, hgap, vgap, split, verbose)
|
||||
|
||||
def _check_halign(self, h):
|
||||
if h not in ('left','center','right'):
|
||||
raise ValueError('Unknown horizontal alignment: ' + h)
|
||||
return h
|
||||
|
||||
def _check_valign(self, v):
|
||||
if v not in ('top','center','baseline','bottom'):
|
||||
raise ValueError('Unknown vertical alignment: ' + v)
|
||||
return v
|
||||
|
||||
def _line_size(self, string):
|
||||
x = 0
|
||||
for char in string:
|
||||
_, _, char_width = self._font.get_ch(char)
|
||||
x += char_width + self.hgap if char_width > 0 else 0
|
||||
x = x - self.hgap if x != 0 else x # remove any trailing hgap
|
||||
return x, self._font.height()
|
||||
|
||||
def _swap_bytes(self, color):
|
||||
# flip the left and right bytes in a 16 bit color word if required
|
||||
return ((color & 255) << 8) + (color >> 8) if self._cswap else color
|
||||
|
||||
def _put_char(self, char, x, y, fg, bg, tkey):
|
||||
# fetch the glyph
|
||||
glyph, char_height, char_width = self._font.get_ch(char)
|
||||
if glyph is None:
|
||||
return None, None # Nothing to write
|
||||
# buffers
|
||||
palette_buf = bytearray(self._font_colors * 2)
|
||||
buf = bytearray(glyph)
|
||||
# assemble color map
|
||||
palette = framebuf.FrameBuffer(palette_buf, self._font_colors, 1, self._palette_format)
|
||||
palette.pixel(0, 0, self._swap_bytes(bg))
|
||||
palette.pixel(self._font_colors -1, 0, self._swap_bytes(fg))
|
||||
# fetch and blit the glyph
|
||||
charbuf = framebuf.FrameBuffer(buf, char_width, char_height, self._font_format)
|
||||
self._device.blit(charbuf, x, y, tkey, palette)
|
||||
return char_width, char_height
|
||||
|
||||
def set_default(self, fg=None, bg=None, tkey=None,
|
||||
halign=None, valign=None, hgap=None, vgap=None, split=None, verbose=None):
|
||||
# Sets the default value for all supplied arguments
|
||||
self.fg = self.fg if fg is None else fg
|
||||
self.bg = self.bg if bg is None else bg
|
||||
self.tkey = self.tkey if tkey is None else tkey
|
||||
self.halign = self.halign if halign is None else self._check_halign(halign)
|
||||
self.valign = self.valign if valign is None else self._check_valign(valign)
|
||||
self.hgap = self.hgap if hgap is None else hgap
|
||||
self.vgap = self.vgap if vgap is None else vgap
|
||||
self.split = self.split if split is None else split
|
||||
self._verbose = self._verbose if verbose is None else verbose
|
||||
if self._verbose:
|
||||
fstr = '{} = fg: {}, bg: {}, tkey: {}, halign: {}, valign: {}, hgap: {}, vgap: {}, split: {}'
|
||||
print(fstr.format(self.name, self.fg, self.bg, self.tkey,
|
||||
self.halign, self.valign, self.hgap, self.vgap, repr(split)))
|
||||
|
||||
def size(self, string):
|
||||
if len(string) == 0:
|
||||
return 0, 0
|
||||
lines = string.split(self.split)
|
||||
w = 0
|
||||
for line in lines:
|
||||
x, _ = self._line_size(line)
|
||||
w = max(w, x) # record the widest line
|
||||
h = (len(lines) * (self._font.height() + self.vgap)) - self.vgap
|
||||
return w, h
|
||||
|
||||
def rect(self, string, x, y, halign=None, valign=None):
|
||||
if len(string) == 0:
|
||||
return x, y, 0, 0
|
||||
# apply alignment overrides
|
||||
halign = self.halign if halign is None else self._check_halign(halign)
|
||||
valign = self.valign if valign is None else self._check_valign(valign)
|
||||
# get the x,y size of the rendered string
|
||||
wide, high = self.size(string)
|
||||
# apply alignment
|
||||
xmin = x
|
||||
if halign == 'center':
|
||||
xmin = int(x - (wide / 2))
|
||||
elif halign == 'right':
|
||||
xmin = x - wide
|
||||
ymin = y
|
||||
if valign == 'baseline':
|
||||
ymin = y - self._font.baseline()
|
||||
elif valign == 'center':
|
||||
ymin = int(y - (high / 2))
|
||||
elif valign == 'bottom':
|
||||
ymin = y - high
|
||||
# return the result
|
||||
return xmin,ymin,wide,high
|
||||
|
||||
def write(self, string, x, y, fg=None, bg=None, tkey=None,
|
||||
halign=None, valign=None):
|
||||
if len(string) == 0:
|
||||
return True
|
||||
all_chars = True
|
||||
# Argument overrides
|
||||
fg = self.fg if fg is None else fg
|
||||
bg = self.bg if bg is None else bg
|
||||
tkey = self.tkey if tkey is None else tkey
|
||||
halign = self.halign if halign is None else self._check_halign(halign)
|
||||
valign = self.valign if valign is None else self._check_valign(valign)
|
||||
# Break the string into lines
|
||||
lines = string.split(self.split)
|
||||
# vertical alignment
|
||||
high = (len(lines) * (self._font.height() + self.vgap)) - self.vgap
|
||||
ypos = y
|
||||
if valign == 'baseline':
|
||||
ypos = y - self._font.baseline() + 1
|
||||
elif valign == 'center':
|
||||
ypos = int(y - (high / 2))
|
||||
elif valign == 'bottom':
|
||||
ypos = y - high
|
||||
for line in lines:
|
||||
wide, high = self._line_size(line)
|
||||
# horizontal alignment
|
||||
if halign == 'left':
|
||||
xpos = x
|
||||
elif halign == 'right':
|
||||
xpos = x - wide
|
||||
else:
|
||||
xpos = int(x - (wide / 2))
|
||||
# write the line
|
||||
for char in line:
|
||||
cx, _ = self._put_char(char, xpos, ypos, fg, bg, tkey)
|
||||
if cx is None:
|
||||
if self._verbose:
|
||||
print('{}: missing char: {} (0x{:02X})'.format(self.name, repr(char), ord(char)))
|
||||
all_chars = False
|
||||
else:
|
||||
xpos += cx + self.hgap
|
||||
ypos += high + self.vgap
|
||||
return all_chars
|
171
ezFBfont_spleen_16x32_ascii_30.py
Normal file
171
ezFBfont_spleen_16x32_ascii_30.py
Normal file
@ -0,0 +1,171 @@
|
||||
'''
|
||||
ezFBfont_spleen_16x32_ascii_30 : generated as part of the microPyEZfonts repository
|
||||
https://github.com/easytarget/microPyEZfonts
|
||||
|
||||
This font definition can be used with the "ezFBfont" class provided there.
|
||||
It can also be used with the "writer" class from Peter Hinches micropython
|
||||
font-to-py tool: https://github.com/peterhinch/micropython-font-to-py
|
||||
|
||||
Original spleen_16x32.bdf font file was sourced from the U8G2 project:
|
||||
https://github.com/olikraus/u8g2
|
||||
|
||||
'''
|
||||
# Code generated by bdf2dict.py
|
||||
# Font: spleen_16x32
|
||||
# Cmd: ['bdf2dict.py'], ['Latin-1-bdf-sources/spleen-16x32.bdf', '_', './ascii-char.set']
|
||||
# Date: 2024-07-31 14:57:34
|
||||
|
||||
# Customised by Fred Boniface 2024-11-18
|
||||
'''
|
||||
Original Copyright, Comments and Notices from source:
|
||||
|
||||
COPYRIGHT /*
|
||||
COPYRIGHT * Spleen 16x32 1.9.1
|
||||
COPYRIGHT * Copyright (c) 2018-2022, Frederic Cambus
|
||||
COPYRIGHT * https://www.cambus.net/
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * Created: 2018-08-12
|
||||
COPYRIGHT * Last Updated: 2020-10-10
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * Spleen is released under the BSD 2-Clause license.
|
||||
COPYRIGHT * See LICENSE file for details.
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * SPDX-License-Identifier: BSD-2-Clause
|
||||
COPYRIGHT */
|
||||
|
||||
COMMENT "Copyright (c) 2018-2022, Frederic Cambus"
|
||||
'''
|
||||
version = '0.33'
|
||||
name = '-misc-spleen-medium-r-normal--32-320-72-72-c-160-iso10646-1'
|
||||
family = 'spleen'
|
||||
weight = 'medium'
|
||||
size = 32
|
||||
|
||||
def height():
|
||||
return 30
|
||||
|
||||
def baseline():
|
||||
return 24
|
||||
|
||||
def max_width():
|
||||
return 16
|
||||
|
||||
def hmap():
|
||||
return True
|
||||
|
||||
def reverse():
|
||||
return False
|
||||
|
||||
def monospaced():
|
||||
return True
|
||||
|
||||
def min_ch():
|
||||
return 32
|
||||
|
||||
def max_ch():
|
||||
return 176
|
||||
|
||||
_g = {
|
||||
32:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
33:b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
34:b'\x00\x00\x00\x00\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
35:b'\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x18\x18\x18\x18\x18\x18\x7f\xfe\x7f\xfe\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x7f\xfe\x7f\xfe\x18\x18\x18\x18\x18\x18\x18\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
36:b'\x00\x00\x00\x00\x01\x80\x01\x80\x0f\xfc\x1f\xfc9\x801\x801\x801\x801\x809\x80\x1f\xf0\x0f\xf8\x01\x9c\x01\x8c\x01\x8c\x01\x8c\x01\x8c\x01\x8c\x01\x8c\x01\x9c?\xf8?\xf0\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
37:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x0e\x0c\x1b\x18\x1b\x18\x1b0\x0e0\x00`\x00`\x00\xc0\x00\xc0\x01\x80\x01\x80\x03\x00\x03\x00\x068\x06l\x0cl\x0cl\x188\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
38:b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\xe0\x0f\xf0\x1c8\x18\x18\x18\x18\x18\x18\x18\x18\x1c8\x0f\xf0\x07\xe0\x1f\x80?\xc0p\xec`|`8`0`8p|?\xee\x1f\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
39:b'\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
40:b'\x00\x00\x00<\x00\xfc\x01\xe0\x03\x80\x07\x00\x06\x00\x0e\x00\x0c\x00\x1c\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x1c\x00\x0c\x00\x0e\x00\x06\x00\x07\x00\x03\x80\x01\xe0\x00\xfc\x00<\x00\x00\x00\x00\x00\x00',
|
||||
41:b'\x00\x00<\x00?\x00\x07\x80\x01\xc0\x00\xe0\x00`\x00p\x000\x008\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x008\x000\x00p\x00`\x00\xe0\x01\xc0\x07\x80?\x00<\x00\x00\x00\x00\x00\x00\x00',
|
||||
42:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x1c8\x0ep\x07\xe0\x03\xc0\x03\xc0\x7f\xfe\x7f\xfe\x03\xc0\x03\xc0\x07\xe0\x0ep\x1c8\x18\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
43:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x1f\xf8\x1f\xf8\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
44:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x03\x80\x07\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
45:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
46:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
47:b'\x00\x00\x00\x06\x00\x06\x00\x0c\x00\x0c\x00\x18\x00\x18\x000\x000\x00`\x00`\x00\xc0\x00\xc0\x01\x80\x01\x80\x03\x00\x03\x00\x06\x00\x06\x00\x0c\x00\x0c\x00\x18\x00\x18\x000\x000\x00`\x00`\x00\x00\x00\x00\x00\x00\x00',
|
||||
48:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x1c0<0|0\xec1\xcc3\x8c7\x0c>\x0c<\x0c8\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
49:b'\x00\x00\x00\x00\x00\x00\x00\x00\x03\x80\x07\x80\r\x80\x19\x80\x11\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x1f\xf8\x1f\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
50:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x18\x000\x00`\x00\xc0\x01\x80\x03\x00\x06\x00\x0c\x00\x18\x000\x0c0\x0c?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
51:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x18\x07\xf0\x07\xf0\x00\x18\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
52:b'\x00\x00\x00\x00\x00\x00\x00\x000\x000\x000\x000\x000000000000000000?\xfc?\xfc\x000\x000\x000\x000\x000\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
53:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc0\x0c0\x0c0\x000\x000\x000\x00?\xf0?\xf8\x00\x1c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
54:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x000\x000\x000\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
55:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc0\x0c0\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x18\x000\x00`\x00\xc0\x01\x80\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
56:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c\x18\x18\x0f\xf0\x0f\xf0\x18\x180\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
57:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x0c\x00\x0c\x00\x0c\x00\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
58:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
59:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x03\x80\x07\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
60:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x008\x00p\x00\xe0\x01\xc0\x03\x80\x07\x00\x0e\x00\x1c\x008\x008\x00\x1c\x00\x0e\x00\x07\x00\x03\x80\x01\xc0\x00\xe0\x00p\x008\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
61:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
62:b'\x00\x00\x00\x00\x00\x00\x00\x008\x00\x1c\x00\x0e\x00\x07\x00\x03\x80\x01\xc0\x00\xe0\x00p\x008\x00\x1c\x00\x1c\x008\x00p\x00\xe0\x01\xc0\x03\x80\x07\x00\x0e\x00\x1c\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
63:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c\x00\x0c\x00\x0c\x00\x18\x000\x00`\x00\xc0\x00\xc0\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
64:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c1\xcc1\xcc1\xcc1\xcc1\xcc1\xcc1\xfc1\xfc0\x000\x008\x00\x1f\xf8\x0f\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
65:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c?\xfc?\xfc0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
66:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x18?\xf0?\xf00\x180\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
67:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x008\x00\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
68:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
69:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x000\x00?\xe0?\xe00\x000\x000\x000\x000\x000\x008\x00\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
70:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x000\x00?\xe0?\xe00\x000\x000\x000\x000\x000\x000\x000\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
71:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x000\x000\xfc0\xfc0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
72:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c?\xfc?\xfc0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
73:b'\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf8\x1f\xf8\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x1f\xf8\x1f\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
74:b'\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf8\x1f\xf8\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x03\x80\x7f\x00~\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
75:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x18000`?\xc0?\xc00`000\x180\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
76:b'\x00\x00\x00\x00\x00\x00\x00\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x008\x00\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
77:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c8\x1c<<>|7\xec3\xcc1\x8c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
78:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c8\x0c8\x0c<\x0c<\x0c6\x0c6\x0c3\x0c3\x0c1\x8c1\x8c0\xcc0\xcc0l0l0<0<0\x1c0\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
79:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
80:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x1c?\xf8?\xf00\x000\x000\x000\x000\x000\x000\x000\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
81:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c1\x8c1\x8c0\xcc8\xdc\x1f\xf8\x0f\xf0\x000\x000\x00\x18\x00\x18\x00\x00\x00\x00',
|
||||
82:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x18?\xf0?\xf00\x180\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
83:b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x008\x00\x1f\xf0\x0f\xf8\x00\x1c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
84:b'\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xfe\x7f\xfe\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
85:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
86:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1c8\x0ep\x07\xe0\x03\xc0\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
87:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c1\x8c3\xcc7\xec>|<<8\x1c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
88:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1c8\x0ep\x07\xe0\x07\xe0\x0ep\x1c88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
89:b'\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
90:b'\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x18\x000\x00`\x00\xc0\x01\x80\x03\x00\x06\x00\x0c\x00\x18\x000\x000\x000\x00?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
91:b'\x0f\xfc\x0f\xfc\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0f\xfc\x0f\xfc\x00\x00\x00\x00',
|
||||
92:b'\x00\x00`\x00`\x000\x000\x00\x18\x00\x18\x00\x0c\x00\x0c\x00\x06\x00\x06\x00\x03\x00\x03\x00\x01\x80\x01\x80\x00\xc0\x00\xc0\x00`\x00`\x000\x000\x00\x18\x00\x18\x00\x0c\x00\x0c\x00\x06\x00\x06\x00\x00\x00\x00\x00\x00',
|
||||
93:b'?\xf0?\xf0\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000\x000?\xf0?\xf0\x00\x00\x00\x00',
|
||||
94:b'\x00\x00\x00\x00\x01\x80\x03\xc0\x07\xe0\x0ep\x1c88\x1cp\x0e`\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
95:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xfe\x7f\xfe\x00\x00\x00\x00',
|
||||
96:b'\x00\x00\x00\x00\x06\x00\x07\x00\x03\x80\x01\xc0\x00\xe0\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
97:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf0\x1f\xf8\x00\x1c\x00\x0c\x00\x0c\x0f\xfc\x1f\xfc8\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
98:b'\x00\x00\x00\x00\x00\x00\x00\x000\x000\x000\x000\x000\x000\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
99:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x000\x000\x000\x000\x000\x000\x008\x00\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
100:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x0f\xfc\x1f\xfc8\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
101:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x0c0\x0c0\x0c0\x0c?\xfc?\xfc0\x000\x000\x008\x00\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
102:b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\xf8\x03\xf8\x07\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x1f\xe0\x1f\xe0\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
103:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x18\x00\x0c\x00\x0c\x00\x1c?\xf8?\xf0',
|
||||
104:b'\x00\x00\x00\x00\x00\x00\x00\x000\x000\x000\x000\x000\x000\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
105:b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x07\x80\x07\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\xe0\x01\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
106:b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x03\x80\x1f\x00\x1e\x00',
|
||||
107:b'\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x180\x18p\x18\xe0\x19\xc0\x1b\x80\x1f\x00\x1f\x00\x1b\x80\x19\xc0\x18\xe0\x18p\x188\x18\x1c\x18\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
108:b'\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x07\x00\x03\xf8\x01\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
109:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>p>x1\x9c1\x8c1\x8c1\x8c1\x8c1\x8c1\x8c1\x8c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
110:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
111:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x1f\xf88\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1f\xf8\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
112:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xf0?\xf80\x1c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x1c?\xf8?\xf00\x000\x000\x000\x000\x000\x00',
|
||||
113:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c',
|
||||
114:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x0c0\x0c0\x000\x000\x000\x000\x000\x000\x000\x000\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
115:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x1f\xfc8\x000\x000\x008\x00\x1f\xf0\x0f\xf8\x00\x1c\x00\x0c\x00\x0c\x00\x1c?\xf8?\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
116:b'\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x1f\xe0\x1f\xe0\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x07\x00\x03\xf8\x01\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
117:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
118:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x1c\x1c8\x0ep\x07\xe0\x03\xc0\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
119:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c1\x8c1\x8c1\x8c1\x8c1\x8c1\x8c1\x8c9\x8c\x1e|\x0e|\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
120:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x0c8\x1c\x1c8\x0ep\x07\xe0\x03\xc0\x03\xc0\x07\xe0\x0ep\x1c8\x18\x188\x1c0\x0c0\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
121:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c0\x0c8\x0c\x1f\xfc\x0f\xfc\x00\x0c\x00\x0c\x00\x0c\x00\x1c?\xf8?\xf0',
|
||||
122:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc?\xfc\x00\x0c\x00\x18\x000\x00`\x00\xc0\x01\x80\x03\x00\x06\x00\x0c\x00\x18\x00?\xfc?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
123:b'\x00\xfc\x01\xfc\x03\x80\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x07\x00>\x00<\x00<\x00>\x00\x07\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x80\x01\xfc\x00\xfc\x00\x00\x00\x00',
|
||||
124:b'\x00\x00\x00\x00\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
125:b'?\x00?\x80\x01\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xe0\x00|\x00<\x00<\x00|\x00\xe0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x01\xc0?\x80?\x00\x00\x00\x00\x00',
|
||||
126:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x0c\x1f\x0c;\x9c1\xf80\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
176:b'\x00\x00\x00\x00\x03\xc0\x07\xe0\x0ep\x0c0\x0c0\x0c0\x0ep\x07\xe0\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
}
|
||||
|
||||
def get_ch(ch):
|
||||
c = ord(ch)
|
||||
if c not in _g.keys():
|
||||
return None, 0, 0
|
||||
return memoryview(_g[c]), 30, 16
|
171
ezFBfont_spleen_8x16_ascii_14.py
Normal file
171
ezFBfont_spleen_8x16_ascii_14.py
Normal file
@ -0,0 +1,171 @@
|
||||
'''
|
||||
ezFBfont_spleen_8x16_ascii_14 : generated as part of the microPyEZfonts repository
|
||||
https://github.com/easytarget/microPyEZfonts
|
||||
|
||||
This font definition can be used with the "ezFBfont" class provided there.
|
||||
It can also be used with the "writer" class from Peter Hinches micropython
|
||||
font-to-py tool: https://github.com/peterhinch/micropython-font-to-py
|
||||
|
||||
Original spleen_8x16.bdf font file was sourced from the U8G2 project:
|
||||
https://github.com/olikraus/u8g2
|
||||
|
||||
'''
|
||||
# Code generated by bdf2dict.py
|
||||
# Font: spleen_8x16
|
||||
# Cmd: ['bdf2dict.py'], ['Latin-1-bdf-sources/spleen-8x16.bdf', '_', './ascii-char.set']
|
||||
# Date: 2024-07-31 14:57:38
|
||||
|
||||
# Customised by Fred Boniface 2024-11-18
|
||||
'''
|
||||
Original Copyright, Comments and Notices from source:
|
||||
|
||||
COPYRIGHT /*
|
||||
COPYRIGHT * Spleen 8x16 1.9.1
|
||||
COPYRIGHT * Copyright (c) 2018-2022, Frederic Cambus
|
||||
COPYRIGHT * https://www.cambus.net/
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * Created: 2018-08-11
|
||||
COPYRIGHT * Last Updated: 2020-10-10
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * Spleen is released under the BSD 2-Clause license.
|
||||
COPYRIGHT * See LICENSE file for details.
|
||||
COPYRIGHT *
|
||||
COPYRIGHT * SPDX-License-Identifier: BSD-2-Clause
|
||||
COPYRIGHT */
|
||||
|
||||
COMMENT "Copyright (c) 2018-2022, Frederic Cambus"
|
||||
'''
|
||||
version = '0.33'
|
||||
name = '-misc-spleen-medium-r-normal--16-160-72-72-c-80-iso10646-1'
|
||||
family = 'spleen'
|
||||
weight = 'medium'
|
||||
size = 16
|
||||
|
||||
def height():
|
||||
return 14
|
||||
|
||||
def baseline():
|
||||
return 11
|
||||
|
||||
def max_width():
|
||||
return 8
|
||||
|
||||
def hmap():
|
||||
return True
|
||||
|
||||
def reverse():
|
||||
return False
|
||||
|
||||
def monospaced():
|
||||
return True
|
||||
|
||||
def min_ch():
|
||||
return 32
|
||||
|
||||
def max_ch():
|
||||
return 176
|
||||
|
||||
_g = {
|
||||
32:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
33:b'\x00\x18\x18\x18\x18\x18\x18\x18\x00\x18\x18\x00\x00\x00',
|
||||
34:b'ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
35:b'\x00ll\xfellll\xfell\x00\x00\x00',
|
||||
36:b'\x10~\xd0\xd0\xd0|\x16\x16\x16\x16\xfc\x10\x00\x00',
|
||||
37:b'\x00\x06fl\x0c\x18\x1806f`\x00\x00\x00',
|
||||
38:b'\x008lll8p\xda\xcc\xccz\x00\x00\x00',
|
||||
39:b'\x18\x18\x18\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
40:b'\x0e\x1800````00\x18\x0e\x00\x00',
|
||||
41:b'p\x18\x0c\x0c\x06\x06\x06\x06\x0c\x0c\x18p\x00\x00',
|
||||
42:b'\x00\x00\x00f<\x18\xff\x18<f\x00\x00\x00\x00',
|
||||
43:b'\x00\x00\x00\x00\x18\x18~\x18\x18\x00\x00\x00\x00\x00',
|
||||
44:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x180\x00\x00',
|
||||
45:b'\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00',
|
||||
46:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x00\x00\x00',
|
||||
47:b'\x06\x06\x0c\x0c\x18\x1800``\xc0\xc0\x00\x00',
|
||||
48:b'\x00|\xc6\xc6\xce\xde\xf6\xe6\xc6\xc6|\x00\x00\x00',
|
||||
49:b'\x00\x188xX\x18\x18\x18\x18\x18~\x00\x00\x00',
|
||||
50:b'\x00|\xc6\x06\x06\x0c\x180`\xc6\xfe\x00\x00\x00',
|
||||
51:b'\x00|\xc6\x06\x06<\x06\x06\x06\xc6|\x00\x00\x00',
|
||||
52:b'\x00\xc0\xc0\xcc\xcc\xcc\xcc\xfe\x0c\x0c\x0c\x00\x00\x00',
|
||||
53:b'\x00\xfe\xc6\xc0\xc0\xfc\x06\x06\x06\xc6|\x00\x00\x00',
|
||||
54:b'\x00|\xc6\xc0\xc0\xfc\xc6\xc6\xc6\xc6|\x00\x00\x00',
|
||||
55:b'\x00\xfe\xc6\x06\x06\x0c\x180000\x00\x00\x00',
|
||||
56:b'\x00|\xc6\xc6\xc6|\xc6\xc6\xc6\xc6|\x00\x00\x00',
|
||||
57:b'\x00|\xc6\xc6\xc6\xc6~\x06\x06\xc6|\x00\x00\x00',
|
||||
58:b'\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x18\x00\x00\x00',
|
||||
59:b'\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x180\x00\x00',
|
||||
60:b'\x00\x06\x0c\x180``0\x18\x0c\x06\x00\x00\x00',
|
||||
61:b'\x00\x00\x00\x00~\x00\x00~\x00\x00\x00\x00\x00\x00',
|
||||
62:b'\x00`0\x18\x0c\x06\x06\x0c\x180`\x00\x00\x00',
|
||||
63:b'\x00|\xc6\x06\x0c\x1800\x0000\x00\x00\x00',
|
||||
64:b'\x00\x00|\xc2\xda\xda\xda\xda\xde\xc0|\x00\x00\x00',
|
||||
65:b'\x00|\xc6\xc6\xc6\xfe\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
66:b'\x00\xfc\xc6\xc6\xc6\xfc\xc6\xc6\xc6\xc6\xfc\x00\x00\x00',
|
||||
67:b'\x00~\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0~\x00\x00\x00',
|
||||
68:b'\x00\xfc\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xfc\x00\x00\x00',
|
||||
69:b'\x00~\xc0\xc0\xc0\xf8\xc0\xc0\xc0\xc0~\x00\x00\x00',
|
||||
70:b'\x00~\xc0\xc0\xc0\xf8\xc0\xc0\xc0\xc0\xc0\x00\x00\x00',
|
||||
71:b'\x00~\xc0\xc0\xc0\xde\xc6\xc6\xc6\xc6~\x00\x00\x00',
|
||||
72:b'\x00\xc6\xc6\xc6\xc6\xfe\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
73:b'\x00~\x18\x18\x18\x18\x18\x18\x18\x18~\x00\x00\x00',
|
||||
74:b'\x00~\x18\x18\x18\x18\x18\x18\x18\x18\xf0\x00\x00\x00',
|
||||
75:b'\x00\xc6\xc6\xc6\xcc\xf8\xcc\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
76:b'\x00\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0~\x00\x00\x00',
|
||||
77:b'\x00\xc6\xee\xfe\xd6\xc6\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
78:b'\x00\xc6\xc6\xe6\xe6\xd6\xd6\xce\xce\xc6\xc6\x00\x00\x00',
|
||||
79:b'\x00|\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6|\x00\x00\x00',
|
||||
80:b'\x00\xfc\xc6\xc6\xc6\xfc\xc0\xc0\xc0\xc0\xc0\x00\x00\x00',
|
||||
81:b'\x00|\xc6\xc6\xc6\xc6\xc6\xc6\xd6\xd6|\x18\x0c\x00',
|
||||
82:b'\x00\xfc\xc6\xc6\xc6\xfc\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
83:b'\x00~\xc0\xc0\xc0|\x06\x06\x06\x06\xfc\x00\x00\x00',
|
||||
84:b'\x00\xff\x18\x18\x18\x18\x18\x18\x18\x18\x18\x00\x00\x00',
|
||||
85:b'\x00\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6~\x00\x00\x00',
|
||||
86:b'\x00\xc6\xc6\xc6\xc6\xc6\xc6\xc6l8\x10\x00\x00\x00',
|
||||
87:b'\x00\xc6\xc6\xc6\xc6\xc6\xc6\xd6\xfe\xee\xc6\x00\x00\x00',
|
||||
88:b'\x00\xc6\xc6\xc6l8l\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
89:b'\x00\xc6\xc6\xc6\xc6~\x06\x06\x06\x06\xfc\x00\x00\x00',
|
||||
90:b'\x00\xfe\x06\x06\x0c\x180`\xc0\xc0\xfe\x00\x00\x00',
|
||||
91:b'>0000000000>\x00\x00',
|
||||
92:b'\xc0\xc0``00\x18\x18\x0c\x0c\x06\x06\x00\x00',
|
||||
93:b'|\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c|\x00\x00',
|
||||
94:b'\x108l\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
95:b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe',
|
||||
96:b'0\x18\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
97:b'\x00\x00\x00\x00|\x06~\xc6\xc6\xc6~\x00\x00\x00',
|
||||
98:b'\x00\xc0\xc0\xc0\xfc\xc6\xc6\xc6\xc6\xc6\xfc\x00\x00\x00',
|
||||
99:b'\x00\x00\x00\x00~\xc0\xc0\xc0\xc0\xc0~\x00\x00\x00',
|
||||
100:b'\x00\x06\x06\x06~\xc6\xc6\xc6\xc6\xc6~\x00\x00\x00',
|
||||
101:b'\x00\x00\x00\x00~\xc6\xc6\xfe\xc0\xc0~\x00\x00\x00',
|
||||
102:b'\x00\x1e000|00000\x00\x00\x00',
|
||||
103:b'\x00\x00\x00\x00~\xc6\xc6\xc6\xc6\xc6|\x06\x06\xfc',
|
||||
104:b'\x00\xc0\xc0\xc0\xfc\xc6\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
105:b'\x00\x18\x18\x008\x18\x18\x18\x18\x18\x1c\x00\x00\x00',
|
||||
106:b'\x00\x18\x18\x00\x18\x18\x18\x18\x18\x18\x18\x18\x18p',
|
||||
107:b'\x00\xc0\xc0\xc0\xcc\xd8\xf0\xf0\xd8\xcc\xc6\x00\x00\x00',
|
||||
108:b'\x00000000000\x1c\x00\x00\x00',
|
||||
109:b'\x00\x00\x00\x00\xec\xd6\xd6\xd6\xd6\xc6\xc6\x00\x00\x00',
|
||||
110:b'\x00\x00\x00\x00\xfc\xc6\xc6\xc6\xc6\xc6\xc6\x00\x00\x00',
|
||||
111:b'\x00\x00\x00\x00|\xc6\xc6\xc6\xc6\xc6|\x00\x00\x00',
|
||||
112:b'\x00\x00\x00\x00\xfc\xc6\xc6\xc6\xc6\xc6\xfc\xc0\xc0\xc0',
|
||||
113:b'\x00\x00\x00\x00~\xc6\xc6\xc6\xc6\xc6~\x06\x06\x06',
|
||||
114:b'\x00\x00\x00\x00~\xc6\xc0\xc0\xc0\xc0\xc0\x00\x00\x00',
|
||||
115:b'\x00\x00\x00\x00~\xc0\xc0|\x06\x06\xfc\x00\x00\x00',
|
||||
116:b'\x00000|00000\x1e\x00\x00\x00',
|
||||
117:b'\x00\x00\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6~\x00\x00\x00',
|
||||
118:b'\x00\x00\x00\x00\xc6\xc6\xc6\xc6l8\x10\x00\x00\x00',
|
||||
119:b'\x00\x00\x00\x00\xc6\xc6\xd6\xd6\xd6\xd6n\x00\x00\x00',
|
||||
120:b'\x00\x00\x00\x00\xc6l88l\xc6\xc6\x00\x00\x00',
|
||||
121:b'\x00\x00\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6~\x06\x06\xfc',
|
||||
122:b'\x00\x00\x00\x00\xfe\x06\x0c\x180`\xfe\x00\x00\x00',
|
||||
123:b'\x0e\x18\x18\x18\x18pp\x18\x18\x18\x18\x0e\x00\x00',
|
||||
124:b'\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x00\x00',
|
||||
125:b'p\x18\x18\x18\x18\x0e\x0e\x18\x18\x18\x18p\x00\x00',
|
||||
126:b'\x00\x00\x00\x00\x002~L\x00\x00\x00\x00\x00\x00',
|
||||
176:b'8ll8\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
}
|
||||
|
||||
def get_ch(ch):
|
||||
c = ord(ch)
|
||||
if c not in _g.keys():
|
||||
return None, 0, 0
|
||||
return memoryview(_g[c]), 14, 8
|
BIN
ico/weather-cloudy.bin
Normal file
BIN
ico/weather-cloudy.bin
Normal file
Binary file not shown.
BIN
ico/weather-fog.bin
Normal file
BIN
ico/weather-fog.bin
Normal file
Binary file not shown.
BIN
ico/weather-hail.bin
Normal file
BIN
ico/weather-hail.bin
Normal file
Binary file not shown.
BIN
ico/weather-hazy.bin
Normal file
BIN
ico/weather-hazy.bin
Normal file
Binary file not shown.
BIN
ico/weather-lightning-rainy.bin
Normal file
BIN
ico/weather-lightning-rainy.bin
Normal file
Binary file not shown.
BIN
ico/weather-lightning.bin
Normal file
BIN
ico/weather-lightning.bin
Normal file
Binary file not shown.
BIN
ico/weather-night-partly-cloudy.bin
Normal file
BIN
ico/weather-night-partly-cloudy.bin
Normal file
Binary file not shown.
BIN
ico/weather-night.bin
Normal file
BIN
ico/weather-night.bin
Normal file
Binary file not shown.
BIN
ico/weather-partly-cloudy.bin
Normal file
BIN
ico/weather-partly-cloudy.bin
Normal file
Binary file not shown.
BIN
ico/weather-partly-lightning.bin
Normal file
BIN
ico/weather-partly-lightning.bin
Normal file
Binary file not shown.
BIN
ico/weather-partly-rainy.bin
Normal file
BIN
ico/weather-partly-rainy.bin
Normal file
Binary file not shown.
BIN
ico/weather-partly-snowy-rainy.bin
Normal file
BIN
ico/weather-partly-snowy-rainy.bin
Normal file
Binary file not shown.
BIN
ico/weather-partly-snowy.bin
Normal file
BIN
ico/weather-partly-snowy.bin
Normal file
Binary file not shown.
BIN
ico/weather-pouring.bin
Normal file
BIN
ico/weather-pouring.bin
Normal file
Binary file not shown.
BIN
ico/weather-rainy.bin
Normal file
BIN
ico/weather-rainy.bin
Normal file
Binary file not shown.
BIN
ico/weather-snowy-heavy.bin
Normal file
BIN
ico/weather-snowy-heavy.bin
Normal file
Binary file not shown.
BIN
ico/weather-snowy-rainy.bin
Normal file
BIN
ico/weather-snowy-rainy.bin
Normal file
Binary file not shown.
BIN
ico/weather-snowy.bin
Normal file
BIN
ico/weather-snowy.bin
Normal file
Binary file not shown.
BIN
ico/weather-sunny.bin
Normal file
BIN
ico/weather-sunny.bin
Normal file
Binary file not shown.
BIN
ico/weather-sunset-down.bin
Normal file
BIN
ico/weather-sunset-down.bin
Normal file
Binary file not shown.
BIN
ico/weather-sunset-up.bin
Normal file
BIN
ico/weather-sunset-up.bin
Normal file
Binary file not shown.
131
main.py
Normal file
131
main.py
Normal file
@ -0,0 +1,131 @@
|
||||
#Copyright 2024 Frederick Boniface
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from Pico_ePaper_2_13_v4 import EPD_2in13_V4_Landscape
|
||||
from ezFBfont import ezFBfont
|
||||
import ezFBfont_spleen_16x32_ascii_30 as spleen30Font
|
||||
import ezFBfont_spleen_8x16_ascii_14 as spleen14Font
|
||||
|
||||
import ntptime, network, utime
|
||||
import config, open_meteo
|
||||
|
||||
epd = EPD_2in13_V4_Landscape()
|
||||
|
||||
WHT = 0xff
|
||||
BLK = 0x00
|
||||
|
||||
spleen30wht = ezFBfont(epd, spleen30Font, fg=WHT, bg=BLK)
|
||||
spleen30blk = ezFBfont(epd, spleen30Font, fg=BLK, bg=WHT)
|
||||
spleen14wht = ezFBfont(epd, spleen14Font, fg=WHT, bg=BLK)
|
||||
spleen14blk = ezFBfont(epd, spleen14Font, fg=BLK, bg=WHT)
|
||||
|
||||
epd.fill(WHT)
|
||||
epd.display(epd.buffer)
|
||||
|
||||
## Functions
|
||||
def update_time():
|
||||
try:
|
||||
ntptime.host = "time.fjla.net"
|
||||
ntptime.settime()
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
# Load icon into buffer
|
||||
def blit_to_framebuffer(framebuffer, fb_width, x, y, image_bytes, img_width, img_height):
|
||||
for row in range(img_height):
|
||||
for col in range(img_width):
|
||||
byte_index = (row * (img_width // 8)) + (col // 8)
|
||||
bit_index = 7 - (col % 8)
|
||||
bit = (image_bytes[byte_index] >> bit_index) & 1
|
||||
|
||||
framebuffer.pixel(x + col, y + row, bit)
|
||||
|
||||
# Load weather data into buffer
|
||||
def update_weather():
|
||||
# Get and load weather data
|
||||
weather = open_meteo.get_weather()
|
||||
blit_to_framebuffer(epd, epd.width, 3, 5, weather['icon'], 72, 72)
|
||||
spleen30wht.write(f"{str(weather['current_temp'])} C", 3, 82)
|
||||
spleen14wht.write(f"Min: {str(weather['min'])} C", 82, 10)
|
||||
spleen14wht.write(f"Max: {str(weather['max'])} C", 82, 25)
|
||||
#epd.image1Gray.text("Apparent min: " + str(weather['apparent_min']) + "C", 75, 25, WHITE)
|
||||
#epd.image1Gray.text("Apparent max: " + str(weather['apparent_max']) + "C", 75, 35, WHITE)
|
||||
return
|
||||
|
||||
def get_day(day_no):
|
||||
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
|
||||
return days[day_no]
|
||||
|
||||
## Init
|
||||
spleen30blk.write("PicoWidget-v0.1", 5, 5)
|
||||
epd.text("Initialising", 5, 40, BLK)
|
||||
epd.display(epd.buffer)
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
wlan.connect(config.WIFI_SSID, config.WIFI_PASS)
|
||||
max_attempts = 10
|
||||
attempt = 0
|
||||
while not wlan.isconnected() and attempt < max_attempts:
|
||||
utime.sleep(1)
|
||||
attempt += 1
|
||||
|
||||
if wlan.isconnected():
|
||||
epd.text(f"WiFi Connection ({config.WIFI_SSID}): OK", 5, 52, BLK)
|
||||
else:
|
||||
epd.text(f"WiFi Connection ({config.WiFi_SSID}): FAIL", 5, 52, BLK)
|
||||
|
||||
try:
|
||||
update_time()
|
||||
epd.text(f"NTP Update: OK", 5, 64, BLK)
|
||||
except Exception as e:
|
||||
epd.text(f"NTP Update: FAIL", 5, 64, BLK)
|
||||
print(e)
|
||||
|
||||
epd.text(f"Location: {config.LATLONG}", 5, 76, BLK)
|
||||
epd.text(f"Buffering display...", 5, 88, BLK)
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
tick = 0
|
||||
displayed_time = None
|
||||
displayed_msg = None
|
||||
|
||||
while True:
|
||||
partial_display_needed = False
|
||||
full_display_needed = False
|
||||
|
||||
if tick % 360 == 0:
|
||||
epd.fill(BLK)
|
||||
update_weather()
|
||||
full_display_needed = True
|
||||
update_time()
|
||||
|
||||
t = utime.localtime()
|
||||
t_str = "{:02}:{:02}".format(t[3], t[4])
|
||||
d_str = "{:02}/{:02}/{:4}".format(t[2], t[1], t[0])
|
||||
if t_str != displayed_time or full_display_needed:
|
||||
spleen30wht.write(t_str, 160, 60)
|
||||
spleen14wht.write(get_day(t[6]), 160, 90)
|
||||
spleen14wht.write(d_str, 160, 110)
|
||||
displayed_time = t_str
|
||||
partial_display_needed = True
|
||||
|
||||
if not full_display_needed:
|
||||
if partial_display_needed:
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
if full_display_needed:
|
||||
epd.display(epd.buffer)
|
||||
epd.displayPartial(epd.buffer)
|
||||
|
||||
tick += 1
|
||||
if tick >= 7200:
|
||||
tick = 0
|
||||
|
||||
utime.sleep(20)
|
63
open_meteo.py
Normal file
63
open_meteo.py
Normal file
@ -0,0 +1,63 @@
|
||||
#Copyright 2024 Frederick Boniface
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import urequests
|
||||
|
||||
import config
|
||||
|
||||
def get_weather():
|
||||
URL = f"https://api.open-meteo.com/v1/forecast?latitude={config.LATLONG[0]}&longitude={config.LATLONG[1]}¤t=temperature_2m&daily=weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset,wind_speed_10m_max,wind_gusts_10m_max&timezone=Europe%2FLondon&forecast_days=1"
|
||||
res = urequests.get(URL)
|
||||
return parse_weather(res.json())
|
||||
|
||||
def parse_weather(weather):
|
||||
output = {
|
||||
"current_temp": weather['current']['temperature_2m'],
|
||||
"max": weather['daily']['temperature_2m_max'][0],
|
||||
"min": weather['daily']['temperature_2m_min'][0],
|
||||
"sunrise": weather['daily']['sunrise'][0],
|
||||
"sunset": weather['daily']['sunset'][0],
|
||||
"icon": get_weather_icon(weather['daily']['weather_code'][0]),
|
||||
}
|
||||
return output
|
||||
|
||||
def get_weather_icon(code):
|
||||
with open (weather_icon_paths[code], "rb") as file:
|
||||
raw_bytes = file.read()
|
||||
return raw_bytes
|
||||
|
||||
weather_icon_paths = {
|
||||
0: "/ico/weather-sunny.bin", #Clear Sky
|
||||
1: "/ico/weather-sunny.bin", #Mainly Clear
|
||||
2: "/ico/weather-partly-cloudy.bin", #Partly Cloudy
|
||||
3: "/ico/weather-cloudy.bin", #Overcast
|
||||
45: "/ico/weather-fog.bin", #Fog
|
||||
48: "/ico/weather-fog.bin", #Depositing Rime Fog
|
||||
51: "/ico/weather-partly-rainy.bin", #Light Drizzle
|
||||
53: "/ico/weather-partly-rainy.bin", #Moderate Drizzle
|
||||
55: "/ico/weather-partly-rainy.bin", #Dense Drizzle
|
||||
56: "/ico/weather-snowy-rainy.bin", #Light Freezing Drizzle
|
||||
57: "/ico/weather-snowy-rainy.bin", #Dense Freezing Drizzle
|
||||
61: "/ico/weather-rainy.bin", #Light Rain
|
||||
63: "/ico/weather-rainy.bin", #Moderate Rain
|
||||
65: "/ico/weather-pouring.bin", #Heavy Rain
|
||||
66: "/ico/weather-hail.bin", #Light Freezing Rain
|
||||
67: "/ico/weather-hail.bin", #Heavy Freezing Rain
|
||||
71: "/ico/weather-snowy.bin", #Slight Snowfall
|
||||
73: "/ico/weather-snowy.bin", #Moderate Snowfall
|
||||
75: "/ico/weather-snowy-heavy.bin", #Heavy Snowfall
|
||||
77: "/ico/weather-snowy-heavy.bin", #Snow Grains
|
||||
80: "/ico/weather-partly-rainy.bin", #Slight Rain Showers
|
||||
81: "/ico/weather-partly-rainy.bin", #Moderate Rain Showers
|
||||
82: "/ico/weather-pouring.bin", #Violent Rain Showers
|
||||
85: "/ico/weather-partly-snowy.bin", #Slight Snow Showers
|
||||
86: "/ico/weather-partly-snowy.bin", #Heavy Snow Showers
|
||||
95: "/ico/weather-partly-lightning.bin", #Slight or Moderate Thunderstorm
|
||||
96: "/ico/weather-lightning.bin", #Thunderstorm with Slight Hail
|
||||
99: "/ico/weather-lightning-rainy.bin", #Thunderstorm with Heavy Hail
|
||||
}
|
Loading…
Reference in New Issue
Block a user