diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbe9c82 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ \ No newline at end of file diff --git a/.picowgo b/.picowgo new file mode 100644 index 0000000..2b7291a --- /dev/null +++ b/.picowgo @@ -0,0 +1 @@ +{'info': 'This file is just used to identify a project folder.'} \ No newline at end of file diff --git a/buttons.py b/buttons.py new file mode 100644 index 0000000..f41bf43 --- /dev/null +++ b/buttons.py @@ -0,0 +1,8 @@ +import machine +import utime +onboard_led = machine.Pin(25, machine.Pin.OUT) +while True: + onboard_led.value(1) + utime.sleep(5) + onboard_led.value(0) + utime.sleep(5) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..e69de29 diff --git a/pico_rainbow.py b/pico_rainbow.py index 1d058b9..1a1164b 100644 --- a/pico_rainbow.py +++ b/pico_rainbow.py @@ -2,17 +2,11 @@ import st7789 from pimoroni import RGBLED -import time -import random -import st7789 - # Set the display resolution, in most cases you can flip these for portrait mode # WIDTH, HEIGHT = 240, 135 # Pico Display WIDTH, HEIGHT = 240, 240 # Pico Display 2.0 -display = st7789.ST7789(WIDTH, HEIGHT, rotate180=False) - -display.set_backlight(0.1) +display = st7789.ST7789(width=WIDTH, height=HEIGHT, spi=3, reset=False, dc=5, backlight=4) class Ball: diff --git a/st7789.py b/st7789.py new file mode 100644 index 0000000..7cd23d0 --- /dev/null +++ b/st7789.py @@ -0,0 +1,777 @@ +import time +from micropython import const +import ustruct as struct +# commands +ST7789_NOP = const(0x00) +ST7789_SWRESET = const(0x01) +ST7789_RDDID = const(0x04) +ST7789_RDDST = const(0x09) +ST7789_SLPIN = const(0x10) +ST7789_SLPOUT = const(0x11) +ST7789_PTLON = const(0x12) +ST7789_NORON = const(0x13) +ST7789_INVOFF = const(0x20) +ST7789_INVON = const(0x21) +ST7789_DISPOFF = const(0x28) +ST7789_DISPON = const(0x29) +ST7789_CASET = const(0x2A) +ST7789_RASET = const(0x2B) +ST7789_RAMWR = const(0x2C) +ST7789_RAMRD = const(0x2E) +ST7789_PTLAR = const(0x30) +ST7789_VSCRDEF = const(0x33) +ST7789_COLMOD = const(0x3A) +ST7789_MADCTL = const(0x36) +ST7789_VSCSAD = const(0x37) +ST7789_MADCTL_MY = const(0x80) +ST7789_MADCTL_MX = const(0x40) +ST7789_MADCTL_MV = const(0x20) +ST7789_MADCTL_ML = const(0x10) +ST7789_MADCTL_BGR = const(0x08) +ST7789_MADCTL_MH = const(0x04) +ST7789_MADCTL_RGB = const(0x00) +ST7789_RDID1 = const(0xDA) +ST7789_RDID2 = const(0xDB) +ST7789_RDID3 = const(0xDC) +ST7789_RDID4 = const(0xDD) +COLOR_MODE_65K = const(0x50) +COLOR_MODE_262K = const(0x60) +COLOR_MODE_12BIT = const(0x03) +COLOR_MODE_16BIT = const(0x05) +COLOR_MODE_18BIT = const(0x06) +COLOR_MODE_16M = const(0x07) +# Color definitions +BLACK = const(0x0000) +BLUE = const(0x001F) +RED = const(0xF800) +GREEN = const(0x07E0) +CYAN = const(0x07FF) +MAGENTA = const(0xF81F) +YELLOW = const(0xFFE0) +WHITE = const(0xFFFF) +_ENCODE_PIXEL = ">H" +_ENCODE_POS = ">HH" +_DECODE_PIXEL = ">BBB" +_BUFFER_SIZE = const(256) +_BIT7 = const(0x80) +_BIT6 = const(0x40) +_BIT5 = const(0x20) +_BIT4 = const(0x10) +_BIT3 = const(0x08) +_BIT2 = const(0x04) +_BIT1 = const(0x02) +_BIT0 = const(0x01) +# Rotation tables (width, height, xstart, ystart)[rotation % 4] +WIDTH_320 = [(320, 240, 0, 0), + (240, 320, 0, 0), + (320, 240, 0, 0), + (240, 320, 0, 0)] +WIDTH_240 = [(240, 240, 0, 0), + (240, 240, 0, 0), + (240, 240, 0, 80), + (240, 240, 80, 0)] +WIDTH_135 = [(135, 240, 52, 40), + (240, 135, 40, 53), + (135, 240, 53, 40), + (240, 135, 40, 52)] +# MADCTL ROTATIONS[rotation % 4] +ROTATIONS = [0x00, 0x60, 0xc0, 0xa0] +def color565(red, green=0, blue=0): + """ + Convert red, green and blue values (0-255) into a 16-bit 565 encoding. + """ + try: + red, green, blue = red # see if the first var is a tuple/list + except TypeError: + pass + return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3 +def _encode_pos(x, y): + """Encode a postion into bytes.""" + return struct.pack(_ENCODE_POS, x, y) +def _encode_pixel(color): + """Encode a pixel color into bytes.""" + return struct.pack(_ENCODE_PIXEL, color) +class ST7789(): + """ + ST7789 driver class + Args: + spi (spi): spi object + width (int): display width + height (int): display height + reset (pin): reset pin + dc (pin): dc pin + cs (pin): cs pin + backlight(pin): backlight pin + rotation (int): display rotation + - 0-Portrait + - 1-Landscape + - 2-Inverted Portrait + - 3-Inverted Landscape + """ + def __init__(self, spi, width, height, reset, dc, + cs=None, backlight=None,xstart=0,ystart=0,rotation=0): + """ + Initialize display. + """ + if height != 240 or width not in [320, 240, 135]: + raise ValueError( + "Unsupported display. 320x240, 240x240 and 135x240 are supported." + ) + self._display_width = self.width = width + self._display_height = self.height = height + self.xstart = 0 + self.ystart = 0 + self.spi = spi + self.reset = reset + self.dc = dc + self.cs = cs + self.backlight = backlight + self._rotation = rotation % 4 + self.xstart=xstart + self.ystart=ystart + self.hard_reset() + self.soft_reset() + self.sleep_mode(False) + self._set_color_mode(COLOR_MODE_65K | COLOR_MODE_16BIT) + time.sleep_ms(50) + self.rotation(self._rotation) + self.inversion_mode(True) + time.sleep_ms(10) + self._write(ST7789_NORON) + time.sleep_ms(10) + if backlight is not None: + backlight.value(1) + self.fill(0) + self._write(ST7789_DISPON) + time.sleep_ms(500) + def _write(self, command=None, data=None): + """SPI write to the device: commands and data.""" + if self.cs: + self.cs.off() + if command is not None: + self.dc.off() + self.spi.write(bytes([command])) + if data is not None: + self.dc.on() + self.spi.write(data) + if self.cs: + self.cs.on() + def hard_reset(self): + """ + Hard reset display. + """ + if self.cs: + self.cs.off() + if self.reset: + self.reset.on() + time.sleep_ms(50) + if self.reset: + self.reset.off() + time.sleep_ms(50) + if self.reset: + self.reset.on() + time.sleep_ms(150) + if self.cs: + self.cs.on() + def soft_reset(self): + """ + Soft reset display. + """ + self._write(ST7789_SWRESET) + time.sleep_ms(150) + def sleep_mode(self, value): + """ + Enable or disable display sleep mode. + Args: + value (bool): if True enable sleep mode. if False disable sleep + mode + """ + if value: + self._write(ST7789_SLPIN) + else: + self._write(ST7789_SLPOUT) + def inversion_mode(self, value): + """ + Enable or disable display inversion mode. + Args: + value (bool): if True enable inversion mode. if False disable + inversion mode + """ + if value: + self._write(ST7789_INVON) + else: + self._write(ST7789_INVOFF) + def _set_color_mode(self, mode): + """ + Set display color mode. + Args: + mode (int): color mode + COLOR_MODE_65K, COLOR_MODE_262K, COLOR_MODE_12BIT, + COLOR_MODE_16BIT, COLOR_MODE_18BIT, COLOR_MODE_16M + """ + self._write(ST7789_COLMOD, bytes([mode & 0x77])) + def rotation(self, rotation): + """ + Set display rotation. + Args: + rotation (int): + - 0-Portrait + - 1-Landscape + - 2-Inverted Portrait + - 3-Inverted Landscape + """ + rotation %= 4 + self._rotation = rotation + madctl = ROTATIONS[rotation] + if self._display_width == 320: + table = WIDTH_320 + elif self._display_width == 240: + table = WIDTH_240 + elif self._display_width == 135: + table = WIDTH_135 + else: + raise ValueError( + "Unsupported display. 320x240, 240x240 and 135x240 are supported." + ) + self.width, self.height, self.xstart, self.ystart = table[rotation] + self._write(ST7789_MADCTL, bytes([madctl])) + def _set_columns(self, start, end): + """ + Send CASET (column address set) command to display. + Args: + start (int): column start address + end (int): column end address + """ + if start <= end <= self.width: + self._write(ST7789_CASET, _encode_pos( + start+self.xstart, end + self.xstart)) + def _set_rows(self, start, end): + """ + Send RASET (row address set) command to display. + Args: + start (int): row start address + end (int): row end address + """ + if start <= end <= self.height: + self._write(ST7789_RASET, _encode_pos( + start+self.ystart, end+self.ystart)) + def _set_window(self, x0, y0, x1, y1): + """ + Set window to column and row address. + Args: + x0 (int): column start address + y0 (int): row start address + x1 (int): column end address + y1 (int): row end address + """ + self._set_columns(x0, x1) + self._set_rows(y0, y1) + self._write(ST7789_RAMWR) + def vline(self, x, y, length, color): + """ + Draw vertical line at the given location and color. + Args: + x (int): x coordinate + Y (int): y coordinate + length (int): length of line + color (int): 565 encoded color + """ + self.fill_rect(x, y, 1, length, color) + def hline(self, x, y, length, color): + """ + Draw horizontal line at the given location and color. + Args: + x (int): x coordinate + Y (int): y coordinate + length (int): length of line + color (int): 565 encoded color + """ + self.fill_rect(x, y, length, 1, color) + def pixel(self, x, y, color): + """ + Draw a pixel at the given location and color. + Args: + x (int): x coordinate + Y (int): y coordinate + color (int): 565 encoded color + """ + self._set_window(x, y, x, y) + self._write(None, _encode_pixel(color)) + def blit_buffer(self, buffer, x, y, width, height): + """ + Copy buffer to display at the given location. + Args: + buffer (bytes): Data to copy to display + x (int): Top left corner x coordinate + Y (int): Top left corner y coordinate + width (int): Width + height (int): Height + """ + self._set_window(x, y, x + width - 1, y + height - 1) + self._write(None, buffer) + def rect(self, x, y, w, h, color): + """ + Draw a rectangle at the given location, size and color. + Args: + x (int): Top left corner x coordinate + y (int): Top left corner y coordinate + width (int): Width in pixels + height (int): Height in pixels + color (int): 565 encoded color + """ + self.hline(x, y, w, color) + self.vline(x, y, h, color) + self.vline(x + w - 1, y, h, color) + self.hline(x, y + h - 1, w, color) + def fill_rect(self, x, y, width, height, color): + """ + Draw a rectangle at the given location, size and filled with color. + Args: + x (int): Top left corner x coordinate + y (int): Top left corner y coordinate + width (int): Width in pixels + height (int): Height in pixels + color (int): 565 encoded color + """ + self._set_window(x, y, x + width - 1, y + height - 1) + chunks, rest = divmod(width * height, _BUFFER_SIZE) + pixel = _encode_pixel(color) + self.dc.on() + if chunks: + data = pixel * _BUFFER_SIZE + for _ in range(chunks): + self._write(None, data) + if rest: + self._write(None, pixel * rest) + def fill(self, color): + """ + Fill the entire FrameBuffer with the specified color. + Args: + color (int): 565 encoded color + """ + self.fill_rect(0, 0, self.width, self.height, color) + def line(self, x0, y0, x1, y1, color): + """ + Draw a single pixel wide line starting at x0, y0 and ending at x1, y1. + Args: + x0 (int): Start point x coordinate + y0 (int): Start point y coordinate + x1 (int): End point x coordinate + y1 (int): End point y coordinate + color (int): 565 encoded color + """ + steep = abs(y1 - y0) > abs(x1 - x0) + if steep: + x0, y0 = y0, x0 + x1, y1 = y1, x1 + if x0 > x1: + x0, x1 = x1, x0 + y0, y1 = y1, y0 + dx = x1 - x0 + dy = abs(y1 - y0) + err = dx // 2 + if y0 < y1: + ystep = 1 + else: + ystep = -1 + while x0 <= x1: + if steep: + self.pixel(y0, x0, color) + else: + self.pixel(x0, y0, color) + err -= dy + if err < 0: + y0 += ystep + err += dx + x0 += 1 + def vscrdef(self, tfa, vsa, bfa): + """ + Set Vertical Scrolling Definition. + To scroll a 135x240 display these values should be 40, 240, 40. + There are 40 lines above the display that are not shown followed by + 240 lines that are shown followed by 40 more lines that are not shown. + You could write to these areas off display and scroll them into view by + changing the TFA, VSA and BFA values. + Args: + tfa (int): Top Fixed Area + vsa (int): Vertical Scrolling Area + bfa (int): Bottom Fixed Area + """ + struct.pack(">HHH", tfa, vsa, bfa) + self._write(ST7789_VSCRDEF, struct.pack(">HHH", tfa, vsa, bfa)) + def vscsad(self, vssa): + """ + Set Vertical Scroll Start Address of RAM. + Defines which line in the Frame Memory will be written as the first + line after the last line of the Top Fixed Area on the display + Example: + for line in range(40, 280, 1): + tft.vscsad(line) + utime.sleep(0.01) + Args: + vssa (int): Vertical Scrolling Start Address + """ + self._write(ST7789_VSCSAD, struct.pack(">H", vssa)) + def _text8(self, font, text, x0, y0, color=WHITE, background=BLACK): + """ + Internal method to write characters with width of 8 and + heights of 8 or 16. + Args: + font (module): font module to use + text (str): text to write + x0 (int): column to start drawing at + y0 (int): row to start drawing at + color (int): 565 encoded color to use for characters + background (int): 565 encoded color to use for background + """ + for char in text: + ch = ord(char) + if (font.FIRST <= ch < font.LAST + and x0+font.WIDTH <= self.width + and y0+font.HEIGHT <= self.height): + if font.HEIGHT == 8: + passes = 1 + size = 8 + each = 0 + else: + passes = 2 + size = 16 + each = 8 + for line in range(passes): + idx = (ch-font.FIRST)*size+(each*line) + buffer = struct.pack( + '>64H', + color if font.FONT[idx] & _BIT7 else background, + color if font.FONT[idx] & _BIT6 else background, + color if font.FONT[idx] & _BIT5 else background, + color if font.FONT[idx] & _BIT4 else background, + color if font.FONT[idx] & _BIT3 else background, + color if font.FONT[idx] & _BIT2 else background, + color if font.FONT[idx] & _BIT1 else background, + color if font.FONT[idx] & _BIT0 else background, + color if font.FONT[idx+1] & _BIT7 else background, + color if font.FONT[idx+1] & _BIT6 else background, + color if font.FONT[idx+1] & _BIT5 else background, + color if font.FONT[idx+1] & _BIT4 else background, + color if font.FONT[idx+1] & _BIT3 else background, + color if font.FONT[idx+1] & _BIT2 else background, + color if font.FONT[idx+1] & _BIT1 else background, + color if font.FONT[idx+1] & _BIT0 else background, + color if font.FONT[idx+2] & _BIT7 else background, + color if font.FONT[idx+2] & _BIT6 else background, + color if font.FONT[idx+2] & _BIT5 else background, + color if font.FONT[idx+2] & _BIT4 else background, + color if font.FONT[idx+2] & _BIT3 else background, + color if font.FONT[idx+2] & _BIT2 else background, + color if font.FONT[idx+2] & _BIT1 else background, + color if font.FONT[idx+2] & _BIT0 else background, + color if font.FONT[idx+3] & _BIT7 else background, + color if font.FONT[idx+3] & _BIT6 else background, + color if font.FONT[idx+3] & _BIT5 else background, + color if font.FONT[idx+3] & _BIT4 else background, + color if font.FONT[idx+3] & _BIT3 else background, + color if font.FONT[idx+3] & _BIT2 else background, + color if font.FONT[idx+3] & _BIT1 else background, + color if font.FONT[idx+3] & _BIT0 else background, + color if font.FONT[idx+4] & _BIT7 else background, + color if font.FONT[idx+4] & _BIT6 else background, + color if font.FONT[idx+4] & _BIT5 else background, + color if font.FONT[idx+4] & _BIT4 else background, + color if font.FONT[idx+4] & _BIT3 else background, + color if font.FONT[idx+4] & _BIT2 else background, + color if font.FONT[idx+4] & _BIT1 else background, + color if font.FONT[idx+4] & _BIT0 else background, + color if font.FONT[idx+5] & _BIT7 else background, + color if font.FONT[idx+5] & _BIT6 else background, + color if font.FONT[idx+5] & _BIT5 else background, + color if font.FONT[idx+5] & _BIT4 else background, + color if font.FONT[idx+5] & _BIT3 else background, + color if font.FONT[idx+5] & _BIT2 else background, + color if font.FONT[idx+5] & _BIT1 else background, + color if font.FONT[idx+5] & _BIT0 else background, + color if font.FONT[idx+6] & _BIT7 else background, + color if font.FONT[idx+6] & _BIT6 else background, + color if font.FONT[idx+6] & _BIT5 else background, + color if font.FONT[idx+6] & _BIT4 else background, + color if font.FONT[idx+6] & _BIT3 else background, + color if font.FONT[idx+6] & _BIT2 else background, + color if font.FONT[idx+6] & _BIT1 else background, + color if font.FONT[idx+6] & _BIT0 else background, + color if font.FONT[idx+7] & _BIT7 else background, + color if font.FONT[idx+7] & _BIT6 else background, + color if font.FONT[idx+7] & _BIT5 else background, + color if font.FONT[idx+7] & _BIT4 else background, + color if font.FONT[idx+7] & _BIT3 else background, + color if font.FONT[idx+7] & _BIT2 else background, + color if font.FONT[idx+7] & _BIT1 else background, + color if font.FONT[idx+7] & _BIT0 else background + ) + self.blit_buffer(buffer, x0, y0+8*line, 8, 8) + x0 += 8 + def _text16(self, font, text, x0, y0, color=WHITE, background=BLACK): + """ + Internal method to draw characters with width of 16 and heights of 16 + or 32. + Args: + font (module): font module to use + text (str): text to write + x0 (int): column to start drawing at + y0 (int): row to start drawing at + color (int): 565 encoded color to use for characters + background (int): 565 encoded color to use for background + """ + for char in text: + ch = ord(char) + if (font.FIRST <= ch < font.LAST + and x0+font.WIDTH <= self.width + and y0+font.HEIGHT <= self.height): + if font.HEIGHT == 16: + passes = 2 + size = 32 + each = 16 + else: + passes = 4 + size = 64 + each = 16 + for line in range(passes): + idx = (ch-font.FIRST)*size+(each*line) + buffer = struct.pack( + '>128H', + color if font.FONT[idx] & _BIT7 else background, + color if font.FONT[idx] & _BIT6 else background, + color if font.FONT[idx] & _BIT5 else background, + color if font.FONT[idx] & _BIT4 else background, + color if font.FONT[idx] & _BIT3 else background, + color if font.FONT[idx] & _BIT2 else background, + color if font.FONT[idx] & _BIT1 else background, + color if font.FONT[idx] & _BIT0 else background, + color if font.FONT[idx+1] & _BIT7 else background, + color if font.FONT[idx+1] & _BIT6 else background, + color if font.FONT[idx+1] & _BIT5 else background, + color if font.FONT[idx+1] & _BIT4 else background, + color if font.FONT[idx+1] & _BIT3 else background, + color if font.FONT[idx+1] & _BIT2 else background, + color if font.FONT[idx+1] & _BIT1 else background, + color if font.FONT[idx+1] & _BIT0 else background, + color if font.FONT[idx+2] & _BIT7 else background, + color if font.FONT[idx+2] & _BIT6 else background, + color if font.FONT[idx+2] & _BIT5 else background, + color if font.FONT[idx+2] & _BIT4 else background, + color if font.FONT[idx+2] & _BIT3 else background, + color if font.FONT[idx+2] & _BIT2 else background, + color if font.FONT[idx+2] & _BIT1 else background, + color if font.FONT[idx+2] & _BIT0 else background, + color if font.FONT[idx+3] & _BIT7 else background, + color if font.FONT[idx+3] & _BIT6 else background, + color if font.FONT[idx+3] & _BIT5 else background, + color if font.FONT[idx+3] & _BIT4 else background, + color if font.FONT[idx+3] & _BIT3 else background, + color if font.FONT[idx+3] & _BIT2 else background, + color if font.FONT[idx+3] & _BIT1 else background, + color if font.FONT[idx+3] & _BIT0 else background, + color if font.FONT[idx+4] & _BIT7 else background, + color if font.FONT[idx+4] & _BIT6 else background, + color if font.FONT[idx+4] & _BIT5 else background, + color if font.FONT[idx+4] & _BIT4 else background, + color if font.FONT[idx+4] & _BIT3 else background, + color if font.FONT[idx+4] & _BIT2 else background, + color if font.FONT[idx+4] & _BIT1 else background, + color if font.FONT[idx+4] & _BIT0 else background, + color if font.FONT[idx+5] & _BIT7 else background, + color if font.FONT[idx+5] & _BIT6 else background, + color if font.FONT[idx+5] & _BIT5 else background, + color if font.FONT[idx+5] & _BIT4 else background, + color if font.FONT[idx+5] & _BIT3 else background, + color if font.FONT[idx+5] & _BIT2 else background, + color if font.FONT[idx+5] & _BIT1 else background, + color if font.FONT[idx+5] & _BIT0 else background, + color if font.FONT[idx+6] & _BIT7 else background, + color if font.FONT[idx+6] & _BIT6 else background, + color if font.FONT[idx+6] & _BIT5 else background, + color if font.FONT[idx+6] & _BIT4 else background, + color if font.FONT[idx+6] & _BIT3 else background, + color if font.FONT[idx+6] & _BIT2 else background, + color if font.FONT[idx+6] & _BIT1 else background, + color if font.FONT[idx+6] & _BIT0 else background, + color if font.FONT[idx+7] & _BIT7 else background, + color if font.FONT[idx+7] & _BIT6 else background, + color if font.FONT[idx+7] & _BIT5 else background, + color if font.FONT[idx+7] & _BIT4 else background, + color if font.FONT[idx+7] & _BIT3 else background, + color if font.FONT[idx+7] & _BIT2 else background, + color if font.FONT[idx+7] & _BIT1 else background, + color if font.FONT[idx+7] & _BIT0 else background, + color if font.FONT[idx+8] & _BIT7 else background, + color if font.FONT[idx+8] & _BIT6 else background, + color if font.FONT[idx+8] & _BIT5 else background, + color if font.FONT[idx+8] & _BIT4 else background, + color if font.FONT[idx+8] & _BIT3 else background, + color if font.FONT[idx+8] & _BIT2 else background, + color if font.FONT[idx+8] & _BIT1 else background, + color if font.FONT[idx+8] & _BIT0 else background, + color if font.FONT[idx+9] & _BIT7 else background, + color if font.FONT[idx+9] & _BIT6 else background, + color if font.FONT[idx+9] & _BIT5 else background, + color if font.FONT[idx+9] & _BIT4 else background, + color if font.FONT[idx+9] & _BIT3 else background, + color if font.FONT[idx+9] & _BIT2 else background, + color if font.FONT[idx+9] & _BIT1 else background, + color if font.FONT[idx+9] & _BIT0 else background, + color if font.FONT[idx+10] & _BIT7 else background, + color if font.FONT[idx+10] & _BIT6 else background, + color if font.FONT[idx+10] & _BIT5 else background, + color if font.FONT[idx+10] & _BIT4 else background, + color if font.FONT[idx+10] & _BIT3 else background, + color if font.FONT[idx+10] & _BIT2 else background, + color if font.FONT[idx+10] & _BIT1 else background, + color if font.FONT[idx+10] & _BIT0 else background, + color if font.FONT[idx+11] & _BIT7 else background, + color if font.FONT[idx+11] & _BIT6 else background, + color if font.FONT[idx+11] & _BIT5 else background, + color if font.FONT[idx+11] & _BIT4 else background, + color if font.FONT[idx+11] & _BIT3 else background, + color if font.FONT[idx+11] & _BIT2 else background, + color if font.FONT[idx+11] & _BIT1 else background, + color if font.FONT[idx+11] & _BIT0 else background, + color if font.FONT[idx+12] & _BIT7 else background, + color if font.FONT[idx+12] & _BIT6 else background, + color if font.FONT[idx+12] & _BIT5 else background, + color if font.FONT[idx+12] & _BIT4 else background, + color if font.FONT[idx+12] & _BIT3 else background, + color if font.FONT[idx+12] & _BIT2 else background, + color if font.FONT[idx+12] & _BIT1 else background, + color if font.FONT[idx+12] & _BIT0 else background, + color if font.FONT[idx+13] & _BIT7 else background, + color if font.FONT[idx+13] & _BIT6 else background, + color if font.FONT[idx+13] & _BIT5 else background, + color if font.FONT[idx+13] & _BIT4 else background, + color if font.FONT[idx+13] & _BIT3 else background, + color if font.FONT[idx+13] & _BIT2 else background, + color if font.FONT[idx+13] & _BIT1 else background, + color if font.FONT[idx+13] & _BIT0 else background, + color if font.FONT[idx+14] & _BIT7 else background, + color if font.FONT[idx+14] & _BIT6 else background, + color if font.FONT[idx+14] & _BIT5 else background, + color if font.FONT[idx+14] & _BIT4 else background, + color if font.FONT[idx+14] & _BIT3 else background, + color if font.FONT[idx+14] & _BIT2 else background, + color if font.FONT[idx+14] & _BIT1 else background, + color if font.FONT[idx+14] & _BIT0 else background, + color if font.FONT[idx+15] & _BIT7 else background, + color if font.FONT[idx+15] & _BIT6 else background, + color if font.FONT[idx+15] & _BIT5 else background, + color if font.FONT[idx+15] & _BIT4 else background, + color if font.FONT[idx+15] & _BIT3 else background, + color if font.FONT[idx+15] & _BIT2 else background, + color if font.FONT[idx+15] & _BIT1 else background, + color if font.FONT[idx+15] & _BIT0 else background + ) + self.blit_buffer(buffer, x0, y0+8*line, 16, 8) + x0 += font.WIDTH + def text(self, font, text, x0, y0, color=WHITE, background=BLACK): + """ + Draw text on display in specified font and colors. 8 and 16 bit wide + fonts are supported. + Args: + font (module): font module to use. + text (str): text to write + x0 (int): column to start drawing at + y0 (int): row to start drawing at + color (int): 565 encoded color to use for characters + background (int): 565 encoded color to use for background + """ + if font.WIDTH == 8: + self._text8(font, text, x0, y0, color, background) + else: + self._text16(font, text, x0, y0, color, background) + def bitmap(self, bitmap, x, y, index=0): + """ + Draw a bitmap on display at the specified column and row + Args: + bitmap (bitmap_module): The module containing the bitmap to draw + x (int): column to start drawing at + y (int): row to start drawing at + index (int): Optional index of bitmap to draw from multiple bitmap + module + """ + bitmap_size = bitmap.HEIGHT * bitmap.WIDTH + buffer_len = bitmap_size * 2 + buffer = bytearray(buffer_len) + bs_bit = bitmap.BPP * bitmap_size * index if index > 0 else 0 + for i in range(0, buffer_len, 2): + color_index = 0 + for bit in range(bitmap.BPP): + color_index <<= 1 + color_index |= (bitmap.BITMAP[bs_bit // 8] + & 1 << (7 - (bs_bit % 8))) > 0 + bs_bit += 1 + color = bitmap.PALETTE[color_index] + buffer[i] = color & 0xff00 >> 8 + buffer[i + 1] = color_index & 0xff + to_col = x + bitmap.WIDTH - 1 + to_row = y + bitmap.HEIGHT - 1 + if self.width > to_col and self.height > to_row: + self._set_window(x, y, to_col, to_row) + self._write(None, buffer) + # @micropython.native + def write(self, font, string, x, y, fg=WHITE, bg=BLACK): + """ + Write a string using a converted true-type font on the display starting + at the specified column and row + Args: + font (font): The module containing the converted true-type font + s (string): The string to write + x (int): column to start writing + y (int): row to start writing + fg (int): foreground color, optional, defaults to WHITE + bg (int): background color, optional, defaults to BLACK + """ + buffer_len = font.HEIGHT * font.MAX_WIDTH * 2 + buffer = bytearray(buffer_len) + fg_hi = (fg & 0xff00) >> 8 + fg_lo = fg & 0xff + bg_hi = (bg & 0xff00) >> 8 + bg_lo = bg & 0xff + for character in string: + try: + char_index = font.MAP.index(character) + offset = char_index * font.OFFSET_WIDTH + bs_bit = font.OFFSETS[offset] + if font.OFFSET_WIDTH > 1: + bs_bit = (bs_bit << 8) + font.OFFSETS[offset + 1] + if font.OFFSET_WIDTH > 2: + bs_bit = (bs_bit << 8) + font.OFFSETS[offset + 2] + char_width = font.WIDTHS[char_index] + buffer_needed = char_width * font.HEIGHT * 2 + for i in range(0, buffer_needed, 2): + if font.BITMAPS[bs_bit // 8] & 1 << (7 - (bs_bit % 8)) > 0: + buffer[i] = fg_hi + buffer[i + 1] = fg_lo + else: + buffer[i] = bg_hi + buffer[i + 1] = bg_lo + bs_bit += 1 + to_col = x + char_width - 1 + to_row = y + font.HEIGHT - 1 + if self.width > to_col and self.height > to_row: + self._set_window(x, y, to_col, to_row) + self._write(None, buffer[0:buffer_needed]) + x += char_width + except ValueError: + pass + def write_width(self, font, string): + """ + Returns the width in pixels of the string if it was written with the + specified font + Args: + font (font): The module containing the converted true-type font + string (string): The string to measure + """ + width = 0 + for character in string: + try: + char_index = font.MAP.index(character) + width += font.WIDTHS[char_index] + except ValueError: + pass + return width \ No newline at end of file diff --git a/temperature.py b/temperature.py new file mode 100644 index 0000000..31ad912 --- /dev/null +++ b/temperature.py @@ -0,0 +1,29 @@ +import time +import machine +import dht +import random +from picographics import PicoGraphics, DISPLAY_PICO_EXPLORER, PEN_P8 + +sensor = dht.DHT11(machine.Pin(2)) + +display = PicoGraphics(display=DISPLAY_PICO_EXPLORER, pen_type=PEN_P8) + +WIDTH, HEIGHT = display.get_bounds() +BLACK = display.create_pen(0, 0, 0) +WHITE = display.create_pen(255, 255, 255) + + + +while True: + try: + time.sleep(2) + sensor.measure() + t = sensor.temperature() + h = sensor.humidity() + display.set_pen(WHITE) + display.text(f"Temp: {t} C \nHumidity: {h} %", 10, 10, 240, 4) + display.update() + print('Temperature: %3.1f C' %t) + print('Humidity: %3.1f %%' %h) + except OSError as e: + print('Sensor Reading Failed') \ No newline at end of file