Как стать автором
Обновить

Комментарии 80

НЛО прилетело и опубликовало эту надпись здесь
почему 65? 8*8=64.

второй вопрос уже к производителям. наверное все же выгоднее и логичнее производить матрицы без контроллера. обеспечивает встраиваемость и гибкость применения. я так думаю.
Потому что 64 катода, скажем, и один общий контакт для анодов. Или наоборот.
Вы правы. исправляю.
64 цифровых выходов + земля, 65-тый выход не нужен
+ земля
Вы напрямую матрицу к микроконтроллеру подключаете или там более сложная схема?
я в радиоэлектронике не силен, мягко говоря. нет, выводы, отвечающие за строки подключаются (в моем случае) через резисторы. чтобы не вышли из строя ножки контроллера в лучшем случае и чтобы он не сгорел в худшем.
[irony]Красота оформления кода, и его структурированность просто поражают.[/irony]
знаете, код форматирован нормально. а как этот код отображается после публикации — другое дело. не пойму почему так.
буду благодарен, если вместо иронии подскажете как исправить)
может это поможет

Подсвечивает код программы (поддерживается bash, cpp, cs, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, tex)
чёрт, скушало теги source lang=«язык» и закрывающий тег /source
спасибо
Если чуть выше окна с комментарием нажать на ссылку «html-теги», то появится не плохая подсказка.
Вы наверное своим примером можете улучшить учебные примеры по arduino.
Напрямую аноды матрицы к выводам контроллера обычно не подключают. На то есть минимум две причины:

1) Нагрузочная способность выводов. Даже если выходного тока хватит на питание всех диодов столбца одновременно, внутреннее сопротивление выходного буфера заявит о себе, и столбец, в котором включены два светодиода, будет светиться ярче, чем столбец с четырьмя.
Ситуацию усугубляет то, что в устройствах с динамической индикацией светодиоды работают в импульсном режиме, и на них подают ток больше номинального (часто в несколько раз).

2) Хорошо, если столбцов всего 8, а если их, скажем, 128 (как на большом табло «бегущая строка»)? Для коммутации столбцов удобно использовать счетчики, дешифраторы или сдвиговые регистры. В последнем случае достаточно использовать всего 2 вывода контроллера (сброс и сдвиг) независимо от количества столбцов.
Дичайше неэкономное использование ножек. Поставьте сдвиговые регистры, на любое количество светодиодов уйдёт всего 4 ножки или меньше.
Сдвиговые регистры не всегда подходят для таких вещей — например при инициализации регистров их выходы пляшут как хотят (такой Новый Год пускай идет доли секунды, но бывает очень портит весь проект).
Ничто не мешает буферезировать их.
Если это так критично — подключите линии строк через дополнительный буфер с tri-state выходами. Алгоритм работы следующий:
1) Подали питание;
2) Проинициализировали регистры;
3) Переключили буфер из Z-состояния в рабочее.
Для этого придумали ещё одну ножку — сброс
Ардуина даже не успевает даже загрузиться пока пляшут регистры. Единственный придуманный колхоз — повесит питание регистров через «реле», и дальше включать его при готовности управлять (2 секунды после подачи питания).
А, понял о чём вы. Тогда можно подтягивающий резистор на reset повесить.
хмм, где вы были раньше…

в итоге после пляски 3х регистров — поставил Arduino Mega на эти задачи. Сердито получилось))
Извините, немного не в теме, но что в Ардуино зашито такого, что грузится целых 2 секунды?
ничего сверх естественного, но Ардуинка подключена по USB к компьютеру, который ресетит его при загрузке.

Посторюсь, даже доли секунды достаточно чтобы испортить картину — у меня на выходе регистров через ключи стояло 24 двигателя. Эта карусель сбивала датчики положения валов.
Понятно. В таком случае разрешение работы периферии по отдельному сигналу готовности должно спасти от дискотеки.
Бутлоадер, который ждёт 2 секунды?
Транзистор поставьте, который зажигает светодиоды, делов-то. Пока он закрыт, никакие пляски в регистрах ничего не испортят.
Регистры разные есть. Есть и с защелкой. Пока строб не дашь ничего не шелохнется. 595й вроде бы такой, но могу ошибаться с номером.
Да, у 74HC595 защёлка есть, и стоит он копейки. Хорошая штука, я через него не то что светодиодную матрицу, а LCD на HD44780 и сервы подключал.
я в общих чертах имею представление, что такое сдвиговые регистры, но с ними не работал. к тому же, в данном случае задача была не «как экономить порты ввода\вывода», а разобраться с принципом динамической индикации. ну и как вдобавок написать «бегущий» текст.
думаю, поняв алгоритм людям несложно будет это все реализовать со сдвиговыми регистрами. хотя, те кто работает со сдвиговыми регистрами, думаю, давно знают как программировать дин. индикацию :)
Какой-то парадокс курицы и яйца получился, не находите? В статье подробности не описаны, потому что «тем, кто подробности знает, эта статья не нужна».
Принципы динамической индикации изложены отлично, не спорю, но хотя бы пару предложений о том, «как это делают в настоящих проектах» стоит добавить.
согласен. только я не делал «настоящих проектов» с матрицами и сдвиговыми регистрами. поэтому, эта статья — не более чем моя личная маленькая победа) о как загнул.
Если это победа лично ваша, и опыта или полезной информации другим она не принесет то зачем делать статью?

ИМХО если вы включите все 8 светодиодов в одном столбце то нагрузка превысит допустимые значения по Даташиту, да это не критично но при продолжительной перегрузке МК будет греться и через «N-ое время» выйдет из стоя.
не выйдет из строя. к ножкам МК выводы строк подключены через резисторы.
А ты ток посчитал? какой в общем будет? явно более 80 мА
я скажу так. ( в который раз:) в электронике я не силен. считал не я и паял тоже. вот. но я УВЕРЕН, что все там в порядке на 100%.
В этом случае яркость одного диода будет в 8 раз выше чем зажженых 8ми диодов. Цветастая получится картинка :)
так ведь в моей реализации в один момент времени включен только один светодиод всегда. 8 одновременно не включатся никак в моем коде)
А! У вас поточечная. Ну тогда да, согласен. Но это тускло. Хотя у данной матрицы весьма неплохой запас по яркости. Видать диоды светятся чуть ли не от святого духа (Помню были у меня зверские светодиоды которые начинали светиться если их просто в руки за разные ножки взять)
яркость программно можно «регулировать». задерживать больше времени светодиод в состоянии «включен». но можно дорегулироваться, что будет ярко, но картинка заметно мигает. или наоборот, мигание совсем нет, все плавно, но очень тускло.
Перечитал внимательно код. У вас же развертка идет и по строкам, и по столбцам! То есть в данный момент времени горит не больше одного светодиода. Да, проблему нагрузочной способности это решает, но в целом такое решение хорошим не назовешь.
— частота обновления картинки в восемь раз ниже, чем могла бы быть;
— вместо побайтного вывода используется побитовый — слишком громоздкий и неэффективный код получается;
— нужны искуственные задержки для выключенных пикселей.
Ocelot, спасибо, я ошибся — думал что реализация как раз по байтовая, да в таком случае с нагрузкой все в порядке.
По поводу обновления картинки: на видео легко увидеть, что обновляется не весь массив, а его часть (будто выключили v-sync). Чем это обусловлено и как это исправить?
Увеличить скорость прорисовки, сделать как раз байтовую динамическую индикацию, когда обновляется 1 строка/столбец за шаг но в таком варианте обязательно использование внешних ключей (транзисторов)
я ведь написал, что это не эталон, как программировать дин. индикацию.

а как проверить одновременно строку, например? я пробегаю по массиву двумерному и где в массиве TRUE, то есть 1, в том месте включаю светодиод.

мне интересно посмотреть и услышать комментарии как другие реализовуют.
Пусть матрица 8x8 и управляется 16 выводами (8 столбцов — PORTB, 8 строк — PORTC) через ключи, чтобы решить проблему мощности, но без всяких сдвиг. регистров.
Состояние экрана хранить в виде массива из восьми байт, причем каждый байт соответствует столбцу.
Вывод:

unsigned char screen_buffer [8];
// ...
for (char i=0; i<8; i++)
{
   PORTB = (1 << i); // включили столбец i
   PORTC = screen_buffer [i]; // зажгли нужные пиксели столбца
   delay ();
}
если можно привести код, например, зажечь какой-нибудь символ. для болей ясности.
Вместо //… вставить следующее:

screen_buffer [0] = 0x1F; // 00011111
screen_buffer [0] = 0x3F; // 00111111
screen_buffer [0] = 0x6C; // 01101100
screen_buffer [0] = 0xCC; // 11001100
screen_buffer [0] = 0xCC; // 11001100
screen_buffer [0] = 0x6C; // 01101100
screen_buffer [0] = 0x3F; // 00111111
screen_buffer [0] = 0x1F; // 00011111

Это для буквы A. Возможно значения придется инвертировать (смотря какие применяются ключи) или изменить порядок (смотря как скоммутированы выводы).
По-хорошему нужно один раз объявить набор констант с матрицами для всех символов, а потом просто копировать в screen_buffer / менять указатель. Бегущая строка организуется путем сдвига элементов в массиве screen_buffer:

void shift (unsigned char &screen_buffer)
{
   for (char i=0; i<7; i++)
   {
       screen_buffer [i] = screen_buffer [i+1];
   }
   screen_buffer [7] = 0x00;
}
в первом куске кода, конечно, индексы не все 0, а от 0 до 7.
жесть. это круто. мои мозги мыслили только в направлении точечной прорисовке картинки. оказывается можно целиком построчно\поколонно рисовать. спасибо.
Только вам под это дело придется схему переделывать. Т.к. один вывод не протащит через себя сразу 8 точек. либо они будут в восемь раз тусклей одного.
Ну я же написал:
>через ключи, чтобы решить проблему мощности
я понял. просто взял на заметку, что есть такой способ.
я тоже так думал сделать. для каждой буквы объявить массив 8х8 типа boolean правда.

а бегущая строка и у меня организуется путем сдвига массива влево на одну колонку.

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

unsigned char screen_buffer [256];
unsigned int position, endpos, column;

// здесь забиваем в screen_buffer всю строку

for (position = 0; position < 256; position++) // сдвиг окна
{
   endpos = position + 8; // определяем правую границу окна
// вывод столбцов,
// попавших в окно
   for (column=position; column<endpos; column++) 
   {
      delay (1);
      if (column > 255) continue; // проверка границ
      PORTB = (1 << column); // включили столбец 
      PORTC = screen_buffer [column]; // зажгли нужные пиксели столбца
   }
  delay (1000);
}

На будущее: вместо циклов с задержками правильнее использовать таймеры и прерывания.
Еще поправочка. Вместо:
for (column=position; column<endpos; column++)
...
PORTB = (1 << column);

нужно написать:
for (char i=0, column=position; column<endpos; i++, column++)
...
PORTB = (1 << i);

Всё, спать пора!
логично
Проблема динамической индикации только в одном — большая загрузка проца (когда число точек идет на сотни) и низкая яркость их. А срегистрами получается все очень дубово, можно воообще даже статично сделать, но это много регистров уйдет :)
если придется мне программировать матрицу на сдвиговых регистрах — обязательно напишу о получившемся) хотя до меня все уже давно написано и сделано и разжевано.
При дин. яркости можно ставить большие токи(максимально допустимые) или даже вылазить то тут уже надо смотреть при каком токе идет перегрев а при каком деградация.

на счет мк, чаще всего под большие матрицы ставят отдельные мк к которыми управляют с Основного мк, получается что то на подобии самодельного графического дисплея

регистры используют не на квадратных матрицах а на бегущих строках чаще всего…
Ну тут регистр незачем ставить, всего 16 выводов. Но если матрица большая… то регистры то что доктор прописал. Даже в динамике, правда вешать их надо будет на SPI и гонять данные на 100Мбит, а может и выше.
AVR такую скорость не потянет только ARM или что то работающие на таких скоростях
Ой не мегабит, 100-400 килобит. :))) SPI там аппаратная, так что это ее даже не напряжет. А скорости аврки вполне хватает, чтобы обслуживать LED CUBE 16x16x16
Здесь так много говорят о сдвиговых регистрах, что стало ужасно интересно как это все реализовать вместе с Arduino. Стал искать по статьям на хабре и… ничего не нашел. Тут столько людей об этом знают и никто ничего про это не написал? Или никто не реализовал ничего?

Большое спасибо автору — все доступно, просто и понятно. На подходе Arduino, скоро буду экспериментировать и начну с вашей статьи =)
Интернет хабром не ограничивается, тем более есть «электронный хабр» — easyelectronics.ru, и там статей про сдвиговый регистр достаточно.
Ну это понятно, не первый день в сети. Все равно жаль, что приходится куда-то ходить и что-то искать вместо того, что бы прочесть это все на родном хабре =)
Если все-все-все пихать на хабр, то он быстро превратится в нетематическую помойку.
Тот кто пользуется сдвиговыми регистрами, чаще всего использует просто AVR или PIC без Arduino
robocraft.ru/blog/arduino/519.html лови про регистры. очень просто описано
О, спасибо большое!
Вообще это основы, поэтому когда вы вдруг начнете читать хоть какой угодно мануал для новичков, вы всеравно на них наткнетесь.
буду рад, если поможет статья.
А что там писать? Три строчки? Я вам и тут напишу: два входа, 8 выходов. Выставляете бит на входе, дрыгаете вверх-вниз ножку сдвига, при этом бит, который был на входе появляется на 0-м выходе, что было на 0-м появляется на 1-м, и так далее (данные на выходе сдвигаются). Подключив каскадом следующий регистр входом на 7-й выход предыдущего — получим регистр с 16-ю выходами, и так каскадировать можно до бесконечности.

Есть еще вход сброса, есть регистры с защелками — на выходе данные не ползут, а буферизируются, появляются только по вашей команде. Но это частности.
Мой первый проект с микроконтроллером — это как раз бегущая строка. Делал на регистрах, что интересно, вообще мало понимал до того, как со всем этим хозяйством делать, но ничего — разобрался. Сделал успешно работающую строчку 7х5, потом решил сделать ее длиннее и перенести на печатную плату, но что-то там в регистрах загуляло не то, и в итоге в буфер писалось не то, что нужно. Так теперь изделие валяется не доделанное.
а можно код того, что на видео?
или опишите, пожалуйста, что менять надо под больший массив
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории