Led Matrix P10 - шрифты

gokerze
Offline
Зарегистрирован: 26.04.2020
Разбираюсь с монохромными (одноцветными) светодиодными модулями P10 (Led Matrix P10, табло P10, HUB12).
На данном этапе для управления панелью использую клон Arduino Nano на Atmega328.
 
С вашего позволения буду вести тут бложик по теме.
Участие уважаемого сообщества категорически приветствуется.
 
Задача: вывод на табло читаемого текста на русском и английском языках
gokerze
Offline
Зарегистрирован: 26.04.2020
Подробнее о панелях:
 
Название номенклатуры в интернет-магазине: Светодиодный модуль DIP 320x160 P10 20W
Надпись на плате: P10(1R)-706-10 DIP-DP4536
Разъем: HUB12
Ссылка на товар в магазине (не реклама, для наглядности):
 
У меня их 2шт. 32x16 пикселей.
Обе панели питаются от одного блока питания для телефона 5V 1,5A.
Блок питания не плавится. Яркость диодов глаза не выжигает.
В продакшене понадобится блок питания сильно мощнее ~4А на панель.
 
Для управления используется Arduino Nano на Atmega328 с библиотекой Freetronics DMD (первая, до DMD2 пока не дотянулся).
gokerze
Offline
Зарегистрирован: 26.04.2020
Используемые библиотеки для Arduino, разработка в Arduino IDE:
 
1. Freetronics DMD - #include <DMD.h> - https://github.com/freetronics/DMD
2. PaulStoffregen TimerOne - #include <TimerOne.h> - https://github.com/PaulStoffregen/TimerOne
gokerze
Offline
Зарегистрирован: 26.04.2020
Программы используемые для создания шрифтов
 
1. Riuson.com LCD Image Converter
https://yadi.sk/d/5WPLJjkQs16JGw - копия репозитория + бинарник под Linux (Qt)
https://yadi.sk/d/JS4zvAifaza30w - бинарник под Windows
Комментарий: Поддерживает кириллицу. В этой программе нарисованы шрифты представленные ниже. Итоговый формат шрифта отличается от необходимого, но это можно исправить скриптом на Python.
Ссылка на скрипт: https://yadi.sk/d/WWhegd0D2IJWjQ
 
2. Форк FontCreator2.0 rsp. 2.1 from F. Maximilian Thiele
https://yadi.sk/d/GWbriczHvJrxEw - копия репозитория + бинарник под Windows (.NET)
Комментарий: Делает правильного для DMD формата шрифты. Не поддерживает кириллицу.
gokerze
Offline
Зарегистрирован: 26.04.2020
Готовые шрифты для Freetronics DMD с кириллицей
 
Отправной точкой стал моноширинный шрифт 5x7 найденный в интернете
 
Из этого шрифта взята магическая последовательность символов в массиве. 
Начинается с пробела и заканчивается строчной буквой "п":
 
Магическая последовательность:
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~†рстуфхцчшщъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп

Сделанные в Riuson.com LCD Image Converter и отформатированные скриптом шрифты с кириллицей готовые к использованию с Freetronics DMD

Font_8pix.h (на панель высотой 16pix умещается в два ряда, не моноширинный)
 

Font_mid.h

https://yadi.sk/d/4MlRRIvGHNK8OQ

Font_BOLD.h (максимально большой)
 
 
Вместо символа "~" в этих шрифтах нарисован "пробел" шириной 1 пиксель. Если использовать "обычный" пробел в команде dmd.drawString, например, то его ширина будет 5 пикселей вне зависимости от чего бы то ни было. Также, между любыми двумя символами рисуется пробел в 1 пиксель - можно не ставить пробелы у знаков препинания.
 
Пример разреженной строки "Вася, иди в лес!"
Пример компактной строки "Вася,иди~в~лес!"
 
Эти шрифты сходу можно вставлять в демку от Freetronics DMD:
 
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>

#include "Font_Arial_mini.h"
#include "Font_Arial_mid.h"
#include "Font_Arial_BIG.h"
#include "SystemFont5x7.h"

#define DISPLAYS_ACROSS 2
#define DISPLAYS_DOWN 1

DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

void ScanDMD() { 
  dmd.scanDisplayBySPI();
}

void setup(void) {
  Timer1.initialize(3000);
  Timer1.attachInterrupt(ScanDMD);

  dmd.clearScreen(true);
  dmd.selectFont(Font_Arial_BIG);
  const char *MSG1 = "Вася,иди~в~лес!";  
  dmd.drawString(0, 0, MSG1, strlen(MSG1), GRAPHICS_NORMAL);
}

void loop(void) {
  
}

 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

если взять библиотеку DMD-STM32 - с этими матрицами можно изпользовать шрифты формата Adafruit - то есть практически любой размер на любом национальном языке.

В качестве платы управления я предпочитаю использовать STM32

подробнее

http://arduino.ru/forum/proekty/dmdstm32-versiya-biblioteki-dmd-dlya-stm32duino

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Хреновая библиотека ИМХО...

 

b707
Онлайн
Зарегистрирован: 26.05.2017

mykaida пишет:

Хреновая библиотека ИМХО...

 

которая? И почему?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А это чего за херня?

#include "Font_mini.h"
#include "Font_mid.h"
#include "Font_BIG.h"
#include "SystemFont5x7.h"

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018
Вы их проверяли на толерастность к пробелу?
gokerze
Offline
Зарегистрирован: 26.04.2020
Порядок записи бит и Байт для символов двухбайтовой высоты (16 пикселей) для библиотеки Freetronics DMD
 
На примере строчной буквы "а" - смотри картинку.
 
Снизу вверх, слева направо. Сперва верхние 8 пикселей (Байт), затем - нижние. Ширина символа - 5 пикселей. Объем - 10 Байт.
 
Двоичное представление:
1000 0000, 0100 0000, 0100 0000, 0100 0000, 1000 0000,
0000 1100, 0001 0010, 0001 0010, 0000 1010, 0001 1111,

Шестнадцатеричное представление:

0x80, 0x40, 0x40, 0x40, 0x80,
0x0c, 0x12, 0x12, 0x0a, 0x1f,
Код для обхода изображения символа двухбайтовой высоты в Riuson.com LCD Image Converter
(Настройки -> Преобразование -> Подготовка -> Сканирование -> Свой алгоритм)
 
for (var x = 0; x < image.width; x++) {
    for (var y = (image.height/2) - 1; y >= 0; y--) {
        image.addPoint(x, y);
    }
}
for (var x = 0; x < image.width; x++) {
    for (var y = image.height - 1; y >= (image.height/2); y--) {
        image.addPoint(x, y);
    }
}

 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

gokerze пишет:

На примере строчной буквы "а" - смотри картинку.
 
Снизу вверх, слева направо. Сперва верхние 8 пикселей (Байт), затем - нижние. Ширина символа - 5 пикселей. Объем - 10 Байт.
 
Интересно, нафига букву размером 5х7 точек описывать массивом 5х16 ? Оперативную память некуда девать? Буква, которая легко помещается в 5 байт - в итоге займет 10. На картинке это хорошо видно.
 
 
gokerze
Offline
Зарегистрирован: 26.04.2020

DMD умеет в шрифты переменной высоты?

b707
Онлайн
Зарегистрирован: 26.05.2017

gokerze пишет:

DMD умеет в шрифты переменной высоты?

конечно.

Вы бы почитали ссылки, что я вам даю - все проблемы. что вы описываете в "бложике" - давно решены. Люди собирают панно из десятков матриц и, конечно же, выводят туда текст не только высотой 16 пикселей...

b707
Онлайн
Зарегистрирован: 26.05.2017

шрифт высотой 96 пикс

gokerze
Offline
Зарегистрирован: 26.04.2020
Я не сомневаюсь, что космические корабли бороздят просторы мирового театра.
Ссылка, что вы предоставили ведет на библиотеку для STM32.
У меня же...
 
Железо:
 
Arduino Nano на Atmega328
1-4 одноцветные P10 в один ряд
 
Задача:
 
Вывод статичной иконки 16x16 в крайнем левом положении, при необходимости.
На оставшемся месте текст кириллицей шрифтами трех размеров.
В зависимости от длины текста с учетом размера шрифта:
1. Статическое отображение - текст влезает полностью
2. Скроллинг <-> влево-право туда-обратно - текст немного длиннее панелей
3. Вертикальный скроллинг - текст сильно длиннее панелей
 
Контроллер управляющий панелью будет заниматься только приемом текста по i2c и выводом его на панель.
Пока я не ощутил нехватку памяти.
 
Что конкретно вы хотите предложить?
 
Перейти на STM32 и вашу библиотеку?
Другую библиотеку для Atmega328?
Конкретный способ генерации шрифтов переменной высоты?
b707
Онлайн
Зарегистрирован: 26.05.2017

gokerze пишет:
Что конкретно вы хотите предложить?

Перейти на STM32 и вашу библиотеку?
Другую библиотеку для Atmega328?
Конкретный способ генерации шрифтов переменной высоты?

я вас ни за что не агитирую :), хотя библиотека поддерживает не только СТМ32. Хотите изобретать велосипед - пожалуйста, это же всегда интересно.

Просто вы, вроде бы, приглашали всех к дискуссии - вот я и указал вам на неэффективность выбранного метода описания шрифтов. Если вам реально интересно, как это улучшить - пссмотрите описание формата шрифтов Адафруит. Там для описании букв используется только прямоугольник, в котором реально есть закрашенные пиксели, без необходимости описывать обширные пустые области.

раз уж вы взялись изобретать свое - там пусть оно будет немного лучше уже готового. А проектов вывода кирилицы на матрицы P10 в интернете довольно.

FoxJone
Offline
Зарегистрирован: 19.04.2019

gokerze пишет:

Я не сомневаюсь, что космические корабли бороздят просторы мирового театра.
Ссылка, что вы предоставили ведет на библиотеку для STM32.
У меня же...
 
Железо:
 
Arduino Nano на Atmega328
1-4 одноцветные P10 в один ряд
 
Задача:
 
Вывод статичной иконки 16x16 в крайнем левом положении, при необходимости.
На оставшемся месте текст кириллицей шрифтами трех размеров.
В зависимости от длины текста с учетом размера шрифта:
1. Статическое отображение - текст влезает полностью
2. Скроллинг <-> влево-право туда-обратно - текст немного длиннее панелей
3. Вертикальный скроллинг - текст сильно длиннее панелей
 
Контроллер управляющий панелью будет заниматься только приемом текста по i2c и выводом его на панель.
Пока я не ощутил нехватку памяти.
 
Что конкретно вы хотите предложить?
 
Перейти на STM32 и вашу библиотеку?
Другую библиотеку для Atmega328?
Конкретный способ генерации шрифтов переменной высоты?

Вам просто сообщают, что вы стучитесь в открытую дверь. Поделка на фото - моя. И там не STM32, а вовсе даже esp8266 (с вебмордой и управлением по вайвай). И в качестве библиотеки использован стандартный DMD2 для атмег. Кучу поделок я делал на 168 и на 328 атмегах. С тем же самым DMD2. Так вот, с памятью проблемы бывали. На 168 постоянно, но и на 328 приходилось ужимать шрифты по максимуму. 

И таки да, шрифты на DMD переменного размера (зависит от буквы).

gokerze
Offline
Зарегистрирован: 26.04.2020
Я не чувствую себя изобретателем велосипедов.
Чувствую себя пользователем библиотеки Freetronics DMD.
Что первое нашел, то схватил.
 
Моей проблемой был не дефицит памяти, не стремление к изящным техническим решениям, не страсть к изобретательству, но отсутствие и сложность изготовления шрифтов.
Я рад что человечество уже решило эту проблему и с удовольствием воспользуюсь результатами чужих трудов.
 
Пошел смотреть вашу библиотеку работающую в том числе на Arduino Uno на Atmega 328.
 
Port of Freetronic DMD library for STM32Duino - DMD_STM32 with Unicode fonts support
 
В папке gfx_fonts нашел шрифты с русскими буквами.
Пробую сделать свой по образу и подобию.
 
Скачал библиотеку Adafruit GFX ради её fontconvert
 
Накатил Ubuntu на виртуалку, ибо fontconvert - линуксовый софт.
В комплекте идет длинная инструкция как завести под Windows.
 
Ищу ttf шрифты в составе дистрибутива и копирую в папку к fontconvert
 
sudo apt install freetype2-demos freetype2-doc libfreetype6 libfreetype6-dev
cd ~/Adafruit-GFX/fontconvert
make
# Участок с латиницей
./fontconvert ./ttf/Ubuntu-M.ttf 9 32 128 > UbuntuMedium9pt8b.h
# Участок с кириллицей
./fontconvert ./ttf/Ubuntu-M.ttf 9 1040 1103 > UbuntuMedium9pt8brus.h

Открываю получившиеся файлы и руками копирую массивы в один файл.

Готово.

Результат:
 
Запускаю демку - работает.
 
#include <DMD_STM32.h> 
#include <TimerOne.h>
#include "gfx_fonts/UbuntuMedium9pt8b.h"

#define DISPLAYS_ACROSS 2
#define DISPLAYS_DOWN 1
#define DMD_PIN_A 6
#define DMD_PIN_B 7
#define DMD_PIN_OE 9
#define DMD_PIN_SCLK 8

SPIClass dmd_spi;
DMD dmd(DMD_PIN_A, DMD_PIN_B, DMD_PIN_OE, DMD_PIN_SCLK, DISPLAYS_ACROSS, DISPLAYS_DOWN, dmd_spi);
DMD_GFX_Font UbuntuMedium((uint8_t*)&UbuntuMedium9pt8b,(uint8_t*)&UbuntuMedium9pt8brus, 0x80, 12);

const unsigned char m[] = "Какое слово скажешь, такое в ответ и услышишь.";
char k[50];

int utf8_rus(char* dest, const unsigned char* src) {
  
  uint8_t i, j;
  for ( i =0, j =0; src[i]; i++) {
   if ((src[i] == 0xD0 )&& src[i+1])  { dest[j++] = src[++i] - 0x10;}
    else if ((src[i] == 0xD1 )&& src[i+1]) {dest[j++] = src[++i] + 0x30;  }
    else dest[j++] = src[i];
  }
  dest[j] ='\0';
  return j;
}

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

void setup(void) {  
  Timer1.initialize(3000);
  Timer1.attachInterrupt(ScanDMD);
  dmd.clearScreen(true); 
  dmd.selectFont(&UbuntuMedium);

  utf8_rus(k,m);   
}

void loop(void) {  
  dmd.drawMarquee(k, strlen(k), (32*DISPLAYS_ACROSS)-1, 0);   
  long prev_step = millis();  
  while(1) {
    if ((millis() - prev_step) > 30 ) {
      dmd.stepMarquee(-1, 0);
      prev_step=millis();  
    }
  }
}

Что таки я ощутил:

1. Бегущая строка будто плавнее относительно Freetronics DMD
2. Шрифты создаются почти сами
 
Продолжаю наблюдение.
and_riy1488
Offline
Зарегистрирован: 20.08.2020

Какие настройки в программе "LCD Image Converter" нужно сделать чтобы создать свой шрифт?

Я сделал свой шрифт по вашей инструкции но матрица выводит иероглифы

ссылки на мой шрифт

https://drive.google.com/file/d/1qIMrwBiZu0FKHHbEB2j6z7HPwag4wKjX/view?u...

b707
Онлайн
Зарегистрирован: 26.05.2017

and_riy1488 пишет:

Какие настройки в программе "LCD Image Converter" нужно сделать чтобы создать свой шрифт?

Я сделал свой шрифт по вашей инструкции но матрица выводит иероглифы

ссылки на мой шрифт

https://drive.google.com/file/d/1qIMrwBiZu0FKHHbEB2j6z7HPwag4wKjX/view?u...

Если хотите, чтобы вам помогли - пишите подробнее

- какую библиотеку ДМД используете, какие матрицы, какая управляющая плата

- пытаетесь выводить на матрицу латиницу или национальные алфавиты?

- приведите код, работающий с матрицей

 

FoxJone
Offline
Зарегистрирован: 19.04.2019

Раз уж вы тут про фонты, вставлю свои 5 копеек.

Лично я пользуюсь вот этой программой (требует яву) https://yadi.sk/d/XTrYnWbaODXy2w

Просто и удобно. Можно загружать системные фонты, можно рисовать свои. Лично я рисую свои - системные не отображаются в полной мере на всю высоту табло. На рисование фонта обычно трачу не больше часа - навострился.

Известные баги:

1. Иногда при экспорте не правильно выставляет высоту фонта в пикселях (и фонт не показывается нормально), надо всегда проверять итоговой фонт.h.

2. Если в описании символа есть какие то знаки (не буквы и цифры), то не делает экспорт в h. Какие точно символы, мне лень проверять, поэтому я всегда эти символы не подписываю, а потом подписываю уже в файле h.  В принципе их можно вообще не подписывать, но я люблю порядок и что бы в файле фонт.h я всегда мог найти нужный символ. Точно знаю, что мешают экспорту /,\, (,), {,} - но это не весь список, остальные мне стало лениво вычислять. Просто не подписываю то, что обвел красным

И таки да, как вы можете видеть, ширина фонтов переменная. Все известные мне ДМД эти фонты употребляют вообще без проблем.

and_riy1488
Offline
Зарегистрирован: 20.08.2020

- Использую обычную DMD библиотеку, матрица P10(1R) HUB12 , Arduino Nano (ATmega328P)

- использую латиницу и кирилицу{  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~†рстуфхцчшщьєю

яАБВГДЕЖЗІИЇЙКЛМНОПРСТУФХЦЧШЩЬЄЮЯабвгдежзіиїйклмноп }

- Еще появляется такая ошибка при cмене кодировки в Sublime Text 3

- Файл source  https://drive.google.com/file/d/187gBvxnArY5JPtJXb-7KhsrkZ119vsR6/view?usp=sharing

 

-  код демка з DMD =>

#include <SPI.h>        //SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include <DMD.h>        //
#include <TimerOne.h>   //
#include "SystemFont5x7.h"
#include "Font_mid.h"
#include "Font_ua2158.h"

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 4
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

/*--------------------------------------------------------------------------------------
  Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
  called at the period set in Timer1.initialize();
--------------------------------------------------------------------------------------*/
void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

/*--------------------------------------------------------------------------------------
  setup
  Called by the Arduino architecture before the main loop begins
--------------------------------------------------------------------------------------*/
void setup(void)
{

   //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
   Timer1.initialize( 3000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
   Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()

   //clear/init the DMD pixels held in RAM
   dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)
  Serial.begin(115200);
}

/*--------------------------------------------------------------------------------------
  loop
  Arduino architecture main loop
--------------------------------------------------------------------------------------*/
void loop(void)
{
   dmd.clearScreen( true );
   dmd.selectFont(Font_ua2158);
   // Français, Österreich, Magyarország
   const char *MSG = "Заїзд комерційного транспорту";
   dmd.drawMarquee(MSG,strlen(MSG),(32*DISPLAYS_ACROSS)-1,0);
   long start=millis();
   long timer=start;
   while(1){
     if ((timer+30) < millis()) {
       dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

скачайте вот этот рус-украинский фонт

https://github.com/board707/DMD_STM32/blob/master/st_fonts/UkrRusSystemFont5x7.h

попробуйте вывести надпись этим фонтом - какой результат?

and_riy1488
Offline
Зарегистрирован: 20.08.2020

На матрицу выводит следующие слова:

Слово "Заїзд" выводит на Матрицу => "ЗаЗзд"
а
слово "комерційного" => комерціЖного"

b707
Онлайн
Зарегистрирован: 26.05.2017

and_riy1488 пишет:

На матрицу выводит следующие слова:

Слово "Заїзд" выводит на Матрицу => "ЗаЗзд"
а
слово "комерційного" => комерціЖного"

это которым фонтом? из моей ссылки?

а когда выводили надпись вашим фонтом. что получалось?

and_riy1488
Offline
Зарегистрирован: 20.08.2020

 Пробовал вот ети с вашей ссылки:

-  UkrRusArial14.h
-  UkrRusSystemFont5x7.h

вот что происходит с моим  цифра "1"

 

 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

для начала сравните местоположения символа "1" в своем и моих фонтах, похоже что у вас рисуется массив байт из какого-то произвольного места в памяти. Если ошибки в коде символа нет - тогда значит ваш фонт имеет неверный формат

gokerze
Offline
Зарегистрирован: 26.04.2020

Заснял процесс на видео

https://youtu.be/MvK-GDpVIjM

Если Sublime Text 3 не может избавиться от Unicode - используйте блокнот. В блокноте сохраните файл в ANSI. Но Sublime справится, если в настройках Riuson.com LCD Image Converter заменить юникодную штриховку на Нолики и Единички. 

gokerze
Offline
Зарегистрирован: 26.04.2020

Не путайте библиотеку Freetronics DMD (https://github.com/freetronics/DMD) о которой говорю я и библиотеку DMD_STM32 (https://github.com/board707/DMD_STM32) о которой говорит b707.

Шрифты для них разные. DMD_STM32 требует дополнительных операций в коде скетча для отображения кириллицы.

b707
Онлайн
Зарегистрирован: 26.05.2017

DMD_STM32 поддерживает и фонты от Freetronics DMD тоже