MicroPython: SSD1306 OLED-дисплей — функции прокрутки и рисование фигур (ESP32/ESP8266)
В этом руководстве показаны дополнительные функции для управления OLED-дисплеем на MicroPython с использованием ESP32 или ESP8266. Вы узнаете, как прокручивать весь экран по горизонтали и вертикали, а также как рисовать фигуры.
Мы рекомендуем сначала ознакомиться с начальным руководством по работе с OLED-дисплеем на MicroPython: MicroPython: OLED-дисплей с ESP32 и ESP8266.
Необходимые условия
Для выполнения этого руководства вам необходимо установить прошивку MicroPython на плату ESP32 или ESP8266. Также вам нужна IDE для написания и загрузки кода на плату. Мы рекомендуем использовать Thonny IDE или uPyCraft IDE:
Thonny IDE:
uPyCraft IDE:
Необходимые компоненты
Список компонентов для этого урока:
ESP32 или ESP8266
OLED-дисплей 0.96 дюйма (SSD1306, 128x64)
Макетная плата
Соединительные провода
Схема подключения — ESP32
Используйте следующую схему подключения, если вы работаете с платой ESP32:
Рекомендуемое чтение: Справочник по выводам ESP32
Схема подключения — ESP8266 NodeMCU
Используйте следующую схему подключения, если вы работаете с платой ESP8266 NodeMCU:
Библиотека SSD1306 OLED
Библиотека для записи на OLED-дисплей не входит в стандартную библиотеку MicroPython по умолчанию. Поэтому вам необходимо загрузить библиотеку на плату ESP32/ESP8266.
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces created by Adafruit
import time
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
# Note the subclass must initialize self.framebuf to a framebuffer.
# This is necessary because the underlying data buffer is different
# between I2C and SPI implementations (I2C needs an extra byte).
self.poweron()
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
SET_VCOM_DESEL, 0x30, # 0.83*Vcc
# display
SET_CONTRAST, 0xff, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_framebuf()
def fill(self, col):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
# Add an extra byte to the data buffer to hold an I2C data/command byte
# to use hardware-compatible I2C transactions. A memoryview of the
# buffer is used to mask this byte from the framebuffer operations
# (without a major memory hit as memoryview doesn't copy to a separate
# buffer).
self.buffer = bytearray(((height // 8) * width) + 1)
self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_framebuf(self):
# Blast out the frame buffer using a single I2C transaction to support
# hardware I2C interfaces.
self.i2c.writeto(self.addr, self.buffer)
def poweron(self):
pass
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
self.buffer = bytearray((height // 8) * width)
self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()
def write_framebuf(self):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(self.buffer)
self.cs.high()
def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()
Следуйте приведённым ниже инструкциям для вашей IDE:
Загрузка библиотеки OLED с помощью uPyCraft IDE
Загрузка библиотеки OLED с помощью Thonny IDE
A. Загрузка библиотеки OLED с помощью uPyCraft IDE
В этом разделе показано, как загрузить библиотеку с помощью uPyCraft IDE. Если вы используете Thonny IDE, перейдите к следующему разделу.
1. Создайте новый файл, нажав кнопку New File.
2. Скопируйте код библиотеки OLED в этот файл. Код библиотеки OLED можно найти здесь.
Примечание
Библиотека SSD1306 OLED-дисплея была создана Adafruit и больше не обновляется. На данный момент она работает нормально. Однако мы обновим это руководство, если найдём аналогичную библиотеку, которая работает так же хорошо.
3. После копирования кода сохраните файл, нажав кнопку Save.
4. Назовите новый файл ssd1306.py и нажмите ok.
5. Нажмите кнопку Download and Run.
Файл должен быть сохранён в папке устройства с именем ssd1306.py, как показано на следующем изображении.
Теперь вы можете использовать функции библиотеки в своём коде, импортировав библиотеку.
B. Загрузка библиотеки OLED с помощью Thonny IDE
Если вы используете Thonny IDE, выполните следующие шаги:
1. Скопируйте код библиотеки в новый файл. Код библиотеки OLED можно найти здесь.
2. Сохраните этот файл как ssd1306.py.
3. Перейдите в Device > Upload current script with the current name.
Вот и всё. Библиотека загружена на вашу плату. Чтобы убедиться, что она успешно загружена, в Shell вы можете ввести:
%lsdevice
Должен отобразиться список файлов, сохранённых на вашей плате. Один из них должен быть файлом ssd1306.py.
После загрузки библиотеки на плату вы можете использовать функции библиотеки в своём коде, импортировав библиотеку.
Функции прокрутки OLED на MicroPython
Библиотека ssd1306.py содержит функцию scroll(x, y). Она прокручивает экран на x пикселей вправо и y пикселей вниз.
Горизонтальная прокрутка экрана OLED
Иногда нужно отображать разные экраны на OLED-дисплее. Например, первый экран показывает показания датчиков, а второй — состояния GPIO.
Прокрутка экрана внутрь по горизонтали
Следующая функция scroll_in_screen(screen) прокручивает содержимое всего экрана (справа налево).
def scroll_in_screen(screen):
for i in range (0, oled_width+1, 4):
for line in screen:
oled.text(line[2], -oled_width+i, line[1])
oled.show()
if i!= oled_width:
oled.fill(0)
Эта функция принимает в качестве аргумента список списков. Например:
screen1 = [[0, 0 , screen1_row1], [0, 16, screen1_row2], [0, 32, screen1_row3]]
Каждый список в списке содержит координату x, координату y и сообщение [x, y, message].
В качестве примера мы отобразим три строки на первом экране со следующими сообщениями:
screen1_row1 = "Screen 1, row 1"
screen1_row2 = "Screen 1, row 2"
screen1_row3 = "Screen 1, row 3"
Затем, чтобы прокрутить экран слева направо, просто вызовите функцию scroll_in_screen() и передайте в качестве аргумента список списков:
scroll_in_screen(screen1)
Вы получите примерно следующее:
Прокрутка экрана наружу по горизонтали
Чтобы прокрутить экран наружу, используйте функцию scroll_out_screen(speed), которая прокручивает весь экран за пределы OLED. Она принимает в качестве аргумента число, управляющее скоростью прокрутки. Скорость должна быть делителем 128 (oled_width).
def scroll_out_screen(speed):
for i in range ((oled_width+1)/speed):
for j in range (oled_height):
oled.pixel(i, j, 0)
oled.scroll(speed,0)
oled.show()
Теперь вы можете использовать обе функции для переключения между экранами. Например:
scroll_in_screen(screen1)
scroll_out_screen(4)
scroll_in_screen(screen2)
scroll_out_screen(4)
Непрерывная горизонтальная прокрутка
Если вы хотите непрерывно прокручивать экран внутрь и наружу, используйте функцию scroll_screen_in_out(screen).
def scroll_screen_in_out(screen):
for i in range (0, (oled_width+1)*2, 1):
for line in screen:
oled.text(line[2], -oled_width+i, line[1])
oled.show()
if i!= oled_width:
oled.fill(0)
Вы можете использовать эту функцию для переключения между экранами или для непрерывной прокрутки одного и того же экрана.
scroll_screen_in_out(screen1)
scroll_screen_in_out(screen2)
scroll_screen_in_out(screen3)
Вертикальная прокрутка экрана OLED
Мы также создали аналогичные функции для вертикальной прокрутки экрана.
Прокрутка экрана внутрь по вертикали
Функция scroll_in_screen_v(screen) прокручивает содержимое всего экрана по вертикали.
def scroll_in_screen_v(screen):
for i in range (0, (oled_height+1), 1):
for line in screen:
oled.text(line[2], line[0], -oled_height+i+line[1])
oled.show()
if i!= oled_height:
oled.fill(0)
Прокрутка экрана наружу по вертикали
Используйте функцию scroll_out_screen_v(speed) для вертикальной прокрутки экрана наружу. Аналогично горизонтальной функции, она принимает в качестве аргумента скорость прокрутки, которая должна быть делителем 64 (oled_height).
def scroll_out_screen_v(speed):
for i in range ((oled_height+1)/speed):
for j in range (oled_width):
oled.pixel(j, i, 0)
oled.scroll(0,speed)
oled.show()
Непрерывная вертикальная прокрутка
Если вы хотите непрерывно прокручивать экран внутрь и наружу по вертикали, используйте функцию scroll_screen_in_out_v(screen).
def scroll_screen_in_out_v(screen):
for i in range (0, (oled_height*2+1), 1):
for line in screen:
oled.text(line[2], line[0], -oled_height+i+line[1])
oled.show()
if i!= oled_height:
oled.fill(0)
Полный скрипт прокрутки экрана OLED на MicroPython
Следующий скрипт применяет все функции прокрутки, описанные выше. Вы можете загрузить этот код на свою плату, чтобы увидеть все эффекты прокрутки.
# Полный проект: https://RandomNerdTutorials.com/micropython-ssd1306-oled-scroll-shapes-esp32-esp8266/
from machine import Pin, SoftI2C
import ssd1306
from time import sleep
# Назначение выводов ESP32
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
# Назначение выводов ESP8266
#i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
screen1_row1 = "Screen 1, row 1"
screen1_row2 = "Screen 1, row 2"
screen1_row3 = "Screen 1, row 3"
screen2_row1 = "Screen 2, row 1"
screen2_row2 = "Screen 2, row 2"
screen3_row1 = "Screen 3, row 1"
screen1 = [[0, 0 , screen1_row1], [0, 16, screen1_row2], [0, 32, screen1_row3]]
screen2 = [[0, 0 , screen2_row1], [0, 16, screen2_row2]]
screen3 = [[0, 40 , screen3_row1]]
# Горизонтальная прокрутка экрана внутрь (слева направо)
def scroll_in_screen(screen):
for i in range (0, oled_width+1, 4):
for line in screen:
oled.text(line[2], -oled_width+i, line[1])
oled.show()
if i!= oled_width:
oled.fill(0)
# Горизонтальная прокрутка экрана наружу (слева направо)
def scroll_out_screen(speed):
for i in range ((oled_width+1)/speed):
for j in range (oled_height):
oled.pixel(i, j, 0)
oled.scroll(speed,0)
oled.show()
# Непрерывная горизонтальная прокрутка
def scroll_screen_in_out(screen):
for i in range (0, (oled_width+1)*2, 1):
for line in screen:
oled.text(line[2], -oled_width+i, line[1])
oled.show()
if i!= oled_width:
oled.fill(0)
# Вертикальная прокрутка экрана внутрь
def scroll_in_screen_v(screen):
for i in range (0, (oled_height+1), 1):
for line in screen:
oled.text(line[2], line[0], -oled_height+i+line[1])
oled.show()
if i!= oled_height:
oled.fill(0)
# Вертикальная прокрутка экрана наружу
def scroll_out_screen_v(speed):
for i in range ((oled_height+1)/speed):
for j in range (oled_width):
oled.pixel(j, i, 0)
oled.scroll(0,speed)
oled.show()
# Непрерывная вертикальная прокрутка
def scroll_screen_in_out_v(screen):
for i in range (0, (oled_height*2+1), 1):
for line in screen:
oled.text(line[2], line[0], -oled_height+i+line[1])
oled.show()
if i!= oled_height:
oled.fill(0)
while True:
# Прокрутка внутрь, пауза, прокрутка наружу (горизонтальная)
scroll_in_screen(screen1)
sleep(2)
scroll_out_screen(4)
scroll_in_screen(screen2)
sleep(2)
scroll_out_screen(4)
scroll_in_screen(screen3)
sleep(2)
scroll_out_screen(4)
# Непрерывная горизонтальная прокрутка
scroll_screen_in_out(screen1)
scroll_screen_in_out(screen2)
scroll_screen_in_out(screen3)
# Прокрутка внутрь, пауза, прокрутка наружу (вертикальная)
scroll_in_screen_v(screen1)
sleep(2)
scroll_out_screen_v(4)
scroll_in_screen_v(screen2)
sleep(2)
scroll_out_screen_v(4)
scroll_in_screen_v(screen3)
sleep(2)
scroll_out_screen_v(4)
# Непрерывная вертикальная прокрутка
scroll_screen_in_out_v(screen1)
scroll_screen_in_out_v(screen2)
scroll_screen_in_out_v(screen3)
Рисование фигур на OLED с помощью MicroPython
Для рисования фигур на OLED-дисплее с помощью MicroPython мы будем использовать библиотеку Adafruit GFX для MicroPython.
Библиотека Adafruit GFX
Для рисования фигур на OLED-дисплее мы будем использовать библиотеку Adafruit GFX. Эта библиотека не входит в стандартную библиотеку MicroPython по умолчанию. Поэтому вам необходимо загрузить библиотеку на плату ESP32/ESP8266.
# Port of Adafruit GFX Arduino library to MicroPython.
# Based on: https://github.com/adafruit/Adafruit-GFX-Library
# Author: Tony DiCola (original GFX author Phil Burgess)
# License: MIT License (https://opensource.org/licenses/MIT)
class GFX:
def __init__(self, width, height, pixel, hline=None, vline=None):
# Create an instance of the GFX drawing class. You must pass in the
# following parameters:
# - width = The width of the drawing area in pixels.
# - height = The height of the drawing area in pixels.
# - pixel = A function to call when a pixel is drawn on the display.
# This function should take at least an x and y position
# and then any number of optional color or other parameters.
# You can also provide the following optional keyword argument to
# improve the performance of drawing:
# - hline = A function to quickly draw a horizontal line on the display.
# This should take at least an x, y, and width parameter and
# any number of optional color or other parameters.
# - vline = A function to quickly draw a vertical line on the display.
# This should take at least an x, y, and height paraemter and
# any number of optional color or other parameters.
self.width = width
self.height = height
self._pixel = pixel
# Default to slow horizontal & vertical line implementations if no
# faster versions are provided.
if hline is None:
self.hline = self._slow_hline
else:
self.hline = hline
if vline is None:
self.vline = self._slow_vline
else:
self.vline = vline
def _slow_hline(self, x0, y0, width, *args, **kwargs):
if y0 < 0 or y0 > self.height or x0 < -width or x0 > self.width:
return
for i in range(width):
self._pixel(x0+i, y0, *args, **kwargs)
def _slow_vline(self, x0, y0, height, *args, **kwargs):
if y0 < -height or y0 > self.height or x0 < 0 or x0 > self.width:
return
for i in range(height):
self._pixel(x0, y0+i, *args, **kwargs)
def rect(self, x0, y0, width, height, *args, **kwargs):
if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width:
return
self.hline(x0, y0, width, *args, **kwargs)
self.hline(x0, y0+height-1, width, *args, **kwargs)
self.vline(x0, y0, height, *args, **kwargs)
self.vline(x0+width-1, y0, height, *args, **kwargs)
def fill_rect(self, x0, y0, width, height, *args, **kwargs):
if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width:
return
for i in range(x0, x0+width):
self.vline(i, y0, height, *args, **kwargs)
def line(self, x0, y0, x1, y1, *args, **kwargs):
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
ystep = 0
if y0 < y1:
ystep = 1
else:
ystep = -1
while x0 <= x1:
if steep:
self._pixel(y0, x0, *args, **kwargs)
else:
self._pixel(x0, y0, *args, **kwargs)
err -= dy
if err < 0:
y0 += ystep
err += dx
x0 += 1
def circle(self, x0, y0, radius, *args, **kwargs):
f = 1 - radius
ddF_x = 1
ddF_y = -2 * radius
x = 0
y = radius
self._pixel(x0, y0 + radius, *args, **kwargs)
self._pixel(x0, y0 - radius, *args, **kwargs)
self._pixel(x0 + radius, y0, *args, **kwargs)
self._pixel(x0 - radius, y0, *args, **kwargs)
while x < y:
if f >= 0:
y -= 1
ddF_y += 2
f += ddF_y
x += 1
ddF_x += 2
f += ddF_x
self._pixel(x0 + x, y0 + y, *args, **kwargs)
self._pixel(x0 - x, y0 + y, *args, **kwargs)
self._pixel(x0 + x, y0 - y, *args, **kwargs)
self._pixel(x0 - x, y0 - y, *args, **kwargs)
self._pixel(x0 + y, y0 + x, *args, **kwargs)
self._pixel(x0 - y, y0 + x, *args, **kwargs)
self._pixel(x0 + y, y0 - x, *args, **kwargs)
self._pixel(x0 - y, y0 - x, *args, **kwargs)
def fill_circle(self, x0, y0, radius, *args, **kwargs):
self.vline(x0, y0 - radius, 2*radius + 1, *args, **kwargs)
f = 1 - radius
ddF_x = 1
ddF_y = -2 * radius
x = 0
y = radius
while x < y:
if f >= 0:
y -= 1
ddF_y += 2
f += ddF_y
x += 1
ddF_x += 2
f += ddF_x
self.vline(x0 + x, y0 - y, 2*y + 1, *args, **kwargs)
self.vline(x0 + y, y0 - x, 2*x + 1, *args, **kwargs)
self.vline(x0 - x, y0 - y, 2*y + 1, *args, **kwargs)
self.vline(x0 - y, y0 - x, 2*x + 1, *args, **kwargs)
def triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs):
self.line(x0, y0, x1, y1, *args, **kwargs)
self.line(x1, y1, x2, y2, *args, **kwargs)
self.line(x2, y2, x0, y0, *args, **kwargs)
def fill_triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs):
if y0 > y1:
y0, y1 = y1, y0
x0, x1 = x1, x0
if y1 > y2:
y2, y1 = y1, y2
x2, x1 = x1, x2
if y0 > y1:
y0, y1 = y1, y0
x0, x1 = x1, x0
a = 0
b = 0
y = 0
last = 0
if y0 == y2:
a = x0
b = x0
if x1 < a:
a = x1
elif x1 > b:
b = x1
if x2 < a:
a = x2
elif x2 > b:
b = x2
self.hline(a, y0, b-a+1, *args, **kwargs)
return
dx01 = x1 - x0
dy01 = y1 - y0
dx02 = x2 - x0
dy02 = y2 - y0
dx12 = x2 - x1
dy12 = y2 - y1
if dy01 == 0:
dy01 = 1
if dy02 == 0:
dy02 = 1
if dy12 == 0:
dy12 = 1
sa = 0
sb = 0
if y1 == y2:
last = y1
else:
last = y1-1
for y in range(y0, last+1):
a = x0 + sa // dy01
b = x0 + sb // dy02
sa += dx01
sb += dx02
if a > b:
a, b = b, a
self.hline(a, y, b-a+1, *args, **kwargs)
sa = dx12 * (y - y1)
sb = dx02 * (y - y0)
while y <= y2:
a = x1 + sa // dy12
b = x0 + sb // dy02
sa += dx12
sb += dx02
if a > b:
a, b = b, a
self.hline(a, y, b-a+1, *args, **kwargs)
y += 1
Следуйте предыдущим инструкциям по установке библиотеки, но для библиотеки GFX. Сохраните файл библиотеки GFX как gfx.py. После этого вы сможете использовать функции библиотеки, импортировав её в свой код.
Итак, вот как рисовать фигуры. Сначала нужно подключить библиотеки ssd1306 и gfx, а также модули Pin и SoftI2C.
from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import gfx
Затем определите выводы для ESP32:
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
Если вы используете ESP8266, используйте следующие выводы:
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
Мы используем OLED-дисплей 128x64. Если вы используете OLED-дисплей с другими размерами, измените следующие строки:
oled_width = 128
oled_height = 64
Создайте объект ssd1306 с именем oled:
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
Затем нужно создать объект gfx для рисования фигур. В данном случае он называется graphics. Он принимает в качестве аргументов ширину и высоту области рисования. В нашем случае мы хотим рисовать на всём OLED, поэтому передаём ширину и высоту OLED. Также нужно передать функцию дисплея, которая рисует пиксели — в нашем случае это oled.pixel.
graphics = gfx.GFX(oled_width, oled_height, oled.pixel)
После этого вы можете использовать функции рисования, показанные далее, для отображения фигур.
Рисование линии
Используйте метод line(x0, y0, x1, y1, color) объекта gfx для создания линии. Координаты (x0, y0) указывают начало линии, а координаты (x1, y1) — конец. Не забывайте вызывать oled.show() для фактического отображения фигур на OLED. Пример:
graphics.line(0, 0, 127, 20, 1)
oled.show()
Прямоугольник
Для рисования прямоугольника используйте метод rect(x0, y0, width, height, color) объекта gfx. Координаты (x0, y0) указывают верхний левый угол прямоугольника. Затем нужно указать ширину, высоту и цвет. Пример:
graphics.rect(10, 10, 50, 30, 1)
oled.show()
Закрашенный прямоугольник
Используйте метод fill_rect(x0, y0, width, height, color) для рисования закрашенного прямоугольника. Этот метод принимает те же аргументы, что и rect().
graphics.fill_rect(10, 10, 50, 30, 1)
oled.show()
Круг
Нарисуйте круг с помощью метода circle(x0, y0, radius, color). Координаты (x0, y0) указывают центр круга. Пример:
graphics.circle(64, 32, 10, 1)
oled.show()
Закрашенный круг
Нарисуйте закрашенный круг с помощью метода fill_circle(x0, y0, radius, color).
graphics.fill_circle(64, 32, 10, 1)
oled.show()
Треугольник
Также есть метод для рисования треугольника: triangle(x0, y0, x1, y1, x2, y2, color). Этот метод принимает координаты каждой вершины и цвет.
graphics.triangle(10,10,55,20,5,40,1)
oled.show()
Закрашенный треугольник
Используйте метод fill_triangle(x0, y0, x1, y1, x2, y2, color) для рисования закрашенного треугольника.
graphics.fill_triangle(10,10,55,20,5,40,1)
oled.show()
Скрипт MicroPython — рисование фигур
Следующий скрипт реализует все методы рисования, показанные ранее.
# Полный проект: https://RandomNerdTutorials.com/micropython-ssd1306-oled-scroll-shapes-esp32-esp8266/
from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import gfx
# Назначение выводов ESP32
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
# Назначение выводов ESP8266
#i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
graphics = gfx.GFX(oled_width, oled_height, oled.pixel)
while True:
graphics.line(0, 0, 127, 20, 1)
oled.show()
sleep(1)
oled.fill(0)
graphics.rect(10, 10, 50, 30, 1)
oled.show()
sleep(1)
oled.fill(0)
graphics.fill_rect(10, 10, 50, 30, 1)
oled.show()
sleep(1)
oled.fill(0)
graphics.circle(64, 32, 10, 1)
oled.show()
sleep(1)
oled.fill(0)
graphics.fill_circle(64, 32, 10, 1)
oled.show()
sleep(1)
oled.fill(0)
graphics.triangle(10,10,55,20,5,40,1)
oled.show()
sleep(1)
oled.fill(0)
graphics.fill_triangle(10,10,55,20,5,40,1)
oled.show()
sleep(1)
oled.fill(0)
Заключение
В этом руководстве вы узнали, как использовать расширенные функции для прокрутки экрана OLED и рисования фигур с помощью MicroPython на ESP32 или ESP8266. Для рисования фигур необходимо импортировать библиотеку Adafruit GFX для MicroPython.
Надеемся, это руководство было полезным. Если вы впервые работаете с OLED-дисплеем на MicroPython, рекомендуем сначала ознакомиться с начальным руководством:
У нас есть похожие руководства, но с использованием Arduino IDE: