ВИДЕО редактируется.
Вы могли наблюдать, что в предыдущих уроках №7 и №8 уже использовался Русский шрифт. В этом уроке мы разберём некоторые проблемные моменты с которыми можно столкнуться при выводе Русских букв на OLED дисплей.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema OLED дисплей х 1шт.
- Trema Shield или Trema Set Shield х 1шт.
Для реализации проекта нам необходимо установить библиотеки:
- Библиотека 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 |
Схема установки дисплея при его подключении через 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 \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 - перевод чисел между системами счисления.
Обсуждение