ARDUINO Бегущая строка на сдвиговых регистрах - вывод котировок акций мосбиржи

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Вести в полей:
Теперь дёргаю Latch в конце загрузки всех регистров вместе с переключением адреса. В статической картинке ничего не изменилось, всё так же гладко и чётко. Если тупо двигаю буфер на единичку, то баг с потерянными пикселями в 16-том столбце остался, и опять та же картина: для движения влево делитель 15 (теряется каждый 16 столбец), для движения вправо - 17 (дублируется каждый 16 столбец). При других делителях видно всё изображение, но опять это "двоение". Похоже, где-то не том месте цикла я меняю делитель.


@Sonya,
диаграмма выходов out0 - out7 у вас тоже не такая, как на больших матрицах. У вас тут идут относительно короткие импульсы, если верить картинке, а на тех матрицах выходы out находятся в фиксированном положении все время показа очередного канала.
На той картинке нет варианта, когда Enable активен в процессе загрузки, разработчики не предусматривали такой вариант, а у меня именно такой случай.
 
Изменено:

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Понимаю, что не видя того, что происходит на матрице, сложно советовать. Поэтому постарался снять два демонстрирующих видео, как бегущую строку видит глаз:
Видео бегущей пилы при использовании логичного делителя 16 или когда тупо сдвигаем буфер на 1 по завершению развёртки 16 столбцов.
По идее, всё должно быть красиво, а по факту видим изломы наклонных линий. Буквы так же искажаются.
C++:
  Column++;
  Column &= 0b00001111; //  if (Column > 15) Column = 0;
    if  (Column == 0) Index++;

Видео бегущей пилы при использовании делителя 15. Строка бежит плавно, но теряем каждый 16й столбец.
C++:
  Column++;
  Column &= 0b00001111; //  if (Column > 15) Column = 0;
Divider++;
    if (Divider > 14) Divider = 0;
    if  (Divider == 0) Index++;
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
2,988
895
@Sonya, ну так Вы так и не ответили на вопрос: сколько занимает одна развёртка на полную матрицу?
Я к тому, что для того, чтобы не было видимого перескока, нужно, чтобы "кадр" оставался статичным более длительное время, чем перерисовка экрана. Кстати, на Ваших видео движение слишком быстрое и, похоже, Вы всё же не синхронизировали смену указателя буфера. Иначе откуда взялись длительные отсуствия пикселей по всей длине матрицы?
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
@Sonya, ну так Вы так и не ответили на вопрос: сколько занимает одна развёртка на полную матрицу?
Я же писал. Прерывания 1000мкс, частота 1кГц. Экран прорисовывается за 16 циклов по столбцам (см гифку из первого сообщения), соответственно столбец горит 1мс, а на отрисовку всей матрицы тратится 16мс. Одновременно отображаются 5 столбцов, по одному в каждом блоке 8x16 из двух индикаторов.


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

Кстати, на Ваших видео движение слишком быстрое
Скорость движения именно такой и должна быть, чтобы один пиксель загорался в нужном месте только один раз, все другие скорости дают только эффект размазывания. И в оригинальной прошивке этой бегущей строки именно так сделано.

и, похоже, Вы всё же не синхронизировали смену указателя буфера. Иначе откуда взялись длительные отсутствия пикселей по всей длине матрицы?
В том то и дело, что синхронизировал, изменение указателя происходит в том же цикле, где и динамическая индикация. И тут даже видно, где теряется один пиксель: на 15 (предпоследнем такте) я увеличиваю указатель, и на шестнадцатом такте (последнем) уже выводится содержимое буфера+1, т.е. текущее содержимое буфера никогда и не выводилось. Но если менять указатель каждые 16 тактов, то вылазят эффекты "лесенки"

PS: Сейчас поменял развёртку в обратную сторону, делаю Column--, соответственно строки отображаются справа налево. Теперь для плавности движения пришлось сделать делитель 17, т.е. сдвигать указатель каждый семнадцатый такт. Соответственно, теперь каждый 16 столбец выводится два раза.
C++:
  Column--;
  Column &= 0b00001111; //  if (Column > 15) Column = 0;
  Divider++;
    if (Divider > 16) Divider = 0;
    if  (Divider == 0) Index++;
Чувствую, косяк где-то рядом. Но не вижу.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,898
862
В том то и дело, что синхронизировал, изменение указателя происходит в том же цикле, где и динамическая индикация. И тут даже видно, где теряется один пиксель: на 15 (предпоследнем такте) я увеличиваю указатель, и на шестнадцатом такте (последнем) уже выводится содержимое буфера+1, т.е. текущее содержимое буфера никогда и не выводилось.
судя по описанию, у вас где-то банальная ошибка с индексами в циклах. При показе строки вообще не должно быть никакой зависимости от скорости.
В конце концов, "механика" вывода картинки на экран до боли простая, загрузили в регистр - вывели... и так по кругу. Чудес-то не бывает, а раз не бывает - значит это ваша программа косячит.
У вас логиканализатор есть? - подключите к нему все линии управления и посмотрите картинку в графическом виде. Очень помогает в поиске ошибок.
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
судя по описанию, у вас где-то банальная ошибка с индексами в циклах.
В конце концов, "механика" вывода картинки на экран до боли простая, загрузили в регистр - вывели... и так по кругу. Чудес-то не бывает, а раз не бывает - значит это ваша программа косячит.
Так и я о том. Где-то нарушена логика программы, но без стороннего взгляда не получается найти это.

При показе строки вообще не должно быть никакой зависимости от скорости.
Это при большой разнице между частотой развёртки и скоростью движения строки. А тут скорости уже соизмеримы, потому и вылазят некоторые эффекты.

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

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Снял видео с оригинальной прошивкой.

Также сделал замедленное видео:

И тут я вижу, что развёртка идёт справа налево, т.е. обратная моей. Попробую тоже так сделать, плюс добавлю пропуск одного кадра, чтобы не было задвоения.
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Вести с полей:
Сделал обратную развёртку.
Нашёл баг с делителем, оказывается в эффекте "лесенки" был виноват переход из одного блока 16x8 в другой. Так как я в конце цикла увеличивал индекс, то следующий цикл начинался со сдвига на 1 столбец, а чтобы компенсировать этот сдвиг пришлось также поменять адреса буфера видеопамяти.

Было так::
Bank0 = (Column + 64 + Index) & B01111111;
Bank1 = (Column + 48 + Index) & B01111111;
Bank2 = (Column + 32 + Index) & B01111111;
Bank3 = (Column + 16 + Index) & B01111111;
Bank4 = (Column + Index) & B01111111;
Стало так::
 Bank0 = (Column + 68 + Index) & B01111111;
Bank1 = (Column + 51 + Index) & B01111111;
Bank2 = (Column + 34 + Index) & B01111111;
Bank3 = (Column + 17 + Index) & B01111111;
Bank4 = (Column + Index) & B01111111;
И всякие делители стали не нужны, просто увеличиваю индекс перед началом цикла развёртки:
C++:
  Column--;
  Column &= 0b00001111; //  if (Column > 15) Column = 0;
if (Column == 15) Index++;
Правда, теперь для вывода статического текста придётся делать отдельный цикл, но это мелочи.

Добавил поддержку цвета в процедуру отрисовки строки.
Осталось дело за малым - научить контроллер принимать новую строку с текстом.
 
Изменено:
  • Лойс +1
Реакции: bort707

Bruzzer

★★★✩✩✩✩
23 Май 2020
327
102
Не понял логики в вашем решении (это не значит, что вы не правы). Т.к. мне проверять не на чем, то чисто теоретически я был склонен считать эффект лесенки при кадровой синхронизации (16) "визуальным эффектом на границе блоков матриц". При условии что буфер заполнен без ошибок, и сигналы подаются без ошибок.
Сейчас (после исправлений) если подать двухстороннюю пилу, то лесенки тоже нет? /\/\/\
П.С. на видео с оригинальной прошивкой "ступенек" полно. Даже не запуская видео, буква Р ломанная.
П.П.С. Видео с оригинальной прошивкой снято хорошо, камера не двигается, все пиксели видны. Ваши варианты сняты не удобно для просмотра.
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Не понял логики в вашем решении (это не значит, что вы не правы). Т.к. мне проверять не на чем, то чисто теоретически я был склонен считать эффект лесенки при кадровой синхронизации (16) "визуальным эффектом на границе блоков матриц". При условии что буфер заполнен без ошибок, и сигналы подаются без ошибок.
Ну да, те эффекты "лесенок" были при переходе с одного блока 16x8 на другой. И как я на это не обратил сразу внимания...

Сейчас (после исправлений) если подать двухстороннюю пилу, то лесенки тоже нет? /\/\/\
Да, теперь пила бежит идеально. Текст из библиотеки runningText.ino тоже бежит, но там очень не оптимизированный код, всякий раз рендерить весь буфер полностью - не лучшее решение. Но хоть так работает...
 

kDn

★★★★★✩✩
18 Ноя 2019
1,103
437
@Sonya, на остановленном кадре явно виден излом для красной части пилы.
А что касается runningText.ino - когда я туда глядел пару лет назад, там было ряд багов. Как сейчас я хз.
1643812407301.png
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
@Sonya, на остановленном кадре явно виден излом для красной части пилы.
Ну так в матрице динамическая индикация, она ж не синхронизирована с затвором камеры, поэтому и вылазят артефакты. Главное, что глазом видно нормально, даже с близкого расстояния.

А что касается runningText.ino - когда я туда глядел пару лет назад, там было ряд багов. Как сейчас я хз.
Не вспомните, что за баги? С тех пор библиотека и не обновлялась.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
327
102
@Sonya,
Наверное есть умные книжки в которых написано, как надо сканировать много матричные индикаторы. Но я их не знаю.
Могу предложить попробовать использовать кадровую синхронизацию (сдвиг через 16 столбцов) в старом варианте
(Column + 16 + Index) но колонки перебирать не последовательно, а так

0​
2​
4​
6​
8​
10​
12​
14​
15​
13​
11​
9​
7​
5​
3​
1​

тогда может пропасть "между матричный оптический эффект" (я так думаю). Повторюсь, это чисто логическое предположение. Но проверить не сложно.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,898
862
Вести с полей:
Сделал обратную развёртку.
Нашёл баг с делителем, оказывается в эффекте "лесенки" был виноват переход из одного блока 16x8 в другой. Так как я в конце цикла увеличивал индекс, то следующий цикл начинался со сдвига на 1 столбец, а чтобы компенсировать этот сдвиг пришлось также поменять адреса буфера видеопамяти.
Сорри, могу ошибаться, но... сдается мне, что это никакое не решение, а просто замаскированный дивайдер = 15...
В смещении между блоками в 16 пикселей был явный смысл - это размер блока.
А у смещения 17 пикселей никакого смысла нет.
17 пикселей при движении назад - это то же самое как дивайдер 15 при движении вперед
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Вести с полей.

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

Сделал чисто аппаратные действия: прошил в плате Arduino микросхему Mega328P, вставил в плату матрицы. Работает, но быстрее. Оказалось, что там микроконтроллер разогнан - кварц-то на 20МГц. Поменял в программе на 20МГц - скорость нормальная, но из Arduino IDE теперь не шьётся, т.к. нужно менять загрузчик - он-то остался прежним, на 16МГц. Буду разбираться.
20220208_090639.jpg

А вот так выглядит плата с бегущей строкой. Мега теперь в панельке, чтобы удобнее было прошивать.

Schematic_Running string_2022-02-08.png

Дорисовал схему, добавил логику и регистры.
 
Изменено:

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
С загрузчиком и работой на частоте 20МГц тоже разобрался - записал optiboot программатором. Оказывается, во время сборки скетча, одновременно генерится и нужный загрузчик. Загрузчик взял из проекта miniCore.

Теперь перехожу к главному, ради чего всё это затевалось:
информер курсов валют и акций.
Запустил код на ESP8266, выводит курсы на экранчик.
20220208_092259.jpg

Осталось организовать передачу полученных строк c ESP на arduino. Кто-нибудь делал такое? Не хотелось бы изобретать велосипед.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,898
862
@Sonya, библиотеку UARTTransfer посмотрите
А вот тут есть пример использования как раз для такого же обмена
 

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Промежуточные результаты: отладил на ESP8266 парсинг данных с iss.moex.com, сделал отправку через UART. На стороне mega32 сделал приём этой строки, вроде уже что-то неуверенно работает: приёмная строка бьётся во время приёма (теряются 4-8 байт), а полученная строка при отрисовке немного мерцает - с такой длинной строкой (255 символов) я ещё не запускал программу. Получается, runningText.ino не оптимизирована и каждый проход заново рендерит всю строку целиком. Придётся переписывать самому.




Во вложении скетч для получения данных с iss.moex.com, парсинга и отправки готовой строки в UART. Вдруг кто-то захочет прикрутить к своей строке котировки с мосбиржи.
 

Вложения

Изменено:

Sonya

✩✩✩✩✩✩✩
2 Июн 2020
38
3
www.cctvsp.ru
Вести с полей: полностью переписал и оптимизировал алгоритм вывода бегущей строки, теперь бегущий текст не мерцает независимо от длины строки. Оптимизация решила и вторую проблему - потерю символов при передаче, теперь строка принимается полностью и стабильно. Переделал массив шрифтов: теперь строка принимает текст в кодировке win1251 (а не в UTF-8, как раньше), расширил знакогенератор до 256 символов, перерисовал буквы, начертания которых мне не понравилось. На этом допил бегущей строки можно считать завершённым.



PS: Конечно, есть ещё куча идей о выводе на эту строку прогноза погоды, рекламной информации, даты-времени и показания датчиков, возможности задания текста бегущей строки из веб-интерфейса ESP8266. Возможно, со временем организую и это.
 

Вложения

  • Лойс +1
Реакции: superflint