КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

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

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

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

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

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

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

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

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

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

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

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

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

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

#include <iarduino_OLED_txt.h>                         // Подключаем библиотеку iarduino_OLED_txt.
iarduino_OLED_txt myOLED(0x78);                        // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x78 (если учитывать бит RW=0).
                                                       //
extern 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
\352

242
\362
Г 131
\203
Л 139
\213
У 147
\223
Ы 155
\233
г 163
\243
л 171
\253
у 227
\343
ы 235
\353

243
\363
Д 132
\204
П 140
\214
Ф 148
\224
Ь 156
\234
д 164
\244
м 172
\254
ф 228
\344
ь 236
\354

244
\364
Е 133
\205
Н 141
\215
Х 149
\225
Э 157
\235
е 165
\245
н 173
\255
х 229
\345
э 237
\355

245
\365
Ж 134
\206
О 142
\216
Ц 150
\226
Ю 158
\236
ж 166
\246
о 174
\256
ц 230
\346
ю 238
\356

246
\366
З 135
\207
П 143
\217
Ч 151
\227
Я 159
\237
з 167
\247
п 175
\257
ч 231
\347
я 239
\357

247
\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 - перевод чисел между системами счисления.

Ссылки:




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями