Главная chevron_right Наши уроки chevron_right Arduino chevron_right Урок 9. Русский язык на OLED дисплее 128X64

Урок 9. Русский язык на OLED дисплее 128X64

Разбираем проблемные моменты вывода русских букв на OLED дисплей 128×64 с Arduino Uno. Подключаем Trema OLED по I2C и настраиваем библиотеку iarduino_OLED_txt для корректного от...

ВИДЕО редактируется.

Вы могли наблюдать, что в предыдущих уроках №7 и №8 уже использовался Русский шрифт. В этом уроке мы разберём некоторые проблемные моменты с которыми можно столкнуться при выводе Русских букв на OLED дисплей.

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

Для реализации проекта нам необходимо установить библиотеки:

  • Библиотека iarduino_OLED_txt (текстовая) - для вывода текста и цифр на OLED дисплеи.
  • Дополнительно можно установить библиотеку iarduino_OLED (графическая), но в данном уроке она использоваться не будет. Графическая библиотека поддерживает все функции текстовой и имеет дополнительные функции для работы с изображениями и графикой, но при этом она занимает больше памяти, как оперативной, так и памяти программ.

О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.

Схема подключения:

OLED дисплей подключается к аппаратной или программной шине I2C Arduino.

ВыводНазначениеOLED дисплейArduino UNO
SCLЛиния тактирования шины I2CSCLA5
SDAЛиния данных шины I2CSDAA4
VccПитание (3,3 или 5 В)Vcc5V
GNDОбщийGNDGND

Подключение OLED дисплея к Arduino UNO по шине I2C

Схема установки дисплея при его подключении через Trema Set Shield.

Код программы:

#include <Wire.h>                                      // Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотеки iarduino_OLED_txt.
#include <iarduino_OLED_txt.h>                         // Подключаем библиотеку iarduino_OLED_txt.
iarduino_OLED_txt myOLED(0x78);                        // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x78 (если учитывать бит RW=0).
                                                       //
extern const uint8_t SmallFontRus[];                   // Подключаем шрифт SmallFontRus.
                                                       //
void setup(){                                          //
    myOLED.begin();                                    // Инициируем работу с дисплеем.
    myOLED.setFont(SmallFontRus);                      // Указываем шрифт который требуется использовать для вывода цифр и текста.
//  myOLED.setCoding(TXT_UTF8);                        // Указываем кодировку текста в скетче. Если на дисплее не отображается Русский алфавит, то ...
}                                                      // раскомментируйте функцию setCoding и замените параметр TXT_UTF8, на TXT_CP866 или TXT_WIN1251.
                                                       //
void loop(){                                           //
    myOLED.clrScr();                                   // Чистим экран.
    myOLED.print( "Большие буквы:"    ,      0, 0);    // Выводим текст начиная с 0 столбца 0 строки.
    myOLED.print( "ABCDEFGHIJKLM"     , OLED_C, 2);    // Выводим текст по центру 2 строки.
    myOLED.print( "NOPQRSTUVWXYZ"     , OLED_C, 3);    // Выводим текст по центру 3 строки.
    myOLED.print( "АБВГДЕЁЖЗИЙКЛМНОП" , OLED_C, 5);    // Выводим текст по центру 5 строки.
    myOLED.print( "РСТУФХЦЧШЩЪЫЬЭЮЯ"  , OLED_C, 6);    // Выводим текст по центру 6 строки.
    delay(3000);                                       // Ждём 3 секунды.
                                                       //
    myOLED.clrScr();                                   // Чистим экран.
    myOLED.print( "Маленькие буквы:"  ,      0, 0);    // Выводим текст начиная с 0 столбца 0 строки.
    myOLED.print( "abcdefghijklm"     , OLED_C, 2);    // Выводим текст по центру 2 строки.
    myOLED.print( "nopqrstuvwxyz"     , OLED_C, 3);    // Выводим текст по центру 3 строки.
    myOLED.print( "абвгдеёжзийклмноп" , OLED_C, 5);    // Выводим текст по центру 5 строки.
    myOLED.print( "рстуфхцчшщъыьэюя"  , OLED_C, 6);    // Выводим текст по центру 6 строки.
    delay(3000);                                       // Ждём 3 секунды.
                                                       //
    myOLED.clrScr();                                   // Чистим экран.
    myOLED.print( "Символы:"          ,      0, 0);    // Выводим текст начиная с 0 столбца 0 строки.
    myOLED.print( "{}[]()<>?!#$%&*"   , OLED_C, 3);    // Выводим текст по центру 3 строки.
    myOLED.print( "~`'\"^_-+=,.:;|/"  , OLED_C, 5);    // Выводим текст по центру 5 строки.
    delay(3000);                                       // Ждём 3 секунды.
                                                       //
    myOLED.clrScr();                                   // Чистим экран.
    myOLED.print( "Цифры:"            ,      0, 0);    // Выводим текст начиная с 0 столбца 0 строки.
    myOLED.print( "1234567890"        ,      6, 2);    // Выводим текст начиная с 6 столбца 2 строки.
    myOLED.print( 1234567890          ,      6, 3);    // Выводим число начиная с 6 столбца 3 строки.
    myOLED.print(-1234567890          ,      0, 4);    // Выводим число начиная с 0 столбца 4 строки.
    myOLED.print( 12345.7890          ,      6, 5);    // Выводим число начиная с 6 столбца 5 строки.
    delay(3000);                                       // Ждём 3 секунды.
}                                                      //

Алгоритм работы программы:

В коде setup() происходит инициализация дисплея (подготовка дисплея к работе) и подключение шрифта «SmallFontRus» (в библиотеке имеется несколько предустановленных шрифтов, которые подключаются перед использованием). Со списком шрифтов и описанием всех функций библиотек iarduino_OLED и iarduino_OLED_txt, можно ознакомиться в разделе Wiki - OLED экран 128×64 / 0,96”.

Код loop() разбит на 4 части. Каждая часть начинается с очистки экрана функцией clrScr(), после чего следуют несколько функций print() для вывода текста или чисел на экран дисплея. Все части выполняются друг за другом с 3 секундной задержкой выполняемой функциями delay().

В результате на дисплее поочерёдно будут появляться: большие буквы (включая Русские), маленькие буквы (включая Русские), символы и цифры.

Проблемы при выводе Русских букв:

Кодировка:

Первая и основная проблема это кодировка в которой скетч передаётся компилятору. Разные версии Arduino IDE хранят скетч в различных кодировках. Даже последняя версия Arduino IDE 1.8.5 (на момент написания данного урока) для ОС Windows, передаёт компилятору скетч в кодировке UTF-8 (если скетч был сохранён в файл *.ino) или в кодировке Windows-1251 (если скетч не был сохранён). Но ни скетч, ни библиотеки используемые в нём, не знают в какой кодировке они будут переданы компилятору. Вот и получается что один и тот же скетч, оперируя Русскими буквами, может работать по разному.

Примечание:

Что такое кодировка? Компьютер, как и контроллер (в т.ч. Arduino) хранит, получает и передаёт данные в виде 1 и 0. Из набора 1 и 0 можно точно составить числа, но нельзя однозначно составить буквы. Кодировка это представление букв числами (по их порядковому номеру), которыми уже может оперировать компьютер или контроллер. Например, «А» - 1, «Б» - 2, «В» - 3 и т.д., тогда слово «ПРИВЕТ» можно передать, принять или сохранить, как набор чисел: 17,18,10,3,6,20. Так как буквы можно располагать по разному (сначала символы или числа, или буквы другого языка и т.д.), то и порядковые номера (числа) у букв будут разные, вот и получилось, что придумано множество кодировок. Исторически сложилось что Латинские буквы имеют одинаковые порядковые номера в большинстве кодировок: «A»...«Z» = 65...90, «a»...«z» = 97...122, а Кириллические буквы не только имеют различные номера, но могут быть разбросаны, или вообще отсутствуют в кодировках.

Решение:

В библиотеках iarduino_OLED и iarduino_OLED_txt, мы предусмотрели функцию setCoding(), которая может принимать в качестве единственного аргумента, одно из значений: TXT_UTF8, TXT_CP866, TXT_WIN1251, определяющее текущую кодировку скетча. Эта функция закомментирована в 3 строке кода setup программы данного урока. Если Русский текст на дисплее отображается некорректно, то раскомментируйте строку с функцией setCoding и замените параметр TXT_UTF8, на TXT_CP866 или TXT_WIN1251. В большинстве случаев это решит проблему кодировок.

myOLED.setCoding(TXT_WIN1251);            // Указываем что текст скетча представлен в кодировке Windows-1251.

Если функция setCoding() Вам не помогла, тогда вызовите функцию setCoding() с параметром false, а Русские буквы указывайте их кодом, как это показано в следующем разделе данного урока: «Недостаточно памяти». При желании укажите в комментариях к уроку свою версию ОС, версию Arduino IDE и какую кодировку использует Ваша Arduino IDE (если Вы не знаете какую кодировку использует Arduino IDE, то напишите какие символы отображаются на дисплее вместо строчных и прописных Русских букв). Мы постараемся добавить Вашу кодировку в библиотеки.

Недостаточно оперативной памяти:

Вторая, но не менее важная проблема заключается в том, что строки занимают много оперативной памяти. Каждая буква строки занимает минимум 1 байт. Особенно актуальна эта проблема при создании различных пунктов меню.

Решение:

Наиболее эффективным решением данной проблемы является хранение строк не в области оперативной памяти, а в области памяти программ, так как объем памяти программ гораздо больше. Для этого указывайте строки в качестве аргумента функции F(). Строки указанные таким образом будут храниться в области памяти программ:

myOLED.print( F("Строка для дисплея") );  // Вывод строки на дисплей.
Serial.print( F("Строка для монитора") ); // Вывод строки в монитор последовательного порта.

Недостаточно оперативной памяти или памяти программ:

Если Вы работаете со строками на Русском языке в Arduino IDE, которая хранит скетч в кодировке UTF-8. Вы уже храните строки в области памяти программ (или оставили строки в области оперативной памяти). Вы все равно можете освободить до половины памяти занимаемой строками!

Дело в том, что в кодировке UTF-8 каждая Русская буква занимает целых 2 байта. Если указывать Русские символы кодом в той кодировке, где они занимают 1 байт, можно освободить половину памяти занимаемой строками, вне зависимости от того, в каком типе памяти они хранятся.

Символы в шрифтах для библиотек iarduino_OLED и iarduino_OLED_txt располагаются в соответствии с кодировкой CP866, значит хранить и выводить Ваши строки на экран дисплея можно в этой кодировке:

myOLED.setCoding(false);                               // Отменяем текущую кодировку, так как Русские буквы будем указывать кодом.
myOLED.print("\200\340\244\343\250\255\256 iArduino"); // Выводим текст "Ардуино iArduino". Вместо Русских букв используем их код в кодировке CP866.

Примечание:

Как указывать символ или букву по его коду в строках скетчей? Для начала нужно узнать коды всех символов той кодировки, в которой Вы желаете их указывать, таблицы символов различных кодировок можно найти в интернете. Для кодировки CP866, Русские символы имеют следующие коды:

А128 \200И136 \210Р144 \220Ш152 \230а160 \240и168 \250р224 \340ш232 \350Ё240 \360
Б129 \201Й137 \211С145 \221Щ153 \231б161 \241й169 \251с225 \341щ233 \351ё241 \361
В130 \202К138 \212Т146 \222Ъ154 \232в162 \242к170 \252т226 \342ъ234 \352242 \362
Г131 \203Л139 \213У147 \223Ы155 \233г163 \243л171 \253у227 \343ы235 \353243 \363
Д132 \204П140 \214Ф148 \224Ь156 \234д164 \244м172 \254ф228 \344ь236 \354244 \364
Е133 \205Н141 \215Х149 \225Э157 \235е165 \245н173 \255х229 \345э237 \355245 \365
Ж134 \206О142 \216Ц150 \226Ю158 \236ж166 \246о174 \256ц230 \346ю238 \356246 \366
З135 \207П143 \217Ч151 \227Я159 \237з167 \247п175 \257ч231 \347я239 \357247 \367

Для вывода любого символа нужно указать его код в 8-ричной системе счисления, которому должен предшествовать обратный слеш «\». Данное правило действует для любых строк в Arduino IDE. В строке «Ардуино iArduino» из примера выше, первая буква - «A», имеет код 128. Если перевести 128 в 8-ричную систему счисления, получится (200)8. Значит букву «А» можно записать как «\200», букву «р» как «\340», букву «д» как «\244» и т.д.

Для перевода чисел из 10-тичной в 8-ричную систему предлагаем воспользоваться стандартным калькулятором Windows. Откройте калькулятор, выберите вид калькулятора - «Программист» и введите число, Вы увидите его представление в разных системах счисления: HEX(16), DEC(10), OCT(8) и BIN(2).

Но если Вы желаете научиться быстро переводить числа между системами счисления 2, 4, 8, 10, 16, без калькулятора, то посмотрите Урок 32 - перевод чисел между системами счисления.

Ссылки:

Комплект для повторения проекта

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

Это быстрый ориентир по основным модулям и деталям. Полный список для повторения проекта смотрите в самой статье.

4 позиции
Все уроки Arduino