esp8266 + u8glib

alex7106

New member
33322.jpg
Как создать свой фонт для библиотеки 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), но в отличии от нее - далее идут не изображения символов, а таблица параметров по каждому символу
Код:
 //Address  length width
  0x00, 0x00, 0xD0, 0x1E, //0
Всего 4 байта на каждый символ. Длина данной таблицы = количеству символов из шапки * 4 байт.
Первых два байта - это адрес смещения начала символа в последующих байтах изображений.
Третий байт - длина (размер в байтах) изображения символа.
Четвертый - ширина знакоместа в пикселях (не изображения символа, а места для него до начала
следующего символа (с учетом интервала) - т.е. это значение должно быть немного больше ширины самого символа)

Итак, мы описали 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 поделитесь пожалуйста ![/Здравствуйте
Как создать свой фонт для библиотеки 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), но в отличии от нее - далее идут не изображения символов, а таблица параметров по каждому символу
Код:
 //Address  length width
  0x00, 0x00, 0xD0, 0x1E, //0
Всего 4 байта на каждый символ. Длина данной таблицы = количеству символов из шапки * 4 байт.
Первых два байта - это адрес смещения начала символа в последующих байтах изображений.
Третий байт - длина (размер в байтах) изображения символа.
Четвертый - ширина знакоместа в пикселях (не изображения символа, а места для него до начала
следующего символа (с учетом интервала) - т.е. это значение должно быть немного больше ширины самого символа)

Итак, мы описали 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: на фотке вывод температуры. Первый символ получен наложением (вывод символа поверх другого).
Здравствуйте! Подскажите, пожалуйста подробней про длину и ширину символов. Как её определить? Я пытаюсь сделать свой шрифт для часов, но у меня не получается.33322.jpg Посмотреть вложение 8121 Посмотреть вложение 8121
 

alex7106

New member
Разобрался с форматом файла шрифтов для вот этой библиотеки: GitHub - squix78/esp8266-oled-ssd1306: Driver for the SSD1306 and SH1106 based 128x64 pixel OLED display running on the Arduino/ESP8266 platform

Конвертнул в нее свои шрифты. Но у меня русский шрифт был только 5x7 со старых времен. Нужно будет еще сделать шрифты побольше...
Здравствуйте! можете помочь с форматом файла шрифтов библиотеки esp8266-oled-ssd1306? Пытаюсь сделать свой шрифт цифр для часов 24х32, но никак не разберусь с параметрами символов.33322.jpg
 

PPS

New member
работаю с https://github.com/squix78/esp8266-oled-ssd1306), но там мало шрифтов.
Если зайти в папку библиотеки (\ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays\resources), там есть файлик, редактор шрифтов glyphEditor.html от разработчиков самой библиотеки (без самодеятельности)), пользуйтесь, не благодарите...
 

Вложения

Сверху Снизу