Как создать свой фонт для библиотеки esp8266-oled-ssd1306
Когда заинтересовался написанием своего шрифта для экрана, столкнулся с небольшой проблемой, что формат шрифта у библиотеки esp8266-oled-ssd1306 немного другой, чем описывается в статье
Свой текст для OLED 128x64 и мне пришлось разобраться в различиях.
И так. Из практики мы знаем, что перед выводом текста в скетче надо вызвать функцию [inline]display.setFont();[/inline]
которой в параметре передается имя шрифта. Сами шрифты описываются в файле OLEDDisplayFonts.h
Давайте теперь создадим свой шрифт с одним символом - цифрой ноль. Прописываем в файл следующую конструкцию:
Где первый параметр - это ширина символа в пикселяхКод:const char CrystalNumbers_64[] PROGMEM = { 0x1A, // Width: 26 0x40, // Height: 64 0x30, // First Char: 48 0x01, // Numbers of Chars: 1
второй параметр - высота в пикселях
третий параметр - код ASCII первого символа в шрифте (в нашем случае - нуля)
четвертый - количество символов в описываемом шрифте (у нас только один символ)
Это описание шрифта используется и в другой библиотеке (например, от Adafruit), но в отличии от нее - далее идут не изображения символов, а таблица параметров по каждому символу
Всего 4 байта на каждый символ. Длина данной таблицы = количеству символов из шапки * 4 байт.Код://Address length width 0x00, 0x00, 0xD0, 0x1E, //0
Первых два байта - это адрес смещения начала символа в последующих байтах изображений.
Третий байт - длина (размер в байтах) изображения символа.
Четвертый - ширина знакоместа в пикселях (не изображения символа, а места для него до начала
следующего символа (с учетом интервала) - т.е. это значение должно быть немного больше ширины самого символа)
Итак, мы описали 1 символ 26*64 начиная с '0' (ord 48).
Также написали адрес его изображения 0x00:0x00, его длину 13 байт (0xD0) и его ширину 30 пикселей (0x1E) (26 ширина изображения и 4 пикселя отступа).
Теперь идет рисунок самого символа. Он описывается по вертикальным столбцам с правого верхнего угла.
Но пиксели собираются по 8 штук в один байт. Т.е. в первый байт попадают пиксели с координатами
по X=1, Y=8..Y=1, во второй X=1, Y=16..Y=9 и так до крайнего X=1, Y=64..Y=56, после которого
переходим к следующей колонке X=1, Y=9..Y=16 и т.д.
Чтобы удобнее было считать, давайте повернем изображение символа на 90 градусов (тут только верхняя половина):
Теперь описываем первую колонку (X=1):
Также описываем вторую и последующие колонки:Код:0xE0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F,
Теперь давайте сохраним и проверим:Код:0xF0,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x1F, 0xF0,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x1F, 0xE6,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F, 0xCF,0xFF,0xFF,0x0F,0xF8,0xFF,0xFF,0x67, 0x9F,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0xF3, 0x3F,0xFF,0xFF,0x03,0xE0,0xFF,0xFF,0xF9, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x9F,0xFF,0xFF,0x03,0xE0,0xFF,0xFF,0xFC, 0xCF,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0xF9, 0xE6,0xFF,0xFF,0x0F,0xF8,0xFF,0xFF,0xF3, 0xF0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x67, 0xF8,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x0F, 0xF8,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x0F, 0xF0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x07,
Как видите, все у нас получилось. Подобным образом рисуются остальные символы.Код:#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` SSD1306 display(0x3c, D3, D4); void setup() { display.init(); display.flipScreenVertically(); display.setContrast(255); display.clear(); display.setFont(CrystalNumbers_64); display.drawString(0, 0, "0" ); display.display(); } void loop() { }
В прикрепленном файле я подготовил шрифт на все цифры, знаки плюс и минус, точку и двоеточие.
А также пример с выводом таймера на экран. Скетч написан так, что можно отключать и подключать экран в любое время "на ходу" (программа его переинициализирует).
(ps: на фотке вывод температуры. Первый символ получен наложением (вывод символа поверх другого).
у кого есть русский шрифт на на esp8266 с oled ssd1306 поделитесь пожалуйста ![/Здравствуйте
Здравствуйте! Подскажите, пожалуйста подробней про длину и ширину символов. Как её определить? Я пытаюсь сделать свой шрифт для часов, но у меня не получается. Посмотреть вложение 8121 Посмотреть вложение 8121Как создать свой фонт для библиотеки esp8266-oled-ssd1306
Когда заинтересовался написанием своего шрифта для экрана, столкнулся с небольшой проблемой, что формат шрифта у библиотеки esp8266-oled-ssd1306 немного другой, чем описывается в статье
Свой текст для OLED 128x64 и мне пришлось разобраться в различиях.
И так. Из практики мы знаем, что перед выводом текста в скетче надо вызвать функцию [inline]display.setFont();[/inline]
которой в параметре передается имя шрифта. Сами шрифты описываются в файле OLEDDisplayFonts.h
Давайте теперь создадим свой шрифт с одним символом - цифрой ноль. Прописываем в файл следующую конструкцию:
Где первый параметр - это ширина символа в пикселяхКод:const char CrystalNumbers_64[] PROGMEM = { 0x1A, // Width: 26 0x40, // Height: 64 0x30, // First Char: 48 0x01, // Numbers of Chars: 1
второй параметр - высота в пикселях
третий параметр - код ASCII первого символа в шрифте (в нашем случае - нуля)
четвертый - количество символов в описываемом шрифте (у нас только один символ)
Это описание шрифта используется и в другой библиотеке (например, от Adafruit), но в отличии от нее - далее идут не изображения символов, а таблица параметров по каждому символу
Всего 4 байта на каждый символ. Длина данной таблицы = количеству символов из шапки * 4 байт.Код://Address length width 0x00, 0x00, 0xD0, 0x1E, //0
Первых два байта - это адрес смещения начала символа в последующих байтах изображений.
Третий байт - длина (размер в байтах) изображения символа.
Четвертый - ширина знакоместа в пикселях (не изображения символа, а места для него до начала
следующего символа (с учетом интервала) - т.е. это значение должно быть немного больше ширины самого символа)
Итак, мы описали 1 символ 26*64 начиная с '0' (ord 48).
Также написали адрес его изображения 0x00:0x00, его длину 13 байт (0xD0) и его ширину 30 пикселей (0x1E) (26 ширина изображения и 4 пикселя отступа).
Теперь идет рисунок самого символа. Он описывается по вертикальным столбцам с правого верхнего угла.
Но пиксели собираются по 8 штук в один байт. Т.е. в первый байт попадают пиксели с координатами
по X=1, Y=8..Y=1, во второй X=1, Y=16..Y=9 и так до крайнего X=1, Y=64..Y=56, после которого
переходим к следующей колонке X=1, Y=9..Y=16 и т.д.
Чтобы удобнее было считать, давайте повернем изображение символа на 90 градусов (тут только верхняя половина):
Теперь описываем первую колонку (X=1):
Также описываем вторую и последующие колонки:Код:0xE0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F,
Теперь давайте сохраним и проверим:Код:0xF0,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x1F, 0xF0,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x1F, 0xE6,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F, 0xCF,0xFF,0xFF,0x0F,0xF8,0xFF,0xFF,0x67, 0x9F,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0xF3, 0x3F,0xFF,0xFF,0x03,0xE0,0xFF,0xFF,0xF9, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 0x9F,0xFF,0xFF,0x03,0xE0,0xFF,0xFF,0xFC, 0xCF,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0xF9, 0xE6,0xFF,0xFF,0x0F,0xF8,0xFF,0xFF,0xF3, 0xF0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x67, 0xF8,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x0F, 0xF8,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x0F, 0xF0,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x07,
Как видите, все у нас получилось. Подобным образом рисуются остальные символы.Код:#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` SSD1306 display(0x3c, D3, D4); void setup() { display.init(); display.flipScreenVertically(); display.setContrast(255); display.clear(); display.setFont(CrystalNumbers_64); display.drawString(0, 0, "0" ); display.display(); } void loop() { }
В прикрепленном файле я подготовил шрифт на все цифры, знаки плюс и минус, точку и двоеточие.
А также пример с выводом таймера на экран. Скетч написан так, что можно отключать и подключать экран в любое время "на ходу" (программа его переинициализирует).
(ps: на фотке вывод температуры. Первый символ получен наложением (вывод символа поверх другого).