Это руководство содержит исчерпывающую информацию для аппаратного и программного подключения E-Paper дисплеев WeAct Studio разрешением 296x128 и 296x160 пикселей к микроконтроллерам семейства ESP32 с использованием высокоскоростного последовательного интерфейса SPI.

Часть 1: Аппаратное подключение (SPI)

В отличие от I²C, для работы по протоколу SPI требуется больше сигнальных линий, но обеспечивается значительно более высокая скорость передачи данных, что критически важно для обновления всего изображения на E-Paper экране.

1.1 Назначение контактов дисплея

Дисплей использует 8-проводной шлейф. Крайне важно подавать на модуль напряжение 3.3V, а не 5V.

В таблице ниже приведено соответствие между обозначениями на шлейфе дисплея, стандартными названиями сигналов SPI и их функциями.

Обозначение на дисплее Сигнал SPI Назначение Важность
1 VCC - Питание (3.3V) Обязательно
2 GND - Земля Обязательно
3 DIN или SDA MOSI (Master Out Slave In) Линия данных от МК к дисплею Обязательно
4 CLK или SCL SCK (Serial Clock) Тактовый сигнал Обязательно
5 CS SS (Slave Select) Выбор ведомого устройства (активен низким уровнем) Обязательно
6 DC - Data/Command (Выбор: данные или команда) Обязательно
7 RST - Сброс дисплея (активен низким уровнем) Сильно рекомендуется
8 BUSY - Флаг занятости дисплея Сильно рекомендуется

Примечание: Контакты RST и BUSY не являются частью стандартного SPI, но необходимы для корректной и надежной работы E-Paper дисплея. Без RST возможны сбои при инициализации, а без BUSY микроконтроллер не сможет определить, когда дисплей готов принять новые данные.

1.2 Подключение к ESP32

ESP32 имеет несколько аппаратных шин SPI (HSPI, VSPI), пины которых можно переназначать (ремапить). Это позволяет гибко выбирать GPIO для подключения.

В таблице ниже показаны два распространенных варианта подключения. Схема из руководства  оставляет свободными аналоговые пины (ADC) для других датчиков, а схема из обсуждения  демонстрирует универсальный пример.

 
Сигнал Пин ESP32 (Вариант 1) Пин ESP32 (Вариант 2) Альтернативные пины (VSPI на ESP32)
VCC 3.3V 3.3V 3.3V
GND GND GND GND
SDA (MOSI) GPIO10 GPIO6 GPIO23 (стандартный MOSI для VSPI)
SCL (SCK) GPIO44 GPIO4 GPIO18 (стандартный SCK для VSPI)
CS GPIO13 GPIO7 GPIO5 (стандартный SS для VSPI)
DC GPIO12 GPIO1 Любой свободный GPIO
RST GPIO11 GPIO2 Любой свободный GPIO
BUSY GPIO43 GPIO3 Любой свободный GPIO

Внимание: При использовании ESP32-S3 Supermini, как в руководстве , следует избегать пинов GPIO0 (кнопка Boot) и GPIO48 (совместно с onboard LED).

Часть 2: Программное обеспечение и написание скетча

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

В Arduino IDE необходимо установить следующие библиотеки через менеджер библиотек (Sketch -> Include Library -> Manage Libraries...):

  1. GxEPD2 by Jean-Marc Zingg (основная библиотека для управления дисплеем).

  2. Adafruit GFX Library (графическая библиотека, от которой зависит GxEPD2).

2.2 Выбор правильного класса дисплея в GxEPD2

Это самый важный шаг. Библиотека GxEPD2 содержит десятки классов для разных моделей дисплеев. Для модулей WeAct Studio 2.9" с контроллером SSD1680 подходят следующие классы:

  • GxEPD2_290_BS (Black & White, 128x296).

  • GxEPD2_290_T5 (Black & White, 128x296, аналог для 160px можно создать, указав высоту вручную).

  • GxEPD2_290_C90c (3-color: Black, White, Red/Yellow, 128x296).

Для дисплея 296x160 может потребоваться использовать базовый класс с явным указанием высоты, как показано в адаптированном коде ниже.

2.3 Базовый скетч для тестирования (ESP32)

Данный скетч выполняет инициализацию, настраивает пользовательские пины SPI, выводит графику и текст, а затем переводит дисплей в режим гибернации. Код адаптирован для поддержки как 128, так и 160 пикселей по высоте.

cpp
#include <GxEPD2_BW.h>
#include <GxEPD2_3C.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <SPI.h> // Подключаем библиотеку для работы с SPI

// ============================================
// НАСТРОЙКА ПИНОВ ПОДКЛЮЧЕНИЯ (ЗАДАЙТЕ СВОИ!)
// ============================================
// Пример для ESP32-S3 Supermini[citation:1]
#define EPD_BUSY  43
#define EPD_CS    13
#define EPD_RST   11
#define EPD_DC    12
#define EPD_SCK   44  // SCK/CLK
#define EPD_MISO  -1  // Не используется (нет данных от дисплея)
#define EPD_MOSI  10  // SDA/DIN

// ============================================
// ВЫБОР КЛАССА ДИСПЛЕЯ
// ============================================
// Раскомментируйте ОДНУ строку, соответствующую вашему дисплею
// Для 296x128 (Black & White):
 GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(GxEPD2_290_BS(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));

// Для 296x160 (Black & White). Создаем экземпляр, явно указывая высоту 160:
// GxEPD2_BW<GxEPD2_290_T5, 160> display(GxEPD2_290_T5(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));

// Для 3-цветного дисплея (Black, White, Red)[citation:1]:
// GxEPD2_3C<GxEPD2_290_C90c, GxEPD2_290_C90c::HEIGHT> display(GxEPD2_290_C90c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));

// Создаем отдельный объект для пользовательской шины SPI (например, HSPI)
SPIClass hspi(HSPI);

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Start E-Paper Demo");

  // ============================================
  // 1. КЛЮЧЕВАЯ НАСТРОЙКА ПОЛЬЗОВАТЕЛЬСКОГО SPI
  // ============================================
  // Стандартные примеры GxEPD2 используют предустановленные пины SPI по умолчанию.
  // Для работы с пользовательскими пинами необходимо:
  // а) Инициализировать дисплей (он временно использует пины по умолчанию).
  // б) Остановить стандартную шину SPI.
  // в) Запустить новую шину SPI (hspi) на нужных нам пинах[citation:1][citation:4].
  display.init(115200, true, 2, false); // Инициализация с таймаутом 115200 мс, сбросом, длительностью импульса сброса 2 мс
  SPI.end(); // Останавливаем стандартный SPI

  // Запускаем шину HSPI на заданных пинах
  hspi.begin(EPD_SCK, EPD_MISO, EPD_MOSI, EPD_CS);
  // Явно сообщаем библиотеке GxEPD2 использовать наш объект hspi с заданными настройками
  display.epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0)); // Частота 4 МГц, режим 0

  // ============================================
  // 2. ТЕСТОВЫЕ ОПЕРАЦИИ
  // ============================================
  testDisplay(); // Функция с тестами (см. ниже)

  // ============================================
  // 3. КРИТИЧЕСКИ ВАЖНЫЙ ЭТАП - ГИБЕРНАЦИЯ
  // ============================================
  // После завершения всех операций ОБЯЗАТЕЛЬНО переведите дисплей в спящий режим.
  // Это предотвращает повреждение экрана из-за длительного приложения высокого напряжения[citation:1][citation:2].
  display.hibernate(); // Предпочтительный метод (самый низкое потребление)
  // display.powerOff(); // Альтернатива

  Serial.println("Demo finished, display in hibernate mode.");
}

void loop() {
  // Пустой цикл. Все действия выполняются в setup.
}

void testDisplay() {
  // 1. Полная очистка экрана (белый фон)
  display.setFullWindow();
  display.fillScreen(GxEPD_WHITE);
  display.display();
  delay(2000);

  // 2. Рисование базовой графики
  display.fillScreen(GxEPD_WHITE);
  // Прямоугольник
  display.drawRect(10, 10, 50, 30, GxEPD_BLACK);
  // Закрашенный прямоугольник
  display.fillRect(70, 10, 50, 30, GxEPD_BLACK);
  // Текст
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  display.setCursor(10, 80);
  display.println("Hello, E-Paper!");
  display.setCursor(10, 110);
  // Динамическое определение высоты экрана для универсальности скетча
  display.print("Height: ");
  display.print(display.height());
  display.print("px");

  display.display();
  delay(3000);

  // 3. Демонстрация частичного обновления (если поддерживается)
  if (display.epd2.hasPartialUpdate) {
    display.setPartialWindow(50, 50, 100, 50);
    display.fillScreen(GxEPD_WHITE);
    display.setCursor(55, 80);
    display.setFont();
    display.println("Partial");
    display.display();
    delay(2000);
  }
}

2.4 Особенности работы с E-Paper и важные предупреждения

  1. Срок службы дисплея: Дисплей не должен оставаться под напряжением без дела. Всегда завершайте работу с помощью display.hibernate() или display.powerOff().

  2. Частичное обновление: Не используйте частичное обновление постоянно. После нескольких частичных обновлений (обычно 5-10) необходимо выполнить полное обновление (display.setFullWindow()), иначе на экране могут появиться нестираемые артефакты.

  3. Скорость обновления: Полное обновление занимает ~2-3 секунды. Избегайте слишком частых обновлений. Рекомендуемый минимальный интервал — 180 секунд.

  4. Уровни напряжения: Все линии данных должны работать от 3.3В. Большинство современных плат дисплея имеют встроенные преобразователи уровня, но проверьте это.

Заключение и итоговая шпаргалка

Для успешного запуска 2.9-дюймового E-Paper дисплея WeAct Studio выполните следующие шаги:

  1. Подключите все 8 проводов к ESP32, соблюдая распиновку.

  2. Подавайте только 3.3V на контакт VCC.

  3. Установите библиотеки GxEPD2 и Adafruit_GFX.

  4. В коде задайте свои пины в секции #define и выберите правильный класс дисплея (например, GxEPD2_290_BS).

  5. Обязательно настройте пользовательский SPI, используя последовательность init() -> SPI.end() -> hspi.begin(...) -> selectSPI(...).

  6. Всегда завершайте работу дисплея командой display.hibernate().

  7. Чередуйте полное и частичное обновление для сохранения качества изображения.

Следуя этому руководству, вы сможете реализовать стабильную и долговечную работу вашего E-Paper дисплея в проектах с минимальным энергопотреблением.

Если у вас возникнут проблемы с отображением, первым делом проверьте корректность настройки пользовательской шины SPI в коде и напряжение питания. Для дисплея 296x160 также убедитесь, что в коде правильно задана высота буфера (например, <GxEPD2_290_T5, 160>).