В одном из китайских наборов попался дисплей, который в описании числился как "0.96inch OLED SPI display". Больше никакой информации не было. Пришлось искать в интернете что-то похожее по картинке и пробовать разные варианты.
При поиске обнаружилось, что вариантов очень много. И разное число выводов, и разные подписи к выводам, и разный внешний вид и т.д и т.п. Один из примеров оказался для меня рабочим, хотя вполне возможно, что есть и другие способы работы с подобным дисплеем.
Для начала приведу таблицу возможных названий к выводам.
Выводы | Альтернативные имена | Описание |
---|---|---|
VCC | Power supply | |
GND | Ground | |
D0 | SCL, CLK, SCK | Clock |
D1 | SDA, MOSI | Data |
RES | RST, RESET | Rest |
DC | A0 | Data/Command |
CS | Chip Select |
В моём случае было GND | VCC | SCL | SDA | RES | DC. Подключал по схеме:
Библиотека U8glib
Дальше скачал библиотеку U8glib через менеджер библиотек. Кстати, на Гитхабе написано, что библиотека больше не развивается и нужно переходить на другую библиотеку U8g2. Но я прочитал об этом уже после того, как поработал со старой библиотекой, поэтому пока отложил знакомство с новой версией.
После установки библиотеки стало доступно множество различных примеров.
Во всех примерах вначале идёт длинный список закомментированных конструкторов, один из которых нужно раскомментировать.
Впечатляет, не так ли? И это только часть списка, расширенный список можно найти на Гитхабе. Проблема в том, что я не знал, какой вариант нужен именно мне. В одном из видео на Ютубе я нашёл похожий внешне на мой дисплей пример и решил следовать ему. Именно по тому ролику я и подключил дисплей по схеме, которую приводил выше.
Выбираем нужный конструктор.
Признаться, пример ввёл меня в ступор. Во-первых, в скетчах я не нашёл варианта, который демонстрировался в ролике и я вводил свой вариант вручную. Во-вторых, в конструкторе указывался вывод 10, который в реальности не использовался. Тем не менее примеры работали!
Нет смысла приводить код примеров, приведу только название простых скетчей, которые можно сразу протестировать.
Потом попробовал вариант другого конструктора, который также заработал.
Русский язык дисплей не поддерживает. Надо попробовать новую версию библиотеки.
Библиотека U8g2
Сейчас развивается новая библиотека U8g2 от того же автора. После установки я попробовал вариант конструктора:
Пример заработал, но как подключить русскую кодировку, я не разобрался.
Также есть и другие библиотеки от других производителей, например, от Adafruit. Пример работы с поддержкой русского языка (надо заменить один файл).
Вообще, от дисплея размером 0.96 дюйма остались двоякие ощущения. Экран настолько мал и текст настолько мелкий, что подойдёт только для людей с нормальным зрением. Как вариант, можно выводить символ крупным шрифтом, например, цифры.
Одно из больших достоинств библиотеки u8glib помимо всех прочих — большое количество готовых шрифтов. К сожалению, кириллических шрифтов среди них не так много, но все-таки русские шрифты есть, их можно найти.
В названии шрифтов (т. е. в именах двоичных массивов, где имеются данные шрифтов) присутствуют суффиксы, которые дают краткую характеристику шрифта (b, n, r и т. п., см. описание суффиксов ниже). Суффикс может быть составной, например br означает жирный урезанный шрифт.
r означает reduced, т. е. уменьшенный знакогенератор. Обычно набор символов ограничен сверху, т. е. символы с кодами 128..255 отсутствуют. Хорошо подходит для систем, где не нужно выводить русские буквы или когда есть жесткие ограничения по объему памяти.
n означает numberic, т. е. цифровые символы (коды 42 .. 57). Обычно это только символы ^+,-./0123456789:. Знак % отсутствует.
b или B означает bold, т. е. "толстые" символы. Если шрифт мелкий, то символы будут угловатые, "квадратные".
O означает наклонный шрифт, italic.
67_75, 78_79 наборы графических символов.
Некоторые символы сделаны так, что они хорошо масштабируются вверх при отображении (например u8g_font_trixel_square). Это позволяет очень экономить на памяти.
Цифры в названии шрифта в формате NNxMM означают размер окружающего символ прямоугольника по X и по Y. Например, имя u8g_font_10x20r говорит нам о том, что максимальный размер символа по горизонтали 10 точек, по вертикали 20, и что шрифт имеет урезанный набор символов (обычно с кодами не более 127).
Название шрифта | Модификации | Описание |
u8g_font_04b_03 | b, n, r, bn, br | Очень маленькие буковки. Символы 128..255 заявлены, но графики на самом деле нет (т. е. это фактически то же самое, что и вариант r). Вариант b имеет весьма угловатые символы. |
u8g_font_04b_24 | r, n | Очень маленькие буковки. |
u8g_font_10x20_67_75 | Графические символы. Шрифт можно использовать для стрелочек, чекбоксов, вращающегося прогресса, закраски штриховкой и т. п. | |
u8g_font_10x20_75r | Графические символы те же, что и в u8g_font_10x20_67_75, только их меньше. | |
u8g_font_10x20_78_79 | Тоже графические символы. | |
u8g_font_10x20 | r | Крупные символы, русифицированный шрифт. |
u8g_font_4x6 | r | Возможно самый мелкий шрифт из всех, русифицированный. |
u8g_font_5x7 | r | Мелкие символы, не русифицированный шрифт. |
u8g_font_5x8 | Мелкие символы, но разборчивые, русифицированный шрифт. | |
u8g_font_6x10 | r | Русифицированный шрифт, подойдет для текста. |
u8g_font_6x12_67_75 | u8g_font_6x12_75r | Графические символы. То же самое, что и u8g_font_10x20_67_75, только мелкие. |
u8g_font_6x12_78_79 | То же самое, что и u8g_font_10x20_78_79, только мелкие графические символы. | |
u8g_font_6x12 | r | Обычный русифицированный шрифт. Больше всего подходит для консоли. Модификация r не содержит коды символов больше 127 (нет русских букв). |
u8g_font_6x13_67_75 | u8g_font_6x13_75r | То же самое, что u8g_font_10x20_67_75, только мелкий. |
u8g_font_6x13_78_79 | То же самое, что и u8g_font_10x20_78_79. | |
u8g_font_6x13 | B, Br, O, Or, r | Не русифицированный шрифт среднего размера. |
u8g_font_7x13_67_75 | u8g_font_7x13_75r | Графические символы. То же самое, что и u8g_font_10x20_67_75, только мелкие. Заметил, что нет промежутков между символами. |
u8g_font_7x13 | B, Br, O, Or, r | |
u8g_font_7x14 | B, Br, r | |
u8g_font_8x13_67_75 | u8g_font_8x13_75r | Графические символы. То же самое, что и u8g_font_10x20_67_75, только средние. |
u8g_font_8x13 | Br, Or, r | Символы среднего размера, тонкие линии, русифицированный. |
u8g_font_9x15_67_75 | u8g_font_9x15_75r | |
u8g_font_9x15_78_79 | ||
u8g_font_9x15Br | u8g_font_9x15r | |
u8g_font_9x18_67_75 | u8g_font_9x18_75r | |
u8g_font_9x18_78_79 | ||
u8g_font_9x18Br | u8g_font_9x18r | |
u8g_font_baby | n, r | Мелкий округлый шрифт, не русифицированный. Высота символа 6 точек. |
u8g_font_blipfest_07 | n, r | Супермелкий шрифт, по размеру похож на u8g_font_4x6, но не русифицирован. Высота символа шрифта 5 точек, ширина обычно 3 точки. |
u8g_font_chikita | n, r | Мелкий широкий шрифт, не русифицированный. |
u8g_font_courB | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24r, 24n | Courier, не русифицированный. Цифры в модификациях соответствуют размерам. |
u8g_font_courR | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24r, 24n | |
u8g_font_cu12_67_75 | u8g_font_cu12_75r | |
u8g_font_cu12 | Оригинальный не русифицированный, символы довольно крупные. | |
u8g_font_cursor | r | Очень крупные графические символы (особенные), с большими отступами по Y и смещениями по X. |
u8g_font_fixed_v0 | n, r | Не русифицированный, угловатый, довольно мелкий шрифт. |
u8g_font_freedoom | r10r, r25n | Квадратные символы среднего размера, урезанный шрифт (без русских букв). |
u8g_font_fub | 11, 11n, 11r, 14, 14n, 14r, 17, 17n, 17r, 20, 20n, 20r, 20t, 25, 25n, 25r, 30, 30n, 30r, 35n, 42n, 49n | Семейство не русифицированных шрифтов |
u8g_font_fur | 11, 11n, 11r, 14, 14n, 14r, 17, 17n, 17r, 20, 20n, 20r, 25, 25r, 30, 30n, 30r, 35n, 42n, 49n | Обычный по виду шрифт, не русифицированный. |
u8g_font_gdb | 11, 11n, 11r, 12, 12n, 12r, 14, 14n, 14r, 17, 17n, 17r, 20, 20n, 20r, 25, 25n, 25r, 30, 30n, 30r, 35n, 42n, 49n | Красивый шрифт, не русифицированный. |
u8g_font_gdr | 9, 9n, 9r, 10, 10n, 11, 11n, 11r, 12, 12n, 12r, 14, 14n, 14r, 17, 17n, 17r, 20, 20n, 20r, 25, 25n, 25r, 30, 30n, 30r, 35n, 42n, 49n | |
u8g_font_helvB | 08, 08n, 08r, 10, 10n, 10r, 11, 11n, 11r, 12, 12n, 12r, 14, 14n, 14r, 18, 18n, 18r, 24, 24n, 24r | helvetica, не русифицированный. |
u8g_font_helvR | 08, 08n, 08r, 10, 10n, 10r, 12, 12n, 12r, 14, 14n, 14r, 18, 18n, 18r, 24, 24n, 24r | helvetica, не русифицированный. |
u8g_font_lucasfont_alternate | r, n | Мелкий шрифт, не русифицированный, довольно симпатичный. |
u8g_font_m2icon | _5, _7, _9 | Графика, мелкий набор, есть галочка для чекбокса и радиокнопки. |
u8g_font_micro | Супермелкий шрифт, в кодах 128..255 пустота. | |
u8g_font_ncenB | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24n, 24r | Красивые толстенькие символы, но шрифт не русифицированный. |
u8g_font_ncenR | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24n, 24r | |
u8g_font_orgv01 | n, r | Квадратный, мелкий и широкий шрифт, не русифицированный. Высота символа шрифта 5 точек, ширина обычно 5 точек. |
u8g_font_osb | 18, 18n, 18r, 21, 21n, 21r, 26, 26n, 26r, 29, 29n, 29r, 35, 35n, 35r | Крупный красивый шрифт, не русифицированный. |
u8g_font_osr | 18, 18n, 18r, 21, 21n, 21r, 26, 26n, 26r, 29, 29n, 29r, 35, 35n, 35r | Большие красивые символы, не русифицированные. |
u8g_font_p01type | n, r | Исключительно мелкие символы, не русифицированный, выше кода 127 есть пустоты. |
u8g_font_pixelle_micro | n, r | Еще один очень мелкий шрифт, выше кода 127 пустота. |
u8g_font_profont | 10, 10r, 11, 11r, 12, 12r, 15, 15r, 17, 17r, 22, 22r, 29, 29r | Обычный не русифицированный шрифт. |
u8g_font_robot_de_niro | n, r | Мелкий не русифицированный шрифт, выше 127 есть пустоты. |
u8g_font_symb | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24r | Шрифт с греческими символами и математической графикой. |
u8g_font_timB | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24n, 24r | Толстенький не русифицированный шрифт. |
u8g_font_timR | 08, 08r, 10, 10r, 12, 12r, 14, 14r, 18, 18r, 24, 24n, 24r | То же самое, что и u8g_font_timB, только линии тонкие. |
u8g_font_tpss | b, bn, br, n, r | Вытянутый вверх, не русифицированный шрифт. |
u8g_font_trixel_square | n, r | Еще один очень мелкий не русифицированный шрифт, выше 127 есть пустоты. Насколько я понял, этот шрифт разработан с учетом возможности его масштабирования вверх при отображении. |
u8g_font_u8glib_4 | r | Супермелкий не русифицированный шрифт. |
u8g_font_unifont | r, _0_10, _0_11, _0_8, _12_13, _18_19, _2_3, _4_5, _67_75, _72_73, _75r, _76, _77, _78_79, _86, _8_9 | Шрифт со спецграфикой. _0_10 такой же, как основной. _0_11 с особенной псевдографикой, не русифицированный. _0_8 шрифт со спецграфикой, среднего размера, есть русские символы. _12_13 "Арабская" псевдографика. _18_19, _2_3 какие-то спецсимволы. _4_5 Разные символы псевдографики. _67_75 графические символы те же, что и в u8g_font_10x20_67_75. _72_73 спецсимволы, есть в виде красивых кружочков с цифрами. _75r то же, что и _67_75, только урезан набор символов. _76 особенные символы графики. _77 другие особенные символы графики, есть игральные кости. _78_79 очень хороший набор символов графики. _86 символы графики, есть много стрелок, формат квадратный. _8_9 до 0x50 русские символы, выше графика и кракозябры. |
[Структура шрифта]
[U8G_FONT_DATA_STRUCT_SIZE][растровая графика шрифта]
Информация о рисуемом символе кэшируется в структуре u8g_t (см. поля glyph_dx, glyph_x, glyph_y, glyph_width, glyph_height). U8G_FONT_DATA_STRUCT_SIZE это специальный блок данных из 17 байт:
Байт, в котором закодирован формат шрифта.
Формат шрифта может быть 0, 1 или 2. От этого зависит размер структуры определения картинки (Glyph) символа шрифта. Я просмотрел все шрифты в модуле u8g_font_data.cpp, и оказалось что примерно половина шрифтов имеет тип 0 и примерно половина тип 1, других типов нет.
В настоящий момент в библиотеке u8glib реально имеется только 2 формата шрифтов 0 и 1. Формат 0 занимает в памяти 6 байт, а формат 1 только 3 байта. Достигается это тем, что в формате 1 данные, описывающие картинку шрифта, запакованы в старшей и младшей тетрадах байта. Если для обоих типов байт 0 формата равен 255, то это означает пустую картинку символа.
1 FONTBOUNDINGBOX width (unsigned). Байт, кодирующий ширину символа.
2 FONTBOUNDINGBOX height (unsigned). Байт, кодирующий высоту символа.
3 FONTBOUNDINGBOX x-offset (signed).
4 FONTBOUNDINGBOX y-offset (signed).
5 Высота заглавной ‘A’ (unsigned).
6 Начало в кодировке символа ‘A’.
8 Начало в кодировке символа ‘a’.
Функции u8g_font_GetFontStartEncoding, u8g_font_GetFontEndEncoding — извлекают из шрифта начальный и конечный коды символов, которые можно отобразить.
10 Начало кодировки, т. е. код первого символа в знакогенераторе.
11 Конец кодировки, т. е. код последнего символа в знакогенераторе.
12 descent ‘g’. Занижение для буквы g, отрицательное значение: ниже базовой линии.
13 max ascent для шрифта, т. е. максимальное завышение символа.
14 min decent для шрифта, т. е. максимальное занижение символа. Отрицательное значение: ниже базовой линии.
15 font xascent.
16 font xdecent. Может быть отрицательным значением.
[Как делать русифицированные шрифты для u8glib]
По ссылке [1] нашел вот такой рецепт:
Шрифт для U8G делается очень просто. Сначала создаете шрифт в формате .bdf (bitmap definition font). Затем с помощью утилиты bdf2u8g.exe конвертируете его в библиотечный формат. Есть очень неплохой редактор шрифтов — Fony, который умеет экспортировать в формат bdf. Кроме этого он умеет импортировать различные шрифтовые форматы. Т.е. с помощью описанной выше связки можно для библиотеки u8g создать практически любой шрифт без особых усилий. Правда шрифт 5×7 я так и не нашел откуда импортнуть, поэтому пришлось поработать.
Из командной строки запускаете:
bdf2u8g.exe my5x7rus_2.bdf my5x7rus my5x7rus.h
my5x7rus_2.bdf — имя исходного BDF-шрифта
my5x7rus — имя шрифта в библиотеке (т.е. это название будете указывать в процедуре u8g.setFont(fontname); т.е. для указанного вторым параметром my5x7rus, выбор шрифта будет осуществляться так: u8g.setFont(my5x7rus);
my5x7rus.h — имя выходного файла шрифта, который вы будете подключать в проект
1. Ставим Fontforge (если некорректно отображаются строки — удалить русскую локаль — будет английский).
2. Качаем шрифты BDF.
3. Так как русский в юникоде кодируется 2 байтами, а библиотека работает с однобайтовыми строками — юникод отпадает. Подойдет кодировка ISO8859-5, где английские и русские буквы ограничены одним байтом. Конвертим кодировку BDF c помощью fontforge, добавляем свои символы, если надо.
4. используя команды типа "bdf2u8g font/6×10.bdf u8g_font_6x10 utility/u8g_font_6x10.c" конвертим обратно, попутно удаляя дубликаты из "utility/u8g_font_data.c" или добавляем как новый в "utility/u8g.h" и кидаем рядом ".с".
5. записывать строки придется "xb0xb1xb2xb3" //АБВГ
Русские символы А..Я имеют коды 0xB0..0xCF, и символы а..я коды D0..0xEF. Кодировка текста Windows ANSI, которую использует VisualDSP, отличается тем, что А..Я имеют коды 0xC0..0xDF, и символы а..я коды E0..0xFF. Таким образом, чтобы отобразить шрифт VisualDSP по-русски, нужно от кода символа отнять 16.
Для вывода русского текста я написал специальную подпрограмму, которая по таблице определяет, какой это шрифт, русский или нет, и если русский, то вычитает из кода символа 16:
В статье постараюсь рассказать, как можно вывести некоторую информацию на LCD дисплей разрешением 128×64 пикселей. Будем выводить температуру и влажность датчиком DHT 11, время и дату с помощью модуля реального времени, уровень освещения двумя аналоговыми датчиками освещенности на фоторезисторах.
А как вывести картинку на такой дисплей узнаете здесь.
Начнем с подключения библиотек.
Библиотека U8glib — скачать
Библиотека dht11 — скачать
Библиотека RTClib — скачать
Далее производим объявление переменных.
Следующий шаг — назначение вводов и выводов.
Теперь нужно сделать прорисовку на дисплее. Сверху делаем белую строку сплошной закраски.
Устанавливаем шрифт, которым будем писать в этой самой строке. Его, кстати, тоже нужно скачать и поместить в папку библиотеки дисплея.
Шрифт LCD дисплея u8g_font_5x8 — скачать.
Нужно указать, что следующие символы мы будем писать на белом фоне отключая пиксели (0).
В этой строке мы выведем время и дату.
u8g.setPrintPos( 2, 8); u8g.print(now.day() / 10);
u8g.setPrintPos( 7, 8); u8g.print(now.day() % 10);
u8g.setPrintPos( 11, 8); u8g.print(".");
u8g.setPrintPos( 15, 8); u8g.print(now.month() / 10);
u8g.setPrintPos( 20, 8); u8g.print(now.month() % 10);
u8g.setPrintPos( 24, 8); u8g.print(".");
u8g.setPrintPos( 29, 8); u8g.print(now.year(), DEC);
u8g.setPrintPos( 101, 8); u8g.print(now.hour() / 10);
u8g.setPrintPos( 107, 8); u8g.print(now.hour() % 10);
u8g.setPrintPos( 112, 8); u8g.print(":");
u8g.setPrintPos( 117, 8); u8g.print(now.minute() / 10);
u8g.setPrintPos( 122, 8); u8g.print(now.minute() % 10);
Заметьте, каждому символу в строке попиксельно указано, где он будет находиться.
Теперь настроим вывод температуры и влажности. Все это уже будет написано другим шрифтом 6х10.
Шрифт LCD дисплея u8g_font_6x10 — скачать.
u8g.setPrintPos( 3, 20); u8g.print("Humidity");
u8g.setPrintPos( 53, 21); u8g.print("=");
u8g.setPrintPos( 60, 20); u8g.print(DHT.humidity, 1);
u8g.setPrintPos( 73, 20); u8g.print("%");
u8g.setPrintPos( 3, 31); u8g.print("Temp");
u8g.setPrintPos( 29, 32); u8g.print("=");
u8g.setPrintPos( 37, 31); u8g.print(DHT.temperature, 1);
u8g.setPrintPos( 49, 31); u8g.print("°C");
u8g.setPrintPos( 3, 42); u8g.print("Light");
u8g.setPrintPos( 29, 43); u8g.print(" — ");
if (digitalRead(sensor1) == HIGH) <
u8g.setPrintPos( 45, 42); u8g.print("On");
>
else
<
u8g.setPrintPos( 45, 42); u8g.print("Off");
>
И тут добавляем число, которое в процентом отношении показывает уровень освещенности. Подробнее об этом уже рассказывалось.
int val = analogRead(sensor2);
val = map(val, 0, 1023, 0, 100);
u8g.setPrintPos( 73, 42); u8g.print(val);
u8g.setPrintPos( 86, 42); u8g.print("%");
И вот что должно получиться.
#include "U8glib.h" \библиотека для работы с LCD дисплеем
#include "dht11.h" \библиотека для работы с датчиком влажности и температуры
#include \библиотека для работы с I2C интерфесом
#include "RTClib.h" \библиотека для работы с модулем часов реального времени (RTC — Real_time_clock)
RTC_DS1307 rtc;
dht11 DHT; // Объявление переменной класса dht11
int chk;
#define DHT11_PIN 12 // Датчик DHT11 подключен к цифровому пину номер 13
const int ledlight = 9;
const int sensor1 = 2;
const int sensor2 = 0;
U8GLIB_ST7920_128X64_1X u8g( 13, 11, 10); // Создаём объект u8g для работы с дисплеем, указывая номер вывода CS для аппаратной шины SPI
pinMode(ledlight, OUTPUT);
pinMode(sensor1, INPUT);