[#] Подключение OLED 0.96" к ESP32 — полный гайд#

OLED дисплей 0.96" на контроллере SSD1306 — идеальный выбор для первого проекта. Подключается 4 проводами, потребляет мало, светится ярко. Разберём всё от пайки до запуска мультика!


[>] Почему OLED SSD1306?#

ПлюсОписание
[~] Низкое потребление~20mA, светятся только активные пиксели
[~] Идеальный чёрныйПиксели реально выключены, не светятся
[o_o] Отличный контрастВидно даже на солнце
[+-] Простое подключениеВсего 4 провода по I2C
[$] Дёшево~100₽ на AliExpress

Минус один: I2C интерфейс медленнее чем SPI. Но! Мы запускали анимацию с 15 FPS без проблем — для большинства проектов хватает с головой.


[+] Что понадобится#

КомпонентПримечание
ESP32 DevKitЛюбая версия
OLED 0.96" SSD1306I2C версия (4 пина)
Провода Dupont4 штуки (мама-мама или мама-папа)
ПаяльникЕсли пины не припаяны

Где купить: Дисплеи | Контроллеры ESP32


[+-] Схема подключения#

Стандартное подключение:#

OLED SSD1306      ESP32
────────────      ─────
VCC          →    3.3V
GND          →    GND
SDA          →    GPIO21
SCL          →    GPIO22

Вот и всё! Четыре провода.

Таблица пинов:#

OLED пинESP32 пинЦвет провода (обычно)
VCC3.3V[!] Красный
GNDGND> Чёрный
SDAGPIO21> Синий
SCLGPIO22[>] Жёлтый

[!] Важно: Подключай к 3.3V, не к 5V! Хотя многие модули имеют стабилизатор, лучше не рисковать.


[>] Пайка пинов#

Если дисплей пришёл без припаянных пинов:

  1. Вставь гребёнку пинами вниз
  2. Припаяй каждый пин с обратной стороны
  3. Не перегревай — OLED не любит высоких температур
  4. Проверь что нет замыканий между пинами

[i] Совет: Можно использовать Dupont провода напрямую без пинов — просто припаять провода к площадкам.


[#] Адрес I2C и перемычка#

Стандартный адрес: 0x3C#

На большинстве модулей есть перемычка (резистор) для смены адреса:

ПеремычкаАдрес
Стандартно0x3C
Перепаяна0x3D

Зачем это нужно?#

Можно подключить два дисплея к одним пинам! Один с адресом 0x3C, второй с 0x3D — и работают параллельно.

Как найти перемычку:#

На обратной стороне дисплея ищи:

  • Маркировку “ADDR” или “A0”
  • Два контакта с перемычкой или без

Перепаяй перемычку на соседние контакты — адрес изменится.

Как узнать адрес?#

Загрузи I2C сканер:

#include <Wire.h>

void setup() {
  Wire.begin(21, 22);
  Serial.begin(115200);
  Serial.println("I2C Scanner");
}

void loop() {
  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found: 0x");
      Serial.println(address, HEX);
    }
  }
  delay(5000);
}

В Serial Monitor увидишь адрес подключённого дисплея.


[+] Установка библиотек#

Вариант 1: Adafruit (рекомендую для новичков)#

В Arduino IDE: Скетч → Подключить библиотеку → Управление библиотеками

Найди и установи:

  1. Adafruit SSD1306
  2. Adafruit GFX Library (установится автоматически)

Вариант 2: U8g2 (больше шрифтов и функций)#

Установи библиотеку U8g2 — она мощнее, но сложнее.

Вариант 3: GyverOLED (русская, лёгкая)#

Библиотека от AlexGyver — поддерживает русский язык из коробки.


[#] Минимальный код#

Hello World на Adafruit:#

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Размер дисплея
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Создаём объект дисплея
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);
  
  // Инициализация I2C на пинах ESP32
  Wire.begin(21, 22);
  
  // Запуск дисплея
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 не найден!");
    while(true);
  }
  
  // Очищаем буфер
  display.clearDisplay();
  
  // Настройки текста
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  
  // Выводим текст
  display.println("MONSTRIX");
  display.setTextSize(1);
  display.println();
  display.println("Hello, World!");
  
  // Отправляем на дисплей
  display.display();
}

void loop() {
  // Ничего не делаем
}

Что происходит в коде:#

  1. Wire.begin(21, 22) — запускаем I2C на стандартных пинах ESP32
  2. display.begin() — инициализируем дисплей с адресом 0x3C
  3. display.clearDisplay() — очищаем буфер (не сам дисплей!)
  4. display.print() — пишем в буфер
  5. display.display() — отправляем буфер на экран

[i] Важно: Пока не вызовешь display.display() — на экране ничего не изменится!


[>] Примеры вывода#

Текст разных размеров:#

display.clearDisplay();

display.setTextSize(1);  // Мелкий (6x8 px)
display.setCursor(0, 0);
display.println("Size 1");

display.setTextSize(2);  // Средний (12x16 px)
display.println("Size 2");

display.setTextSize(3);  // Крупный (18x24 px)
display.println("Size 3");

display.display();

Графические примитивы:#

display.clearDisplay();

// Пиксель
display.drawPixel(10, 10, SSD1306_WHITE);

// Линия
display.drawLine(0, 0, 127, 63, SSD1306_WHITE);

// Прямоугольник
display.drawRect(10, 10, 50, 30, SSD1306_WHITE);

// Заполненный прямоугольник
display.fillRect(70, 10, 50, 30, SSD1306_WHITE);

// Круг
display.drawCircle(64, 32, 20, SSD1306_WHITE);

// Заполненный круг
display.fillCircle(64, 32, 10, SSD1306_WHITE);

display.display();

Анимация (простой счётчик):#

void loop() {
  static int count = 0;
  
  display.clearDisplay();
  display.setTextSize(3);
  display.setCursor(40, 20);
  display.print(count);
  display.display();
  
  count++;
  delay(100);
}

[#] Анимация и FPS#

Сколько FPS можно выжать?#

РежимFPSПримечание
Полная перерисовка~15-20Нормально для большинства задач
Частичное обновление~30+Если обновлять только изменившееся
С буфером~25Adafruit использует буфер

Мы запускали мультик с 15 FPS — смотрится плавно! Для часов, датчиков, меню — более чем достаточно.

Пример простой анимации:#

void loop() {
  static int x = 0;
  
  display.clearDisplay();
  display.fillCircle(x, 32, 10, SSD1306_WHITE);
  display.display();
  
  x += 2;
  if (x > 128) x = 0;
  
  delay(30);  // ~30 FPS
}

[?] Решение проблем#

Дисплей не включается#

ПроблемаРешение
Неправильный адресЗапусти I2C сканер
Перепутаны SDA/SCLПоменяй местами
Нет питанияПроверь 3.3V мультиметром
Плохой контактПроверь пайку

Мусор на экране#

display.clearDisplay();
display.display();

Выполни очистку — возможно в буфере был мусор.

Текст не отображается#

Не забыл вызвать display.display() после print()?

Дисплей мерцает#

  • Проверь питание — возможно просадки
  • Добавь конденсатор 100μF между VCC и GND
  • Укороти провода (макс 20 см для I2C)

[#] Характеристики OLED 0.96"#

ПараметрЗначение
Диагональ0.96" (24.4 мм)
Разрешение128×64 пикселей
КонтроллерSSD1306
ИнтерфейсI2C (4 пина)
Напряжение3.3V (некоторые 5V tolerant)
Потребление~20mA (зависит от картинки)
ЦветМонохром (белый/синий/жёлто-синий)
Угол обзора>160°

vs Варианты дисплеев#

ВариантОсобенность
БелыйКлассика, хороший контраст
СинийПриятный оттенок
Жёлто-синийВерх жёлтый, низ синий (для заголовков)

Функционально одинаковые — выбирай по вкусу.


[+] Где купить?#

Проверенные дисплеи собраны в разделе:

[#] Дисплеи


[+] Что дальше?#


<3 Поддержать проект#

Если гайд был полезен — буду рад поддержке! Все средства идут на новые эксперименты и компоненты.

[ <3 Поддержать автора ]

Вопросы? Пиши в Telegram