В этом расширенном уроке мы подключим дисплей OLED SSD1306 0.96" (I2C) к Arduino Uno, добавим полноценную поддержку кириллицы (UTF‑8) и реализуем переключение строк с помощью джойстика HW‑504.
Мы используем связку библиотек Adafruit_SSD1306 + Adafruit_GFX и надстройку U8g2_for_Adafruit_GFX, которая позволяет печатать кириллицу «как есть» (UTF‑8), без доп. конвертеров и самодельных таблиц соответствия.
Зачем U8g2_for_Adafruit_GFX?
СтандартнаяAdafruit_GFXне умеет напрямую Unicode. НадстройкаU8g2_for_Adafruit_GFX«встраивает» шрифты U8g2 (включая кириллицу) в Adafruit GFX и даёт простые методы для вывода UTF‑8 на наш SSD1306.
| Компонент | Кол-во | Примечание |
|---|---|---|
| Arduino Uno | 1 | Любая совместимая плата 5 В |
| OLED SSD1306 128×64 (I2C) | 1 | Адрес по умолчанию чаще всего 0x3C |
| Джойстик HW‑504 | 1 | Оси VRx/VRy (A0/A1) + кнопка SW (D2) |
| Провода Dupont | набор | M‑F/F‑F по необходимости |
OLED SSD1306 (I2C):
VCC → 5VGND → GNDSDA → A4SCL → A5Джойстик HW‑504:
VRx → A0VRy → A1SW → D2+5V → 5VGND → GND
Для компиляции этого урока нужны три библиотеки из Library Manager Arduino IDE:
Зависимости: при установке
Adafruit SSD1306IDE предложит поставитьAdafruit GFXиAdafruit BusIO. При установкеU8g2_for_Adafruit_GFXможет потребоваться пакетU8g2. Соглашайтесь на установку всех зависимостей — это нормально.
Итог: отдельно за вами ничего «ручками» подтягивать не нужно — просто соглашайтесь на зависимости.
RusFont.hПроект состоит из двух файлов:
lesson_rus_font.ino — основной скетч с логикой дисплея и джойстика.RusFont.h — лёгкая обёртка над U8g2_for_Adafruit_GFX с готовыми кириллическими шрифтами и удобными методами print().RusFont.h прямо в IDERusFont.h и нажмите Enter.RusFont.h» ниже и сохраните скетч.Альтернатива: создать файл
RusFont.hв папке скетча через Проводник/Файловый менеджер, затем вернуться в IDE.
lesson_rus_font.ino#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RusFont.h" // наш тонкий обёрточный хедер с U8g2 шрифтами (UTF-8)
// ---------- Дисплей ----------
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ---------- Джойстик HW-504 ----------
#define JOY_X A0
#define JOY_Y A1
#define JOY_SW 2
int joyX, joyY;
bool joyBtn;
const int DEADZONE = 180;
unsigned long lastMove = 0;
const int debounceDelay = 180;
// ---------- Текстовые строки ----------
const char* messages[] = {
"Привет, Arduino!",
"Это OLED SSD1306",
"Кириллица!",
"Управляй мечтой!"
};
int msgCount = sizeof(messages) / sizeof(messages[0]);
int currentMsg = 0;
void showMessage();
void setup() {
pinMode(JOY_SW, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
// Если дисплей не найден — зависаем
for (;;);
}
display.clearDisplay();
RusFont::begin(display); // Подключаем U8g2 движок и кириллический шрифт
RusFont::setCursor(0, 18);
RusFont::print(F("Загрузка..."));
display.display();
delay(1000);
showMessage();
}
void loop() {
joyX = analogRead(JOY_X);
joyY = analogRead(JOY_Y);
joyBtn = !digitalRead(JOY_SW);
if (millis() - lastMove > debounceDelay) {
// Вверх
if (joyY < (512 - DEADZONE)) {
currentMsg--;
if (currentMsg < 0) currentMsg = msgCount - 1;
showMessage();
lastMove = millis();
}
// Вниз
if (joyY > (512 + DEADZONE)) {
currentMsg++;
if (currentMsg >= msgCount) currentMsg = 0;
showMessage();
lastMove = millis();
}
}
}
void showMessage() {
display.clearDisplay();
// Заголовок мелким шрифтом
RusFont::setFontSmall();
RusFont::setCursor(0, 12);
RusFont::print(F("Русский шрифт (UTF-8)"));
// Основной текст покрупнее/читабельнее
RusFont::setFontNormal();
RusFont::setCursor(0, 36);
RusFont::print(messages[currentMsg]);
// Подсказка
RusFont::setFontSmall();
RusFont::setCursor(0, 60);
RusFont::print(F("Джойстик: вверх/вниз"));
display.display();
}
RusFont.hФайл создаем в новой вкладке одного проекта
#pragma once
#include <U8g2_for_Adafruit_GFX.h>
// Лёгкая обёртка: один статический объект U8g2_for_Adafruit_GFX,
// выбор шрифтов и удобные методы печати.
// Используем U8g2 встроенные кириллические шрифты (UTF-8 поддерживается).
namespace RusFont {
// Единый экземпляр U8g2_for_Adafruit_GFX
inline U8G2_FOR_ADAFRUIT_GFX& core() {
static U8G2_FOR_ADAFRUIT_GFX u8;
return u8;
}
// Два кегля: компактный и нормальный (оба с кириллицей)
// Эти шрифты входят в U8g2:
// u8g2_font_6x13_t_cyrillic — компактный
// u8g2_font_8x13_t_cyrillic — нормальный
inline void setFontSmall() { core().setFont(u8g2_font_6x13_t_cyrillic); }
inline void setFontNormal() { core().setFont(u8g2_font_8x13_t_cyrillic); }
// Инициализация: соединяем U8g2 движок с Adafruit_GFX-дисплеем,
// выбираем кириллический шрифт и цвета
inline void begin(Adafruit_GFX &gfx) {
core().begin(gfx); // связываем с дисплеем
core().setFontMode(1); // прозрачный фон
core().setFontDirection(0); // слева-направо
core().setForegroundColor(1); // белый (для монохрома)
setFontNormal(); // шрифт по умолчанию
}
inline void setCursor(int16_t x, int16_t y) { core().setCursor(x, y); }
inline size_t print(const __FlashStringHelper *ifsh) { return core().print(ifsh); }
inline size_t print(const char* s) { return core().print(s); }
inline size_t print(const String& s) { return core().print(s); }
}
lesson_rus_font.ino (проверьте, что рядом есть вкладка RusFont.h).После загрузки на экране появится «Загрузка…», затем первая строка. Двигайте джойстик вверх/вниз — сообщения будут переключаться.
Неверный I2C‑адрес. У большинства модулей SSD1306 адрес 0x3C, но бывают 0x3D.
Проверьте адрес I2C‑сканером:
#include <Wire.h>
void setup() {
Serial.begin(9600);
Wire.begin();
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("I2C device found at 0x");
Serial.println(addr, HEX);
}
}
}
void loop() {}
Подставьте найденный адрес в display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
SDA/SCL перепутаны. На Uno это A4/A5.
Питание: подключите VCC к 5 В, земля общая.
Старые/конфликтующие версии библиотек: удалите дубликаты из Documents/Arduino/libraries и установите через Library Manager заново.
RusFont (RusFont::print()), а не прямой display.print() — мы печатаем UTF‑8 через U8g2‑мост.DEADZONE (например, 150–220).analogRead() в setup() и запомните как центр).INPUT_PULLUP и кнопка замыкает на GND.joyBtn = !digitalRead(JOY_SW);RusFont.h имена на, например, u8g2_font_10x20_t_cyrillic (крупнее) или u8g2_font_5x8_t_cyrillic (компактнее).display.invertDisplay(true/false);drawRect()/fillRect()).JOY_SW: по нажатию инвертируйте экран или переходите к первому пункту.joyX, joyY, состояние joyBtn русскими подписями.10x20) и переразместите текст, чтобы он умещался на 128×64.