MicroPython Skill Builders — #7: SPI OLED-дисплеи

MicroPython Skill Builders — #7 SPI OLED Displays

Добро пожаловать в седьмой выпуск серии MicroPython Skill Builders, автором которой является Тони Гудхью. Цель серии — улучшить ваши навыки программирования на MicroPython, попутно знакомя вас с новыми компонентами и техниками — с использованием Raspberry Pi Pico!

В этом выпуске Тони расскажет, как использовать OLED-дисплеи с Raspberry Pi Pico через интерфейс SPI. Мы уже рассматривали связь с OLED по I2C в предыдущей статье, а сегодня Тони берётся за SPI!

Пропустили предыдущие выпуски? Загляните в раздел руководств, чтобы найти предыдущие эпизоды.

Что вам понадобится

Предполагается, что вы уже установили Thonny на компьютер и настроили Raspberry Pi Pico с актуальной прошивкой MicroPython (UF2). Если нет — сначала ознакомьтесь с руководством по началу работы с Raspberry Pi Pico, где это подробно описано.

Вам понадобится:

  • Raspberry Pi Pico с контактными штырьками (header pins)

  • Полноразмерная макетная плата

  • Кабель Micro-USB (для питания и программирования Pico)

  • Провода-перемычки (папа/папа и папа/мама, желательно разных цветов)

  • Waveshare 0.96» OLED-модуль (или версия синего либо белого цвета)

Waveshare 0.96" OLED-дисплеи

Варианты OLED-дисплея

Цвет

Сегодня мы будем использовать версию жёлтый/синий дисплея Waveshare 0.96» — также доступны полностью белая и полностью синяя версии. OLED расшифровывается как O rganic L ight-E mitting D iode (органический светодиод).

Жёлто-синий дисплей имеет жёлтые пиксели в верхних 25% экрана и синие в нижних 75%.

Все версии имеют 128 пикселей по горизонтали и 64 пикселя по вертикали. Дисплеи небольшие, но очень яркие и чёткие. Они могут отображать как текст, так и графику, и являются отличным введением в программирование дисплеев.

I2C или SPI

Их можно подключить по SPI (настройка по умолчанию, пайка не требуется) или по I2C (нужны навыки пайки и корректировка библиотеки — см. предыдущее руководство).

Мы будем использовать прилагаемые кабели для подключения по SPI (Serial Peripheral Interface). Документацию Waveshare можно найти на сайте производителя, однако она не охватывает подключение к Raspberry Pi Pico — но мы нашли решение!

Немного о SPI

Не уверены насчёт SPI? В интернете можно найти отличное введение по теме.

В нашей статье используется современная терминология и не применяются исторические обозначения, такие как MISO и MOSI, появившиеся ещё в восьмидесятых (это интересная, но очень длинная и сложная тема — советуем вернуться к ней позже, поскольку использовать дисплей можно и без глубокого понимания всех деталей).

В нашем примере MAIN (главный) — это Pico, а SUBNODE (подузел) — это дисплей.

Библиотека кода для SPI OLED

Запустить дисплей очень просто. Для этого нам нужен код, управляющий дисплеем, — и мы можем скачать готовую библиотеку. Несмотря на то что данный дисплей использует чип SSD1315, он совместим с чипом SSD1306, поэтому мы можем использовать библиотеку SSD1306.

Установка библиотеки

Нам нужно установить библиотеку micropython-ssd1306, чтобы использовать этот дисплей. Следуйте шагам ниже.

Примечание: мы устанавливаем библиотеку вручную, так как на момент написания статьи метод установки через меню плагинов не работает.

  • Перейдите по этой ссылке: https://raw.githubusercontent.com/stlehmann/micropython-ssd1306/master/ssd1306.py

  • Выделите весь код на этой странице (используйте Ctrl+A) и скопируйте его в Thonny

  • В Thonny выберите File > Save as и укажите Raspberry Pi Pico в качестве места сохранения

  • Назовите файл ssd1306.py

  • Нажмите OK

  • ВАЖНО — теперь нужно закрыть этот файл ssd1306.py (нажмите маленький крестик на вкладке), затем откройте новый для своего кода (File > New)

Если всё прошло успешно, в нижнем левом углу экрана Thonny (секция файлов) вы должны увидеть имя библиотеки, подтверждающее её установку на Pico.

Подключение дисплея

Дисплеи поставляются с соединительными кабелями, у которых на одном конце находится блок-разъём, а на другом — одиночные разъёмы типа «мама». Вставьте блок в штырьки на задней стороне дисплея так, чтобы КРАСНЫЙ провод оказался на пине VCC. БЕЛЫЙ провод должен быть подключён к RES (reset).

Другие концы кабелей можно подключить в нескольких разных позициях на пинах Pico. Сначала мы будем использовать GP16–GP20, так как их легко найти. Вот таблица подключения пинов:

Цвет провода

Номер пина GPIO

Название

Белый

16

RST — сброс (reset)

Оранжевый

17

CS — выбор чипа (Chip select)

Жёлтый

18

CLK — тактовый сигнал (Clock)

Синий

19

MOSI / DIN

Зелёный

20

DC — данные/команда (Data/Command)

Красный

3.3 В

VCC

Чёрный

GND

GND

Тестовая программа SPI OLED для Pico

Программа ниже проверит, что всё работает правильно. При выполнении она должна зажечь дисплей с текстом и вывести строку в окно Shell в Thonny, как на изображении:

Пример работы OLED-дисплея с Pico по SPI (MicroPython)

После копирования и запуска кода прочитайте дальше, чтобы узнать, как он работает:

# Waveshare 0.96inch OLED Module via SPI (SSD1315)
# Available in White, Blue or Yellow & Blue
# Tony Goodhew 2 June 2023 - for thepihut.com

# Connect Red to 3.3V and Black to GND
from machine import Pin, SPI
import ssd1306

# Uses SPI port 0
spi_port = 0
MOSI = 19     # blue
CLK = 18      # yellow
CS = 17       # orange
RST = 16      # white   #NB MISO not used
DC = 20       # green

WIDTH = 128
HEIGHT = 64

spi = SPI(
    spi_port,
    baudrate=40000000,
    mosi=Pin(MOSI),
    sck=Pin(CLK))
print(spi) # Not essential - comment out

oled = ssd1306.SSD1306_SPI(WIDTH,HEIGHT,
    spi,
    dc=Pin(DC),
    res=Pin(RST),
    cs=Pin(CS),
    external_vcc=False
    )

# Clear the oled display in case it has junk on it.
oled.fill(0)

# Add some text
oled.text("Pi Pico with", 5, 6, 1)
oled.text('WS 0.96" OLED', 5, 16, 1)
oled.text("SSD1315 SPI", 5, 25, 1)
oled.text('White, Blue or', 5, 36, 1)
oled.text('Yellow & Blue', 5, 46, 1)
oled.text("thepihut.com", 5, 57, 1)

# Finally update the oled display so the text is displayed
oled.show()

Как это работает

Эта программа даёт нам информацию о подключении. На Pico имеется два порта SPI0 и 1, распределённых по нескольким наборам пинов GPIO. Здесь мы используем порт SPI 0.

Указывается, что данный порт в данной позиции обычно использует GP16 для MISO (main in, subnode out). Поскольку это дисплей, он только получает данные от Pico (main) и не отправляет никаких данных обратно от дисплея (subnode) на Pico.

Мы также использовали GP16 для сброса (reset). Мы выбрали GP16 для reset, чтобы не «тратить» другой пин впустую. Для этой цели мог быть использован любой другой пин GPIO.

Разбор кода

Этот раздел импортирует необходимые библиотеки и задаёт константы для подключения и размеров дисплея — 128 пикселей в ширину и 64 пикселя в высоту:

from machine import Pin, SPI
import ssd1306

# Uses SPI port 0
spi_port = 0
MOSI = 19     # blue
CLK = 18      # yellow
CS = 17       # orange
RST = 16      # white   #NB MISO not used
DC = 20       # green

WIDTH = 128
HEIGHT = 64

Этот раздел настраивает порт SPI и дисплей, который мы назвали oled:

spi = SPI(
    spi_port,
    baudrate=40000000,
    mosi=Pin(MOSI),
    sck=Pin(CLK))
print(spi) # Not essential - comment out

oled = ssd1306.SSD1306_SPI(WIDTH,HEIGHT,
    spi,
    dc=Pin(DC),
    res=Pin(RST),
    cs=Pin(CS),
    external_vcc=False
    )

Последний раздел очищает дисплей с помощью oled.fill(0), выводит несколько строк текста и обновляет экран командой oled.show(). Читайте дальше, чтобы узнать подробнее об этом разделе.

# Clear the oled display in case it has junk on it.
oled.fill(0)

# Add some text
oled.text("Pi Pico with", 5, 6, 1)
oled.text('WS 0.96" OLED', 5, 16, 1)
oled.text("SSD1315 SPI", 5, 25, 1)
oled.text('White, Blue or', 5, 36, 1)
oled.text('Yellow & Blue', 5, 46, 1)
oled.text("thepihut.com", 5, 57, 1)

# Finally update the oled display so the text is displayed
oled.show()

Пиксель в верхнем левом углу экрана имеет координаты (0, 0): x = 0 и y = 0. Пиксель в верхнем правом углу находится по адресу (0, 127). Пиксель в нижнем правом углу — (127, 63).

Команда oled.fill(0) заполняет экран ЧЁРНЫМИ пикселями. Цвет 0 означает ЧЁРНЫЙ, а цвет 1 означает БЕЛЫЙ (или цвет вашего конкретного экрана — белый, синий или жёлтый). Если заменить 0 на 1, экран заполнится «белым».

Команда oled.text(«Pi Pico with», 5, 6, 1) выводит текст, заключённый в кавычки, «белым» цветом, начиная с позиции (5, 6). Если изменить последнюю 1 на 0, текст будет выводиться чёрными пикселями, которые будут видны только на «белом» фоне.

Строка oled.text(„WS 0.96» OLED“, 5, 16, 1) демонстрирует, как включить кавычки в строку текста, которая размещается в позиции x = 5 и y = 16.

Финальная команда oled.show() является обязательной! Она сообщает плате дисплея обновить экран. Если её пропустить — ничего не появится на экране. Забыть эту команду — самая распространённая причина того, что ничего не отображается.

Дополнительный пример — движущийся текст

Следующая программа демонстрирует движение чёрного текста на ярком фоне. Подключение перенесено для демонстрации другой позиции на пинах GPIO.

# Waveshare 0.96inch OLED Module(C) via SPI (SSD1315)
# Moving name
# Tony Goodhew 5th July 2023

from machine import Pin, SPI
import ssd1306
import time

# Uses SPI port 0
MOSI = 3     # blue
CLK = 2      # yellow
CS = 1       # orange
RST = 0      # white
DC = 4       # green
spi_port = 0
WIDTH = 128
HEIGHT = 64

spi = SPI(
    spi_port,
    baudrate=40000000,
    mosi=Pin(MOSI),
    sck=Pin(CLK))
print(spi)

oled = ssd1306.SSD1306_SPI(WIDTH,HEIGHT,
    spi,
    dc=Pin(DC),
    res=Pin(RST),
    cs=Pin(CS),
    external_vcc=False
    )

for x in range(64):
    oled.fill(1)
    oled.text("Pico", int(x*1.5), x, 0)
    oled.show()
    time.sleep(0.1)

oled.fill(0)
oled.show()

На сегодня всё, друзья, от Тони скоро выйдут новые руководства!

Об авторе

Эта статья написана Тони Гудхью. Тони — учитель информатики на пенсии, который начал писать код ещё в 1968 году, когда это называлось программированием — он начинал с FORTRAN IV на IBM 1130! Активный участник сообщества Raspberry Pi, сейчас его основные интересы — программирование на MicroPython, путешествия и фотография.