Компоненты · 4 мин чтения

OLED-дисплей SSD1306: текст, фигуры и графика на Arduino

Как пользоваться I2C OLED-дисплеем 0,96 дюйма (SSD1306)? Подключение и I2C-адрес (0x3C), библиотеки Adafruit SSD1306 и GFX, вывод текста, фигур, показаний датчиков и картинок, код для ESP32 и Pico на MicroPython.

OLED-дисплей 0,96 дюйма размером чуть больше кончика пальца показывает чёткое изображение 128×64 пикселя и входит в число самых популярных дисплеев для проектов на Arduino. В отличие от символьных LCD, он рисует не только буквы, но и линии, круги, значки, графики и даже маленькие игры. Он идеален для умных часов, метеостанций, пультов и портативных измерительных приборов. Почти все такие дисплеи работают на микросхеме-драйвере SSD1306 и подключаются всего двумя проводами данных (I2C).

I2C OLED-дисплей 0,96 дюйма SSD1306
I2C OLED-дисплей 0,96 дюйма: 128×64 пикселя, драйвер SSD1306 и всего 4 пина (GND, VCC, SCL, SDA).

Что такое OLED и чем он отличается от LCD?

В OLED-дисплее (Organic Light Emitting Diode, органический светодиод) каждый пиксель сам излучает свет; подсветки нет. Поэтому чёрные области по-настоящему чёрные, контраст очень высокий, изображение чёткое под любым углом, а если большая часть картинки тёмная, потребление очень маленькое. 128×64 пикселя позволяют выводить графику, значки и рисунки, которые символьные LCD показать не могут.

ПараметрOLED 0,96″OLED 0,91″LCD 16x2
Разрешение128×64 пикселя128×32 пикселя16×2 символа
Графика и значкиДаДаНет (только символы)
ПодсветкаНе нужнаНе нужнаНужна
ПодключениеI2C (бывают и версии с SPI)I2C4 провода с I2C-модулем
На солнцеЧитается с трудомЧитается с трудомЧитается легче

Характеристики

ПараметрЗначение
Микросхема-драйверSSD1306
Экран0,96″ 128×64 (версия 0,91″ — 128×32)
ЦветМонохромный: белый, синий или жёлтый сверху и синий снизу
Питание3,3–5 V (на плате есть стабилизатор)
ТокОколо 10–25 mA (зависит от числа горящих пикселей)
I2C-адрес0x3C (на некоторых моделях 0x3D)
ПиныGND, VCC, SCL, SDA

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

Пин OLEDArduino UnoESP32Raspberry Pi Pico
GNDGNDGNDGND
VCC5V или 3.3V3V33V3
SCLA5GPIO 22GP5
SDAA4GPIO 21GP4
На одних OLED-модулях порядок пинов VCC, GND, на других — GND, VCC. Перед подключением всегда читай подписи на плате: если перепутать питание, дисплей мгновенно сгорит.

На двухцветных моделях верхние 16 строк экрана светятся жёлтым, а остальные — синим; программно эти цвета не меняются, поэтому верхнюю часть красиво оформить как строку заголовка. Если адрес дисплея неизвестен, воспользуйся скетчем-сканером I2C из статьи I2C LCD-дисплей.

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

  1. Открой «Менеджер библиотек» (Library Manager) в Arduino IDE и найди Adafruit SSD1306.
  2. Когда при установке появится вопрос о зависимостях, выбери Install all («Установить все»), чтобы установились также Adafruit GFX и Adafruit BusIO.
  3. При желании открой «Файл › Примеры › Adafruit SSD1306 › ssd1306_128x64_i2c» и попробуй его, указав адрес дисплея 0x3C.

Первая программа: выводим текст на экран

C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4
5Adafruit_SSD1306 display(128, 64, &Wire, -1);   // genişlik, yükseklik, I2C, reset pini yok / width, height, I2C, no reset pin
6
7void setup() {
8  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {   // I2C adresi / I2C address
9    for (;;);                                         // ekran bulunamadı / display not found
10  }
11  display.clearDisplay();
12  display.setTextColor(SSD1306_WHITE);
13  display.setTextSize(2);                   // 2 kat büyük / double size
14  display.setCursor(0, 0);
15  display.println(F("BlueGrays"));
16  display.setTextSize(1);
17  display.setCursor(0, 24);
18  display.println(F("OLED 128x64 hazir!"));
19  display.display();                        // tamponu ekrana gönder / push the buffer to the screen
20}
21
22void loop() {
23}
Библиотека сначала рисует всё в буфер в памяти; чтобы увидеть результат на экране, нужно вызвать display.display(). Забытая команда — самая частая причина «пустого дисплея». На Uno постоянный текст внутри F("...") ещё и экономит ОЗУ.

Рисуем фигуры: функции Adafruit GFX

ФункцияЧто рисует
drawPixel(x, y, color)Один пиксель
drawLine(x0, y0, x1, y1, color)Линию
drawRect / fillRect(x, y, ширина, высота, color)Прямоугольник или закрашенный прямоугольник
drawCircle / fillCircle(x, y, радиус, color)Окружность или закрашенный круг
drawRoundRect(x, y, ширина, высота, скругление, color)Прямоугольник со скруглёнными углами
drawTriangle(x0, y0, x1, y1, x2, y2, color)Треугольник
drawBitmap(x, y, массив, ширина, высота, color)Готовое изображение (bitmap)

Левый верхний угол экрана — (0, 0), правый нижний — (127, 63). Для цвета используют SSD1306_WHITE (включить), SSD1306_BLACK (выключить) или SSD1306_INVERSE (инвертировать).

Показываем значение датчика: живой термометр

Сильная сторона OLED — вывод показаний крупными цифрами и графикой. Код ниже пишет крупным шрифтом температуру, считанную с DHT11, а под ней показывает влажность в виде шкалы. Про подключение датчика читай в статье Датчик температуры и влажности DHT11.

C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <DHT.h>
5
6Adafruit_SSD1306 display(128, 64, &Wire, -1);
7DHT dht(2, DHT11);
8
9void setup() {
10  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
11  display.setTextColor(SSD1306_WHITE);
12  dht.begin();
13}
14
15void loop() {
16  float t = dht.readTemperature();
17  float h = dht.readHumidity();
18  display.clearDisplay();
19  display.setTextSize(1);
20  display.setCursor(0, 0);
21  display.print(F("Sicaklik / Temp"));
22  display.setTextSize(3);
23  display.setCursor(0, 16);
24  display.print(t, 1);
25  display.print(F("C"));
26  display.drawRect(0, 52, 128, 10, SSD1306_WHITE);                    // nem çubuğu çerçevesi / humidity bar frame
27  display.fillRect(2, 54, (int)(h / 100.0 * 124), 6, SSD1306_WHITE);  // nem oranı kadar dolu / filled by humidity
28  display.display();
29  delay(2000);
30}

Рисуем свой значок: растровые изображения

Чтобы показать логотип или значок, изображение превращают в массив байтов: каждый бит — один пиксель. Утилиты-конвертеры вроде image2cpp сразу превращают чёрно-белую картинку в массив для Arduino. Маленькие значки можно написать и вручную; массив 8×8 ниже рисует сердечко:

C++ (Arduino IDE)
1const unsigned char PROGMEM heart[] = {
2  0b01100110,
3  0b11111111,
4  0b11111111,
5  0b11111111,
6  0b01111110,
7  0b00111100,
8  0b00011000,
9  0b00000000
10};
11
12// setup() ya da loop() içinde / inside setup() or loop()
13display.drawBitmap(60, 28, heart, 8, 8, SSD1306_WHITE);
14display.display();

OLED с ESP32 и Raspberry Pi Pico

На ESP32 работают тот же код Arduino и те же библиотеки; пины I2C — GPIO 21 (SDA) и 22 (SCL). Памяти у ESP32 много, поэтому анимации и быстро обновляемая графика идут гораздо плавнее. На Pico с MicroPython достаточно скопировать на Pico файл драйвера ssd1306.py (из micropython-lib):

MicroPython
1from machine import Pin, I2C
2import ssd1306                                 # ssd1306.py Pico'da olmalı / must be on the Pico
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
5oled = ssd1306.SSD1306_I2C(128, 64, i2c)       # adres varsayılan 0x3C / default address 0x3C
6
7oled.fill(0)                                   # ekranı temizle / clear the screen
8oled.text("BlueGrays", 0, 0)
9oled.text("Pico + OLED", 0, 16)
10oled.rect(0, 40, 128, 20, 1)                   # çerçeve / frame
11oled.fill_rect(2, 42, 80, 16, 1)               # dolu çubuk / filled bar
12oled.show()                                    # ekrana gönder / push to the screen

Срок службы дисплея и выгорание

Пиксели OLED со временем теряют яркость. Если одно и то же изображение месяцами остаётся на экране без изменений, на часто горящих пикселях может появиться слабый «призрак». Чтобы этого избежать, выключай дисплей, когда он не нужен (display.ssd1306_command(SSD1306_DISPLAYOFF)), снижай яркость (display.dim(true)), время от времени сдвигай статичное содержимое на несколько пикселей или включай дисплей с помощью PIR-датчика, только когда рядом кто-то есть.

Идеи проектов с OLED-дисплеем

  • Мини-метеостанция: показывай температуру, влажность и давление со значками.
  • Карманные игры: играй в Pong или «динозаврика» T-Rex кнопками или джойстиком.
  • Экран погоды: показывай погоду, полученную из интернета на ESP32, вместе со значками.
  • Экран парктроника: показывай расстояние, измеренное HC-SR04, числом и шкалой.
  • Осциллограф-самоделка: рисуй значения analogRead на экране бегущим графиком.
  • Настольные часы: собери на одном экране время из интернета, дату и погоду на день.

Частые ошибки и как их исправить

  • Экран остаётся пустым: не вызывается display.display(), неверный адрес (0x3D вместо 0x3C), или перепутаны SDA и SCL.
  • «SSD1306 allocation failed»: у Uno закончилась ОЗУ; буфер дисплея 128×64 занимает 1 КБ. Пиши текст через F(), переноси большие массивы в PROGMEM или используй экономную к ОЗУ библиотеку U8g2.
  • Изображение искажено или видна только половина: дисплей 128×32 объявлен как 128×64 (или наоборот); укажи в коде правильный размер.
  • Изображение перевёрнуто: поверни его на 180 градусов через display.setRotation(2).
  • Перепутаны VCC и GND: это навсегда убивает дисплей; читай подписи пинов перед подключением.
  • Случайные зависания: длинные, болтающиеся провода I2C; делай провода короткими и при необходимости снижай скорость I2C.

OLED-дисплей — самый дешёвый способ придать проекту профессиональный вид. Если нужно показывать только цифры, хороший выбор — 7-сегментный индикатор, а для текста, который должен читаться на солнце, — I2C LCD. В приложении BlueGrays есть игры Pong и T-Rex на OLED, экран погоды на ESP32, парктроник и регистратор температуры — со схемами подключения и кодом.

Частые вопросы

Какой адрес у моего OLED-дисплея: 0x3C или 0x3D?

Большинство OLED-модулей 128×64 используют адрес 0x3C; на некоторых он становится 0x3D, если переставить резистор на обратной стороне платы. Если сзади написано «0x78», это 8-битная запись, которая в коде соответствует 0x3C. Чтобы знать наверняка, запусти скетч-сканер I2C.

Работает ли OLED-дисплей от 5 V?

На большинстве модулей SSD1306 есть стабилизатор, поэтому их можно питать от 3,3 V или 5 V и подключать прямо к Arduino Uno. На ESP32 и Pico питание модуля от пина 3V3 удерживает и линии I2C на уровне 3,3 V.

Почему появляется ошибка «SSD1306 allocation failed»?

Для дисплея 128×64 библиотека хочет зарезервировать буфер кадра в 1 КБ; если 2 КБ ОЗУ у Arduino Uno заняты другими переменными, места для него нет. Пиши постоянный текст через макрос F(), переноси большие массивы в PROGMEM или используй библиотеку U8g2, которая рисует постранично.

Может ли OLED-дисплей показывать кириллицу или особые символы?

Шрифт Adafruit GFX по умолчанию не содержит кириллицу и буквы вроде é. Библиотека U8g2 умеет показывать их благодаря поддержке UTF-8 и шрифтам с большими наборами символов; с Adafruit GFX нужно создать свой шрифт или рисовать буквы как растровые изображения.

Бывают ли цветные OLED-дисплеи?

Дисплеи SSD1306 монохромные; даже у двухцветных моделей цвета фиксированы. Для цветного изображения используй цветные OLED на драйверах SSD1331 или SSD1351 либо цветные TFT-дисплеи вроде ST7789 и ILI9341.

Можно ли подключить два OLED-дисплея к одной Arduino?

Да. Если поменять адрес одного дисплея на 0x3D, переставив резистор на обратной стороне, оба смогут работать на одной шине I2C. Если адрес поменять нельзя, на ESP32 и Pico можно использовать вторую шину I2C или добавить I2C-мультиплексор, например TCA9548A.

Все проекты
Игра в пинг-понг — SSD1306
#86Средний
Premium

Игра в пинг-понг — SSD1306

Мяч, две ракетки и ты: на маленьком OLED-экране ты играешь в настольный теннис — одну из самых первых видеоигр. Две кнопки двигают твою ракетку справа вверх и вниз, а левой ракеткой управляет компьюте

4.5(47)
65
OLED T-Rex Run: игра с динозавром на Arduino
#87Продвинутый
Premium

OLED T-Rex Run: игра с динозавром на Arduino

Игра с динозавром, которая появляется, когда пропадает интернет, теперь у тебя на столе: динозавр бежит по маленькому OLED-экрану, навстречу едут кактусы, а прыгаешь ты одной кнопкой. Счёт растёт в ре

4.7(33)
53
ESP32 HTTPClient + API погоды (с OLED-дисплеем SSD1306)
#134Продвинутый
Premium

ESP32 HTTPClient + API погоды (с OLED-дисплеем SSD1306)

В этом проекте ESP32 через HTTPClient.h делает вызов REST API к сервису погоды (wttr.in). В отличие от прошлой версии с I2C LCD, здесь используется OLED SSD1306 (128×64), который позволяет крупные шрифты, векторные значки и богатую картинку на одном экране. Семь векторных значков погоды (солнечно, переменная облачность, облачно, дождь, снег, гроза, туман) рисуются во время работы (растровые файлы не нужны). Температура выводится крупными цифрами.

4.3(10)
19
Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)
#135Продвинутый
Premium

Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)

Режим глубокого сна (Deep Sleep) у ESP32 снижает потребление до ~10 µA, выключая процессор и большую часть периферии, — это важно для IoT-устройств на батарейках. В этом проекте используются три источника пробуждения: таймер (15 секунд), внешний пин (EXT0 — кнопка GPIO 33) и касание (T0/GPIO 4). Переменные с RTC_DATA_ATTR сохраняются во время глубокого сна — счётчики загрузок, пробуждений по таймеру и по кнопке ведутся непрерывно.

4.3(10)
16
Счётчик ракаатов намаза на ESP32 (HC-SR04 + SSD1306 OLED + 2 кнопки)
#136Продвинутый
Premium

Счётчик ракаатов намаза на ESP32 (HC-SR04 + SSD1306 OLED + 2 кнопки)

Бывает, что во время намаза забываешь, сколько ракаатов уже совершено? Этот проект — счётчик ракаатов, который ставится рядом с молитвенным ковриком и считает земные поклоны, когда к нему приближается рука. Ультразвуковой датчик HC-SR04 замечает приближение руки, OLED-дисплей SSD1306 показывает число ракаатов, а двумя кнопками можно выбрать 2, 3 или 4 ракаата и сбросить счёт. В нём умный конечный автомат с паузой 2,5 секунды и проверкой «рука убрана».

4.8(11)
14
Смеситель цветов на ESP32 (3 потенциометра + RGB-светодиод + OLED)
#138Продвинутый
Premium

Смеситель цветов на ESP32 (3 потенциометра + RGB-светодиод + OLED)

Умная лампа для смешивания цветов на ESP32: вращая три потенциометра, можно получить любой цвет! Когда крутишь потенциометры красного, зелёного и синего, RGB-светодиод с общим катодом меняет цвет в реальном времени. OLED-дисплей SSD1306 показывает значения каждого цвета в диапазоне 0–255, полосы заполнения и веб-код цвета HEX (например, #FF8040). Мини-студия цвета, которая учит теории цвета RGB, чтению АЦП, регулировке яркости через PWM и дизайну экрана I2C.

4.7(6)
10
Умное освещение на ESP32 (PIR + LDR + реле + OLED)
#141Продвинутый
Premium

Умное освещение на ESP32 (PIR + LDR + реле + OLED)

Сделай умное освещение для коридора, ванной или кладовки на ESP32! С PIR-датчиком движения, датчиком освещённости LDR и модулем реле собирается классический сценарий «свет включается при движении в темноте»: если вокруг уже светло, движение свет НЕ включает, и днём энергия экономится. Свет горит 30 секунд; если движение продолжается, таймер сбрасывается, и свет горит дольше. OLED SSD1306 крупно показывает состояние (ON / DAYTIME / WAITING) и обратный отсчёт.

4.3(6)
11
Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Продвинутый
Premium

Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Собери на ESP32 регистратор температуры с отметками времени! Каждую минуту читай температуру и влажность с DHT22, бери реальное время из DS1307 RTC и записывай всё на карту microSD в формате CSV. OLED показывает текущую температуру (крупным шрифтом), влажность в процентах, время и счётчик записей. Файл /temp_log.csv на SD-карте открывается в Excel, Google Sheets или Python pandas — идеально для теплиц, комнат, лабораторий и хранения продуктов.

4.7(7)
12