DMD_STM32 - версия библиотеки DMD для СТМ32Дуино

b707
Offline
Зарегистрирован: 26.05.2017

Редакция библиотеки DMD.h для p10 светодиодных матриц -  под платы СТМ32 в рамках проекта Arduino_STM32

 

b707
Offline
Зарегистрирован: 26.05.2017

Просьба не цитировать этот пост, чтобы я мог потом его редактировать

Выложил на Гитхаб пробную версию библиотеки DMD_STM32 https://github.com/board707/DMD_STM32

На данный момент код включает себя только возможности, аналогичные оригинальной библиотеке DMD.h от Freetronics. Основная цель первого этапа - добиться устойчивой работы p10 матриц на дешевых платах СТМ32, в частности на т.н. "блюпилл".

В качестве базы использован незаконченный проект DMDSTM https://github.com/mozok/DMDSTM  Попытки связаться с его автором пока успеха не дали. От проекта DMDSTM в настоящую библиотеку перекочевала возможность вывода сообщений кириллицей в кодировке UTF8 прямо из Ардуино ИДЕ - при выборе измененных шрифтов, начинающихся с UkrRus... В дальнейшем планируется прикрутить к проекту поддержку UTF8 фонтов какого-либо распространенного формата.

Использование библиотеки аналогично оригинальной DMD.h, за исключением контруктора - он требует указания используемых пинов и обьекта SPI:

DMD dmd(DMD_PIN_A, DMD_PIN_B, DMD_PIN_nOE, DMD_PIN_SCLK, DISPLAYS_ACROSS, DISPLAYS_DOWN, dmd_spi );

Пины CLK и R_DATA жестко определены используемым каналом SPI, их указывать не нужно:
SPI_1: CLK = PA5
            R_DATA = PA7
SPI_2: CLK = PB13
            R_DATA = PB15

Благодаря тому, что пины теперь являются переменными класса DMD, появилась возможность вызывать несколько эземпляров, в частности на STM32F103, где два независимых канала SPI - можно повесить две цепочки матриц и управлять ими отдельно. см. пример double_dmd и видео https://www.youtube.com/watch?v=OCpLTLpwgRI

Подключение описано в README. Обратите внимание на сноску Исключения (Exclusions) под табличкой пинов. не используйте ноги PB3 PB4 PA11 PA12 PA15. Оттестированные комбинации пинов можно подсмотреть в примерах.

Любые замечания и пожелания всячески приветсвуются!

b707
Offline
Зарегистрирован: 26.05.2017

вести о проекте - прикрутил к библиотеке поддержку фонтов в формате GFX_Font от либы Adafruit GFX. Этот формат хорош тем, что в самой библиотеке куча фонтов, и , главное, можно одним движением конвертить в этот формат фонты TTF, которых сотни в инете. В том числе и в национальных кодировках.  Например можно брать фонты с кириллицей из винды.

Видео - выводим текст фонтом FreeSerifBold9pt7b из Adafruit_GFX:

https://youtu.be/jRa607nLxqI

Поддержку "чужих" фонтов написал в виде абстрактного класса, так что с небольшими усилиями можно добавить и фонты других форматов. Правда, пока нет работы с UTF8, но надеюсь это не за горами. Новую версию чуть подчищу и выложу на Гитхаб.

Традиционно буду рад замечаниям и пожеланиям.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Спасибо, слежу за проектом ;) BTW, только под STM32? Или компилится под другие МК? 

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

только под STM32? Или компилится под другие МК? 

пока нет. Изначальная цель проекта была именно порт под СТМ :) ... и еще я убил немало времени, чтобы получить возможность одновременного запуска двух DMD обьектов... поэтому о возврате на АВР пока не думал.

Но в принципе, специфично СТМ-ского кода там совсем чуть-чуть - думаю настроить условную компиляцию будет не слишком сложно.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan , я победил Unicode :)

https://youtu.be/9xUB8-jk5Tc

Строка выведена шрифтом Comic9pt из комплекта Windows7. Фонт преобразован Адафрутовским fontconvert прямо из виндовского TTF.  Получаются фонты, сразу готовые к подключению к библиотеке. Нагенерить кучу фонтов совершенно не проблема, причем не только с кириллицей.

Хотя конечно работа с UTF8 со стороны пользовательского скетча у меня пока реализована не слишком изящно - нужно пропускать строчки через некую функцию utf8_rus(), которая преобразует 16-битные UTF8 коды Ардуино ИДЕ в верхнюю половину 8-битной ASCII таблицы. В будущем, конечно, хотелось бы чтобы пользователь передавал строки в методы класса DMD -и они внутри автоматом перекодировались.

Зато в остальном схема более менее универсальна - меняя функции перкодировки и добавляя фонты с нужным чарсетом, можно добавить к DMD поддержку любого национального алфавита, символы которого кодируются 16-битным Юникодом.

b707
Offline
Зарегистрирован: 26.05.2017

Еще, кстати, конвертация фонтов из TTF позволяет делать фонты любого размера - например высотой в две матрицы или в три :) Понятно, что такие фонты будут довольно обьемными (8-15К на фонт), но для СТМ32 с ее 128К, в принципе, это не так и много.

Жалко у меня матриц в наличии всего две, а то я бы прямо сейчас попробовал :)

sadman41
Offline
Зарегистрирован: 19.10.2016

Не знаю, актуально ли это для STM, но на AVR замена digitalWrite() на прямое манипулировние регистрами экономит такты, а рисование из PGM-строки - экономит RAM. Если надо в этом плане подмогнуть - пиши в email, расскажу чего как.

b707
Offline
Зарегистрирован: 26.05.2017

Гриш, за предложение спасибо, но вроде пока не нужно. Работу с железом в этой либе я взял готовую из стандартной библиотеки DMD от Freetronics и пока улучшать не планировал. А что касается экономии памяти - все фонты там и так в ПРОГМЕМе

С ресурсами на СТМ особо проблем нет - код, что на видео, использует 17% флеша (половина из которых - фонты) и 12% оперативки. Всего.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

PGM-строка - это которая не перегружается в RAM. "Войну и Мир" гнать, например, бегущей строкой.

А замена digitalWrite на несколько простых конструкций давала мне выигрыш по скорости втрое на AVR-ке. 

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

PGM-строка - это которая не перегружается в RAM. "Войну и Мир" гнать, например, бегущей строкой.

Спасибо, если что - это я умею :) но у меня пока задач для такой бегущей строки нет - матрицы я просто поиграться купил. :)

sadman41 пишет:

А замена digitalWrite на несколько простых конструкций давала мне выигрыш по скорости втрое на AVR-ке. 

это я понимаю - и это интересно. Надо будет попробовать. Оригинальная библиотека, скажем так, не слишком эффективно написана, даже мне это очевидно.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

DIYMan , я победил Unicode :)

https://youtu.be/9xUB8-jk5Tc

Супер, браво! Теперь осталось сделать компилируемым под 328-ю мегу - и нахер заброшу штатную DMD ;) Осилим? ;)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

 матрицы я просто поиграться купил. :)

Не, это уже не просто поиграться - ты себе не представляешь, что ты сделал, и какой секас со шрифтами был. ОЧЕНЬ советую сделать кросскомпилируемым под разные платформы  (а не только под конкретный камень), и подумать над дальнейшим развитием. Всё - не вкладывай, рекламщики заплатят, если что ;)

Ещё вариант развития - GUI-редактор, и можно продавать ;)

З.Ы. Короче: развивай, если нужна мал-мала помощь - помогу, чем смогу. Пока не скачивал с гитхаба, но обязательно попробую - в наличии есть три матрицы. Кстати за них: надеюсь, ты в курсе, что схемотехника у матриц разных цветов может быть разная? Столкнулся с тем, что код, который на красной матрице показывал текст нормально, на зелёной - показывал инверсный текст. С точки зрения переносимости кода конкретной прошивки - желательно в библиотеке предусмотреть флаг в конструкторе, типа "инверсная логика" ;) Когда допиливал DMD - так и делал.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Теперь осталось сделать компилируемым под 328-ю мегу - и нахер заброшу штатную DMD ;) Осилим?

думаю да

Цитата:
Пока не скачивал с гитхаба, но обязательно попробую

и пока не скачивай - поддержки фонтов там пока нет

Цитата:

 Кстати за них: надеюсь, ты в курсе, что схемотехника у матриц разных цветов может быть разная? С точки зрения переносимости кода конкретной прошивки - желательно в библиотеке предусмотреть флаг в конструкторе, типа "инверсная логика" ;)

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

Цитата:
Всё - не вкладывай, рекламщики заплатят, если что ;)

а как тогда распространять? :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

В библиотеке, кстати, есть переключатели прямого и инверсного режима...

Ты имеешь в виду флаги отрисовки? Это не то, потому что применяется _по_месту_. А если мне нужно на букве текста отобразить звезду, скажем? Я просто в коде пишу, образно - draw(...,GRAPHICS_NORMAL), потом поверх draw(,,,GRAPHICS_INVERSE). И если я поменяю матрицу на красную, то окажется, что теперь текст - инверсный, а звезда - горит, поэтому надо в тыще мест поменять местами флаги отрисовки. Я же говорю - за общий флаг отрисовки, передаваемый в конструкторе, например ;)

b707 пишет:

а как тогда распространять? :)

Как обычно - основные плюшки - свободно, вкусности - за донат или лицензию. Так, чисто на поддержку штанов - конкуренция в этой нише есть, надо приложить массу усилий, чтобы сделать вкусный продукт. Но окупить свою работу - стоит, считаю. Потому как это совершенно чётко - рекламщики, там деньги есть, и не стоит бесплатно халявщиков плодить ;)

З.Ы. У меня матрицы красные, кста. Могу протестировать на Uno, если что ;) Blue pill щас нету, есть парочка взрослых STM - V и Z серий.

lean_74
Онлайн
Зарегистрирован: 22.12.2015

Я протестирую, если че.... 13 вернусь  с Питера и в легкую, десяток 103 как раз китайцы подвезли.

b8hri11
Offline
Зарегистрирован: 11.05.2019

Приветствую, пробовал данную библиотеку с инверсным красным модулем (инверсию поменял через библиотеку, но проблемы те же), имею следующие проблемы:

1. Если яркость находится в диапозоне от 258 до 65534 имеются моргания пикселей что горят выше. Если 257 или 65535 то проблемы нету. В библиотеке Евгения Мозка точно самое.

2. Очень моргает, у Евгения Мозака так не моргает.

С таким же успехом dmd2 SPI и Software версию сделал со всеми платформами, но проблема под номером 1 осталась ;(. Самое интересное что на AVR такой проблемы нету.

На руках ещё кучка контроллеров onbon bx-5ul, там стоит китайский GD32, он же разогнанный STM32, сделал трассировку платы и вывод такой, там используется софтварный SPI, кварц на 25мгц, последних два поменял на blue pill'овские и софтварная версия DMD2 работает. На заметку, там линии OE, A, B, SCLK, на оба порта используются те же, а вот R1 и CLK для каждого свой. Ну это так на будущее)

Все проверки делал на первом SPI PB5

  SPIClass dmd_spi(1);  
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // release PB3 and PB5 
  afio_remap(AFIO_REMAP_SPI1);
  gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode(GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode(GPIOB, 5, GPIO_AF_OUTPUT_PP);

Был бы ослик может избавился от первой проблемы ;(

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Приветствую, пробовал данную библиотеку с инверсным красным модулем (инверсию поменял через библиотеку, но проблемы те же), имею следующие проблемы:

1. Если яркость находится в диапозоне от 258 до 65534 имеются моргания пикселей что горят выше. Если 257 или 65535 то проблемы нету. В библиотеке Евгения Мозка точно самое.

2. Очень моргает, у Евгения Мозака так не моргает.

b8hri11, приветсвую

Что касается проблемы 1 - насколько я вижу по форумам, слабые мерцания незасвеченных пикселей  - это общая проблема библиотек DMD и DMD2 при использовании контроллеров с напряжением 3.3в. То что это связано со скважностью PWM - интересное наблюдение, надо будет проверить на АВР, может там так же?

По п 2 - поясните, что именно "очень моргает" ?

b8hri11
Offline
Зарегистрирован: 11.05.2019

b707 пишет:

Что касается проблемы 1 - насколько я вижу по форумам, слабые мерцания незасвеченных пикселей  - это общая проблема библиотек DMD и DMD2 при использовании контроллеров с напряжением 3.3в. То что это связано со скважностью PWM - интересное наблюдение, надо будет проверить на АВР, может там так же?

на китайском контроллере стоят 74hc245 они сигналы в 5 вольт преобразуют, но даже так видно проблему. На оригинальной плате там вообще нету мерцания даже на камеру. R1 обоих разъемов подключены на PB4 и PB5.

Сейчас ещё попробую на blue pill глянуть как оно будет работать.

b707 пишет:

2 - поясните, что именно "очень моргает" ?

Видно глазу как мерцает, как эфект строб, больно смотреть даже. Если в оригинале у Евгения исправить период таймера с 4000 до 1000 или 2000 то даже на камеру не видно мерцания.

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Видно глазу как мерцает, как эфект строб, больно смотреть даже. Если в оригинале у Евгения исправить период таймера с 4000 до 1000 или 2000 то даже на камеру не видно мерцания.

это в высшей степени странно - если вы сравните две библиотеки, код вывода сигнала на матрицу я взял у Евгения практически без изменений, добавил только выбор SPI канала и инициализацию SPI. Кстати. без этого код Евгения у меня вообще не работал. А у вас его код работает без изменений?

В моих тестах я особых мерцаний не вижу, хотя может просто не понимаю, куда смотреть ... это первые матрицы, которые я держу в руках

b8hri11
Offline
Зарегистрирован: 11.05.2019

b707 пишет:

 степени странно - если вы сравните две библиотеки, код вывода сигнала на матрицу я взял у Евгения практически без изменений, добавил только выбор SPI канала и инициализацию SPI. Кстати. без этого код Евгения у меня вообще не работал. А у вас его код работает без изменений?

В моих тестах я особых мерцаний не вижу, хотя может просто не понимаю, куда смотреть ... это первые матрицы, которые я держу в руках

примеры конечно же доработать пришлось, но содержание примерно то же что в вашей версии.

Фантомных пикселей нету если в место analogWrite или pwmWrite используется digitalWrite, но тогда яркость вырвиглазная)

#include <SPI.h>        //SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include <DMD_STM32.h>        //
//#include <TimerOne.h>   //
#include "SystemFont5x7.h"
#include "Arial_black_16.h"
SPIClass SPI_2(1);

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 1
#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(SPI_2);
}

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

    SPI_2.begin();                          //Initialize the SPI_2 port.
    SPI_2.setBitOrder(MSBFIRST);            // Set the SPI_2 bit order
    SPI_2.setDataMode(SPI_MODE0);           //Set the  SPI_2 data mode 0
    SPI_2.setClockDivider(SPI_CLOCK_DIV64); // Use a different speed to SPI 1
    SPI.setModule(1);
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // release PB3 and PB5 
  afio_remap(AFIO_REMAP_SPI1);
  gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode(GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode(GPIOB, 5, GPIO_AF_OUTPUT_PP);
    pinMode(SPI2_NSS_PIN, OUTPUT);
    //clear/init the DMD pixels held in RAM
    dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)
    //  Led Panel setup
    Timer3.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
    Timer3.setPeriod(3000);          // in microseconds
    Timer3.setCompare(TIMER_CH1, 1); // overflow might be small
    Timer3.attachInterrupt(TIMER_CH1, ScanDMD);
    dmd.setBrightness(100);
}

Если есть у кого ослик, посмотрите как выглядят сигналы digitalWrite и analogWrite на AVR и на STM32. Там думаю будет понятно.

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11  -насчет "моргает" - кажется понял, о чем вы. Если поставить brightness = 65535, то фантомных пикселей нет, но вся надпись иногда моргает - причем не ритмично, а то чаще, то реже, как будто наводки идут. Вы это имели в виду? Спасибо, попытаюсь разобраться.

Правда не могу проверить, было ли такое на коде Евгения, у меня даже с инициализацией SPI его код почему-то не работает.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan - "портировал обратно" свой код на Атмегу328 :)  Русские фонты работают.

Хотел посоветоваться. Не могу решить, как в библиотеке поступить с перекодировкой. Оставить это на юзера - чтобы каждый сам добавлял в скетч функцию utf8_rus() , по аналогии с тем, как в DMD заставлют пользователя вставлять в скетч инициализацию таймера. Или же встроить перекодировку в функции библиотеки?

Первый вариант выглядит несколько кустарно. Зато добавить другую кодировку вместо кириллицы - не проблема, заменил функцию в скетче да и все.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Из общих соображений:

1. Перекодировка из многобайтовой в однобайтовую кодировку, очевидно, операция с потерей информации. Зависит от используемой кодовой страницы. Соотвественно, если проект планируется как международный, эту операцитю следует либо делать вовне библиотеки, либо уж учиться правильно обрабатывать все 65536 юникодных символов, а не только символы кириллицы.

2. Обработка строки и отображение ее на устройстве - совершенно не связанные друг с другом операции. Вряд ли их целесообразно делать в одной библиотеке.

Т.е. оба соображения з-а то, чтобы в библиотеке перекодировки не делать.

И еще: с моей точки зрения, кустарно - это когда библиотека работы с "железом" заточена именно на кириллицу и не позволяет относительно простыми средтвами применять ее для других наборов символов.

b8hri11
Offline
Зарегистрирован: 11.05.2019

b707 пишет:

Правда не могу проверить, было ли такое на коде Евгения, у меня даже с инициализацией SPI его код почему-то не работает.


SPI.setModule(1); // тут spi выбрать нужно, если он не первый, то второй и код ниже не нужен
34
afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // release PB3 and PB5
35
afio_remap(AFIO_REMAP_SPI1);
36
gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP);
37
gpio_set_mode(GPIOB, 4, GPIO_INPUT_FLOATING);
38
gpio_set_mode(GPIOB, 5, GPIO_AF_OUTPUT_PP);
39

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:
SPI.setModule(1); // тут spi выбрать нужно, если он не первый, то второй и код ниже не нужен 34 afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // release PB3 and PB5 35 afio_remap(AFIO_REMAP_SPI1); 36 gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP); 37 gpio_set_mode(GPIOB, 4, GPIO_INPUT_FLOATING); 38 gpio_set_mode(GPIOB, 5, GPIO_AF_OUTPUT_PP); 39

это все не то. Это вы зачем-то "перемапили" SPI_1 на PB3-PB5, а если пользовать "родные" пины PA5 - PA7, то этот код не нужен. Как конфигурировать пины - это я все в курсе .

Вы мне так и не ответили на вопрос, в чем заключается "стробоскоп", который есть на моем коде и которого нет у Евгения? - Хаотичные редкие помаргивания символов - иногда раз в 2-3 секунды, иногда пару раз в секунду? - Оно?

b707
Offline
Зарегистрирован: 26.05.2017

andriano пишет:

Т.е. оба соображения з-а то, чтобы в библиотеке перекодировки не делать.

Пожалуй соглашусь :) Тем более что так и мороки меньше. Получается очередная XXXX-ая по счету библиотека руссуфикации чего-либо.

b8hri11
Offline
Зарегистрирован: 11.05.2019

stm32duino ?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

DIYMan - "портировал обратно" свой код на Атмегу328 :)  Русские фонты работают.

Хотел посоветоваться. Не могу решить, как в библиотеке поступить с перекодировкой. Оставить это на юзера - чтобы каждый сам добавлял в скетч функцию utf8_rus() , по аналогии с тем, как в DMD заставлют пользователя вставлять в скетч инициализацию таймера. Или же встроить перекодировку в функции библиотеки?

Первый вариант выглядит несколько кустарно. Зато добавить другую кодировку вместо кириллицы - не проблема, заменил функцию в скетче да и все.

Я за вариант номер 2. Составить документ по соглашению кодовой страницы шрифта, и всё. Впихнуть невпихуемое невозможно, рефлексировать на всех желающих - також.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Я за вариант номер 2. Составить документ по соглашению кодовой страницы шрифта, и всё. Впихнуть невпихуемое невозможно, рефлексировать на всех желающих - також.

нифига не понял, сорри. Какой документ по соглашению? Хелп с описанием как добавлять фонты? Или речь о коде?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Мне кажется, после тщательного обдумывания, как именно следует "составить документ", чаша весов склонится в пользу первого варианта ))).

b707
Offline
Зарегистрирован: 26.05.2017

andriano пишет:

Мне кажется, после тщательного обдумывания, как именно следует "составить документ", чаша весов склонится в пользу первого варианта ))).

В качестве подготовки - напишу о работе с национальными фонтами

Изначально задача ставилась так - прикрутить к DMD-матрицам какие-нибудь распространенные фонты. После изучения вариантов я выбрал формат GFXFont из библиотеки Adafruit_GFX. Формат простой и ясный и хорошо документированный, и при этом мощный. Но что важнее - в этот формат можно одним движением конвертировать любые TTF и OTF фонты при помощи родной утилиты fontconvert от того же Адафруита. Фонтов TTF OTF в инете десятки тысяч, для лыбых наборов национальных символов. Многие фонты бесплатны, в том числе и для использования в коммерческих проектах. Для примера ссылка на сайт :

https://www.fontspace.com/

Как человек ленивый - я сразу поставил себе условие, что фонты должны подключаться "как есть", без редактирования и сложных перекодировок. Большинство TTF фонтов используют Unicode для национальных символов, при этом латиница расположена в диапазоне 0х20 - 0х7E, а буквы кириллицы А-Яа-я имеют коды 0х410-0х44F.  Из этого возникает проблема - Формат GFX_font хранит битмапы символов сплошным массивом, и чтобы охватить разом латиницу и кириллицу, придется либо оставлять в фонте кучу (около 850-ти) неиспользуемых символов между латиницей и кириллицей, либо кириллицу перекодировать поближе к латинице.  Но мы же решили, что ничего перекодировать не будем. Поэтому делаем проще - для каждого фонта в библиотеке поддерживается несколько обьектов GFX-Font, каждый на свой диапазон кодов. Для латиницы и кириллицы получаем два отдельных компактных обьекта GFX_Font, в каждом из которых только нужные символы, а в момент вывода на матрицу конкретного символа библиотека сама выбирает нужный фонт.

Остается еще проблема, что в Ардуино ИДЕ для кириллицы используется совсем другая кодировка, которая вроде тоже Unicode, но коды другие и даже порядок символов не тот. Чтобы не трахаться (извините) с двухбайтовыми символами, строчки текста из Ардуино ИДЕ я перекодирую из 16битных в 8битные, отображая коды в верхнюю половину таблицы ASCII. При этом конкретные коды символов, используемые в библиотеке и в фонте - в общем-то не имеют значения, лишь бы лпростенькая программа перекодировки отображала одни коды в другие. Результат перекодировки должен иметь тот же порядок символов, что и в фонте GFX, например я в своей библиотеке поместил символы А-Яа-я в самое начало второй половины ASCII - 0x80 - 0xBF

Уф, пока все. Далее дам подробную инструкцию по конвертации TTF фонта из инета и подключения его к библиотеке

PS предупреждая возгласы "Хватит болтать, выкладывай код" :) - сорри, после замечаний товарища b8hri11 нужно еще кое-что проверить

 

 

b8hri11
Offline
Зарегистрирован: 11.05.2019

Вот компилируемый вариант Евгения

https://github.com/b8hri11/DMDSTM

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

Остается еще проблема, что в Ардуино ИДЕ для кириллицы используется совсем другая кодировка, которая вроде тоже Unicode, но коды другие и даже порядок символов не тот.

На самом деле и то, и другое - юникод, только две различные его формы: utf-8 и utf-16. 

utf-16 - это двухбайтовая кодировка, любой символ имеет длину ровно 16 битов. Отсюда недостаток - с utf-16 практически невозможна работа программ, рассчитанных на однобайтовыю кодировку (например, компиляторы).

utf-8 - кодировка переменной длины. Символы могут иметь различную длину - от 1 до 6 байтов. Что очень сильно затрудняет посимвольную бработку. Но зато все символы ascii представлены одним байтом. Что позволяет обрабатывать ее компиляторами, где все служебные слова и переменные задаются латинницей.

Естественно, между utf-8 и utf-16 существует взаимно однозначное соответствие и алгоримы перекодировки в обе стороны.

b707 пишет:

PS предупреждая возгласы "Хватит болтать, выкладывай код" :)

PS. Как по мне, так самое интереное на форуме как раз пишется по-русски. И в этом наблюдается явный дефицит.

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Вот компилируемый вариант Евгения

https://github.com/b8hri11/DMDSTM

b8hri11 - огромное спасибо за код! Запускал и сравнивал разные варианты - но основе библиотеки, предоставленной Вами -  и своей. В итоге выяснил следующее - неприятное мерцание картинки ("эффект строба") от библиотечного кода вообще не зависит - а зависит только от выбранного в скетче таймера для генерации прерывания для сканирования матриц.

Вот так запускается таймер в Ваших примерах:

    Timer3.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
    Timer3.setPeriod(3000);          // in microseconds
    Timer3.setCompare(TIMER_CH1, 1); // overflow might be small
    Timer3.attachInterrupt(TIMER_CH1, ScanDMD);

при этом мерцания нет, картинка четкая. Но если в приведенном выше коде заменить обьект Timer3  на Timer2 - появляется строб и картинка начинает дрожать. Причину такой разницы не знаю.

 

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

 

 

 

b8hri11
Offline
Зарегистрирован: 11.05.2019

Да ладно прибедняться, лучше обьясни что не нравится компилятору под stm32duino в примере marque из dmd2. Он то ошибку в строке drawstring_p видит, то компилирует, но платка в цикличный резет уходит.
Портируется аналогично, так же таймер поменять, и ifdefine для stm добавить в паре мест. Попозже выложу на гитхаб.

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:
Да ладно прибедняться, лучше обьясни что не нравится компилятору под stm32duino в примере marque из dmd2. Он то ошибку в строке drawstring_p видит, то компилирует, но платка в цикличный резет уходит. Портируется аналогично, так же таймер поменять, и ifdefine для stm добавить в паре мест. Попозже выложу на гитхаб.

выкладывайте.

А я пока фонтами займусь

b707
Offline
Зарегистрирован: 26.05.2017

Выложил на гитхаб новую версию с поддержкой Unicode шрифтов в формате Adafruit GFX.

Добавлено:

 - новый класс DMD_Font с потомками DMD_Standard_Font  для работы со старыми фонтами библиотеки DMD и DMD_GFX_Font для фонтов Adafruit GFX соответственно (см пример dmd_cyr_chars)

- выполнено обратное портирование на АВР, пока поддерживается только Атмега328 (см пример dmd_cyr_uno)

- добавлен метод inverseAll() для работы с матрицами. инвертированными на аппаратном уровне

- переписаны все примеры

Соответвенно изменился синтаксис работы с фонтами, метод selectFont() не совместим с прошлой версией. Документации пока нет, смотрите примеры.

DIYMan - код решил выложить полностью, так как пока нет уверенности в том, насколько он окажется полезным...

 

b8hri11
Offline
Зарегистрирован: 11.05.2019

Вот DMD2 под STM, но там не работает пример marque, не понимаю что компилятору не нравится

https://github.com/b8hri11/dmd2-stm

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Вот DMD2 под STM, но там не работает пример marque

А другие примеры работают? Компилятор никаких предупреждений не выдает?

b8hri11
Offline
Зарегистрирован: 11.05.2019

b707 пишет:

А другие примеры работают? Компилятор никаких предупреждений не выдает?

С другими все в порядке, он ругается на строку drawstring_p вроде бы так, но по факту все есть. Потом бац и кломпилирует, но плата в резете

Разобрался, в примере если убрать F(""), то всё работает

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Разобрался, в примере если убрать F(""), то всё работает

то есть ничего делать не надо? или нужна какая-то помощь?

b707
Offline
Зарегистрирован: 26.05.2017

Обновление - добавлена вертикальная бегущая строка. Вроде в оригинальной DMD этого нет, хотя может ошибаюсь.

Видео:

https://youtu.be/JNL-5qp6bDc

Сорри, в релиз на  Гитхабе пока гне вошла.

b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 - на примерах для СТМ обнаружил любопытный глюк, может вы сталкивались на своем коде или на коде Евгения.

При подключении 2х матриц анимация начинает как-то странно подтормаживать. Странно - потому что неравномерно. Две-три строчки пробегают с нормальной скоростью - потом строчки начинают ползти, зрительно раза в 2 медленнее. Немного времени пройдет - снова все бегает...

не похоже, чтобы плата не успевала - более вероятно какой-то глюк с таймером анимации.

b8hri11
Offline
Зарегистрирован: 11.05.2019

Первую dmd не использовал нигде. Вторая в основном, но там проблем не было.

b8hri11
Offline
Зарегистрирован: 11.05.2019

Короче чтобы избавиться от моргающих фантомных пикселей нужно закомментировать следующее, но помогает до 58% яркости)

//Timer3.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
Timer3.setPeriod(4000);          // in microseconds
//Timer3.setCompare(TIMER_CH1, 1); // overflow might be small
Timer3.attachInterrupt(TIMER_CH1, ScanDMD);
b707
Offline
Зарегистрирован: 26.05.2017

b8hri11 пишет:

Короче чтобы избавиться от моргающих фантомных пикселей нужно закомментировать следующее, но помогает до 58% яркости)

спасибо, попробую.

Но вообще ,  на Таймере3 в той версии кода, что на Гитхабе, у меня фантомные пиксели на любой яркости практически незаметны.