Андрей Смирнов
Время чтения: ~11 мин.
Просмотров: 8

Подключение OLED дисплея I2C к NANO и вывод Русского шрифта

OLED_I2C

описание библиотеки для использования в Arduino oled дисплея на контроллере SSD1306 с I2C на русском языкеoled_bw1.jpgСкачать:   на официальном сайте       зеркало1    зеркало2

Определенные литералы:

ВыравниваниеИспользуется совместно с print(), printNumI() and printNumF()LEFT:   0RIGHT:  9999CENTER: 9998

Встроенные шрифты:

TinyFonttinyfont.jpgРазмер символа: 6 х 8 пикселейКоличество символов: 95SmallFont:SmallFont.jpgРазмер символа: 4 х 6 пикселейКоличество символов: 95MediumNumbers:Размер символа: 12 х 16 пикселейКоличество символов: 13BigNumbers:Размер символа: 14 х 24 пикселейКоличество символов: 13

Функции:

OLED(Data, Clock, [Reset]);Инициализация библиотеки с помощью интерфейса I2CПараметры:Data: Вывод подключения SDA-пина (данные)Clock: Вывод подключения SCL-пина (тактирование)Reset: Выбод подключения сброса <необязательный параметр>Пример: OLED myOLED(SDA, SCL); // Инициализация библиотеки с помощью интерфейса I2C TWI/I2C без сброса контроллера дисплеяbegin();Инициализация дисплеяПараметры: НетПример: myOLED.begin(); // Инициализация дисплеяПримечания: Данная функция выполняет сброс (при подключенном выводе сброса) и очистку дисплея.setBrightness(value);Установка яркости дисплея.Параметры: value: Указание значение яркости (0-255)Пример: myOLED.setBrightness(207); // Установка значения яркости, равным 207 (значение  по умолчанию)Примечание: Следует отметить, что шаг регулирувки яркости очень мал и может быть не заметенupdate();Копирование буфера экрана на экран.Это единственная команда, кроме invert() и setBrightness(), которые изменяют изображение на физическом экране. Все остальные команды изменяют буфер экрана.Параметры: НетПример: myOLED.update(); // Скопировать содержимое буфера экрана на экранПримечание: Не забывайте выполнять update() после того, как Вы сделали изменения в буфере экрана.clrScr();Очистка буфера экранаПараметры: нетПример: myOLED.clrScr(); // Очистка буфера экранаfillScr();Заполнение буфера экрана.Параметры: нетПример: myOLED.fillScr(); // Заполнить буфер экранаinvert(mode);Инвертировать изображение на экранеПараметры:mode:true — инверсное изображение            false — нормальное изображениеПример: myOLED.invert(true); // Изображение на экране инвертноеsetPixel(x, y);Включение указанного пикселя в буфере экрана,Параметры:      х: координата пикселя по горизонтали     y: координата пикселя по вертикалиПример: myOLED.setPixel (0,0); // Включить верхний левый пиксель (в буфере экрана)clrPixel(x,y);Выключение указанного пикселя в буфере экрана,Параметры:      х: координата пикселя по горизонтали     y: координата пикселя по вертикалиПример: myOLED.clrPixel(0,0); // Выключить верхний левый пиксель (в буфере экрана)invPixel(x,y);Инвертировать состояние указанного пикселя в буфере экранаПараметры:      х: координата пикселя по горизонтали     y: координата пикселя по вертикалиПример: myOLED.invPixel(0, 0); // Инвертировать верхний левый пиксель (в буфере экрана)print(st, x, y);Распечатать строку в указанных координатах в буфере экранаМожно использовать как литералы LEFT, CENTER и RIGHT, так и числовые координаты, чтобы выровнять строку на экране.Параметры:     st: строка для печати     x: координата верхнего левого угла первого символа по горизонтали     y: координата верхнего левого угла первого символа по вертикалиПример: myOLED.print(«Hello World»,CENTER,0); // Печать строки «Hello World» по центру в верхней части экрана (в буфере экрана)Примечания: Строка для печати может быть либо массив символов или строковый объектprintNumI(num, x, y[, length[, filler]]);Распечатать целое число в указанных координатах в буфере экрана.Можно использовать как литералы LEFT, CENTER и RIGHT, так и числовые координаты, чтобы выровнять строку с числом на экране.Параметры:     num: Число для вывода на экран (от -2147483648 до 2147483647). Допускаются только ЦЕЛЫЕ числа     x: координата верхнего левого угла первой цифры/знака по горизонтали     y: координата верхнего левого угла первой цифры/знака по вертикали     length: <необязательный параметр> минимальное количество цифр / символов (включая знак) для отображения на экране     filler:<необязательный параметр> Символ для заполнения, чтобы получить минимальную длину.Символ будет вставлен перед номером, но после знака. Умолчанию » » (пробел).Пример: myOLED.printNumI(num,CENTER,0); // Печать значения переменной «num» по центру в верхней части экрана (в буфере экрана)printNumF(num, dec, x, y[, divider[, length[, filler]]]);Распечатать число с плавающей точкой в указанных координатах в буфере экрана.Можно использовать как литералы LEFT, CENTER и RIGHT, так и числовые координаты, чтобы выровнять строку с числом на экране.Внимание: Числа с плавающей точкой имеют погрешность при округлении и могут давать неверные результаты при сравнении. Используйте на свой страх и риск.Параметры:     num: Число для вывода на экран     Dec: количество цифр после запятой (в дробной части) (допустимые значения 1-5). Число 0 не поддерживается, для этого используйте printNumI ()     x: координата верхнего левого угла первой цифры/знака по горизонтали     y: координата верхнего левого угла первой цифры/знака по вертикали     divider:<необязательный параметр> Одиночный символ для использования в качестве десятичной точки. По умолчанию ‘.’     length:<необязательный параметр> минимальное количество цифр / символов (включая знак) для отображения на экране     filler:<необязательный параметр> Символ для заполнения, чтобы получить минимальную длину.Символ будет вставлен перед номером, но после знака. Умолчанию » » (пробел).Пример: myOLED.printNumF(num, 3, CENTER,0); // Печать значения переменной «num» с 3-мя знаками после запятой по центру в верхней части (в буфере экрана)Примечания: Поддерживаемые диапазон зависит от количества цифр в дробной части.Диапазон приблизительный +/- 2 * (10 в степени 9) — для десятичной системы.invertText(mode);Инвертировать текст на экранеПараметры:mode — true — инверсное изображение             false — нормальное изображениеПример: myOLED.invertText(true); // Изображение текста инвертноеПримечания: функция SetFont() отключает инвертный режимsetFont(fontname);Выбор шрифта для использования совместно с Print(), printNumI() и printNumF()Параметры:     fontname: Имя массива, содержащий шрифт, для использованияПример: myOLED.setFont(SmallFont); // Выбор шрифт под названием SmallFontПримечания: Перед использованием необходимо объявить массив со шрифтом  в качестве внешнего или включить его в свой скетч.

В очередном своём проекте я решил использовать китайский OLED дисплей разрешением 128х64 точки с интерфейсом подключения I2C.

Но после курения весьма немногочисленных и однотипных гайдов по работе с такими экранами я понял, что круче руководств как подключить его к дуньке (4 провода, смех) и вывода на него стандартного примера, ничего во всеобъемлющем интернете толком то и нет… Да и ещё у него есть такой недостаток как скудность стандартных шрифтов – в стандартной библиотеке их всего 5, два из которых буквенные и три циферные, причём самый большой циферный выполнен в каком-то псевдоготическом стиле.

В общем ни один из стандартных шрифтов мне не подходил категорически. Ну чтож, подумал я, значит надо сделать свой шрифт с блекджеком и шлюхами. Дело за малым – найти гайд и бабахнуть. Но тут всплыла ещё одна проблема – гайдов по этому делу нет, только ссылки на мёртвые сайты, хождения вокруг да около, троллинг, закольцованные комментарии. Ныть на форумах я не собирался, ожидая что кто-то сделает всю работу за меня, поэтому принял решение расковырять библиотеку, а конкретнее файл DefaultFonts.c, лежащий в её папке. Итак, открываем его и видим портянку из шестнадцатеричного кода с комментами.

Ну думаю круто, сейчас возьму фотошоп, нарисую в монохроме шрифт, загоню его в прогу конвертер картинок в хекс-код, забью в наш DefaultFonts.c и дело в шляпе. Ок, рисую шрифт 20х40:

Сохраняю в картинку каждый символ, перегоняю его в хекс с помощью DotFactory (скрин наспех, делал уже потом, для данного поста, восьмёрка кривая, как видно по визуализатору, не исправлял настройки программы):

Вставляю в файл шрифта, в скопированный блок с новообозванным шрифтом. Затем загружаю в ардуино тестовый скетч и получаю сраку на дисплее (фото не делал, там просто россыпь хаотичных пикселей, как будто гном чихнул).

Значит не так всё просто как кажется… В конечном итоге разобрался и опишу процесс пошагово на примере одного символа.

Начну пожалуй с того, что каждый шрифт в файле DefaultFonts.c представляет собой блок с заголовком в виде:

Где MediumNumbers — имя шрифта, а набор из четырёх байтов — параметры. Итак по порядку:

0x0c — ширина шрифта, в данном случае 12 пикселей

0x10 — высота шрифта, тут равна 16ти пикселям

0x2d — порядковый номер первого символа согласно таблице ASCII

0x0d — общее количество символов в шрифте (блоке)

Теперь постараюсь ещё подробнее, чтобы не извращаться с дорисовкой ноликов, ширину принимаем кратной 4ке, то есть 4, 8, 12, 16 и тд. С высотой попроще, позже объясню как правильно её корректировать. Количество символов наверное можно не объяснять, в данном примере она равна 13ти и можно тупо посчитать строки — их ровно 13, справа даже комментарии есть какой символ зашифрован. По поводу кода символа согласно ASCII — ниже таблица, например если нужно чтобы шрифт начинался с двойки — пишем 0x32 (50 номер в десятичной), если например с буквы Q — пишем 0x51 (81 в десятичной).

В данном примере сделаем шрифт из одного символа, с размерами 24х32, который будет печататься на экран вместо цифры «0». Так как все делают метеостанции и умные дома, то решил нарисовать наспех такой символ:

Заметьте, картинка 24х30 пикселей, нестандартная высота для примера, цвет неважен. Хоть сине-зелёную сделайте.

Дальше валим её набок вправо, затем делим её справа налево на колонки по 8 пикселей, открываем любой текстовый редактор (или тетрадку). Я предпочитаю обычный Microsoft Word, где делаю таблицу из двух колонок — в первой у нас будут двоичные числа, во второй — перевод в 16тиричную. В принципе всё видно на картинках ниже:

Забиваем в таблицу числа в виде ХХХХХХХХ (8 бит или 1 байт) согласно заполненности цветом, у меня белый — 0, чёрный — 1. Занятие муторное, но нормальных программ для этого дела я не нашёл, наверное плохо искал.

В итоге получаем 4 блока, нумерация идёт справа налево, повторюсь. В фотошопе прекрасно видно — фон как раз таки состоит из клеток 8х8 пикселей.

После того, как все значения записаны в двоичном коде — переводим их в шестнадцатиричную систему счисления, я делаю это с помощью калькулятора из 10ой винды, можно приспособить любой онлайн конвертер или прогу BinDecHex. В принципе наверное можно забить в файл шрифтов и в двоичном коде, но я не пробовал, можете попробовать и отписаться. В двоичном формате наверняка портянка получится дай боже.

Не забываем отделять все числа запятыми!

Когда мучения закончатся — вставляем полученное содержимое в файл DefaultFonts.c в новый свеженький блок:

Обзовём шрифт Symbol, параметры будут «0x18, 0x20, 0x30, 0x01,» что равнозначно 24х32 пикселя, 48 стартовый номер (цифра «0») и всего 1 символ в шрифте.

Далее осталось дело за малым — накидать скетч и залить в ардуино:

В итоге получаем это:

Толком сфокусироваться не смог, дисплей слишком контрастный, да и поздно было) Но в принципе видно что всё у нас вышло.

Как обычно замечу что на гениальность не претендую, возможно есть способы быстрее и продуктивнее. Но этот пост позволит разобраться в принципах формирования шрифта в этой библиотеке. Гайд не исчерпывающий и для меня остались некоторые пробелы — почему например нельзя сделать шрифт произвольного размера, допустим 37х21. Если ответ на этот вопрос появится в комментариях — буду рад. Так же если имеются дополнения и вопросы — пишите, не стесняйтесь.

554

Модули

Все модули

Модуль потенциометра

Модуль энкодера

Модуль micro SD карты

Модуль SD карты

Модуль RGB-светодиода

Модуль RGB-светодиода (Keyestudio)

Модуль светодиода

Силовой ключ

Модуль лазера

Матричная клавиатура 4х1

Матричная клавиатура 3х4

Матричная клавиатура 4х4

Модуль кнопки

Модуль светодиода «пиранья»

Расширитель I2C (хаб)

Модуль адресных светодиодов (х4)

Модуль часов DS-1302

Модуль часов с автономным питанием DS-3231

Модуль часов PCF8563

Модуль зуммера

Джойстик PS2

Модуль измерения напряжения

Концевой переключатель

Датчики

Все датчики

Датчик температуры и влажности DHT-11

Датчик температуры и влажности DHT-22

Датчик температуры DS18B20 (датчик, герметичный датчик, модуль датчика)

Модуль для герметичного датчика температуры

Аналоговый датчик температуры TMP36

Ультразвуковой дальномер HC-SR04

Ультразвуковой дальномер US-015

Модуль инфракрасного датчика движения HS-SR501

Датчик уровня жидкости угловой

Датчик уровня жидкости прямой

Инфракрасный датчик препятствия (аналоговый)

Инфракрасный датчик препятствия (цифровой)

Модуль 4-х датчиков препятствия

Модуль датчика пламени

Датчик наклона

Датчик вибрации аналоговый

Датчик вибрации цифровой

Датчик влажности почвы

Модуль датчика дождя

Датчик уровня жидкости

Датчик освещенности

Датчик звука

Модуль датчика углеводородных газов MQ-2

Модуль датчика паров спирта MQ-3

Модуль датчика газа MQ-5

Модуль датчика угарного газа MQ-7

Модуль датчика газа MQ-135

Датчик линии TCRT5000 аналоговый

Датчик линии TCRT5000 цифровой

Модуль датчика Холла (Keyestudio)

Датчик жидкости

Инфракрасный датчик контроля KB874

Связь

Все модули связи

Комплект беспроводной RF 315MHz

Комплект беспроводной RF 433MHz

WiFi модуль ESP12

Беспроводной приемопередатчик NRF24L01+ 2,4GHz

Беспроводной приемопередатчик NRF905

Инфракрасный приемник VS1838B и Модуль инфракрасного приемника VS1838B

Модуль инфракрасного приемника TSOP4838

Модуль инфракрасного передатчика

Шилды

Все шилды

Motor Shield (SmartElements)

Motor Drive Shield L293D

Relay shield

Sensor shield (SmartElements)

Sensor shield v5.0

Power Shield

Ethernet shield

Uno Protoshield

Дисплеи

Все дисплеи

Модуль 4 — разрядного индикатора

OLED Дисплей 0,96′ (128×64) I2C

Дисплей 2,4′ TFT LCD 240х320

Дисплей 3,5′ TFT LCD 320х480

Моторы, драйверы, шасси

Все моторы, драйверы, шасси

Вибромотор

Шасси 2WD SmartElements

Драйвер моторов TB6612

Материалы и статьи

Все статьи

Установка Arduino IDE (среда разработки)

Подключение и настройка контроллера

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

Как прошить загрузчик для контроллеров линейки Mini

Использование UNO в качестве конвертера для плат линейки Mini

Определение адреса I2C устройства

Энергонезависимая память Arduino

Режимы сна и энергосбережение

Если что-то пошло не так …

Все статьи

Возможные неисправности при работе с контроллерами

Что-то пошло не так с наборами «Смарт 10», «Смарт 20», «Смарт 30»

Что-то пошло не так с набором «Смарт Робо»

Что-то пошло не так с набором «МиниБот»

Используемые источники:

  • http://mynobook.blogspot.com/2016/11/oledi2c.html
  • https://pikabu.ru/story/svoy_tekst_dlya_oled_128x64_4834291
  • http://know.smartelements.ru/doku.php

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации