35

Улучшаем матрицу 8x8 для Arduino при помощи сдвиговых регистров

Вступление

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

Хорошо описано. Что-то даже захотелось свои поделки на ардуйне выкладывать.

В тот же день, на мой комментарий отозвались еще несколько человек и подбили меня на публикацию своей работы. Что ж, этот пост специально для @technoid91@slavikf@PomidorniyBochok,  ну и конечно для всех остальных, кому интересна тема электроники и программирования под Arduino.


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


Обозначу сразу следующие пункты:

Я не электронщик и не претендую на это звание.

Спаяно не красиво, припой не убран, ножки у резисторов до конца не срезаны. Это потому, что схема не будет оставаться в таком виде и при наличии материалов и времени будет переделана, поэтому то, что сделано сейчас – временно.


Языками C и C++, а значит, что и языком Arduino, я не владею в полной мере и не являюсь асом. Уверен, что профессионал выполнил бы скетч гораздо экономнее по памяти и грамотнее. Но мне как-то все равно, потому что контроллер поставляемый в Arduino UNO и Nano спокойно справился со скетчем, а для меня, в рамках хобби, этого достаточно.


Я в курсе о существовании схем MAX7219, MAX6960 и аналогичных им, а также готовых модулей матриц, но есть парочка «но»:

1) Из-за торговых проблем с Китаем, временно таких схем нет в наличии в моем городе и подозреваю что в стране в целом.

2) Базовый набор, который я покупал в местном магазинчике, содержал голую матрицу, без доп. модулей, а также два голых модуля семисегментников на 1 и 4 цифры. Поэтому покупать еще одну матрицу только потому что ею будет удобнее управлять – расточительство для моего кармана.

3) Всегда полезно изучить что-то в ходе создания/повторения проекта, поэтому это отличное подспорье, чтобы научиться чему-то новому.


Разделю пост на два основных раздела Hardware и Software.


Железки (Hardware)


И так, для выполнения этой задачи мне понадобились следующие вещи:

1) Сама матрица. Моя была с маркировкой 1088BS.

2) Два сдвиговых регистра 74HC595N. Для управления по двум осям X и Y.

3) 8 резисторов на 220 Ом, т.к. мы имеем дело со светодиодами, а подключать светодиоды в цепь без резисторов – это слишком даже для такого дилетанта как я.

4) 7 пинов для удобного подключения в виде модуля. Они пылились без дела в моем стартовом наборе и прям напрашивались на использование.

5) Перфорированная плата для единичных вариантов самоделок.

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


Идея не моя, ее я позаимствовал отсюда: https://cxem.net/arduino/arduino225.php, но собрал сам и модифицировал, поэтому считаю, что "мое" уместно.


Прежде чем ляпать что-то на плате, я воссоздал схему при помощи сервиса easyeda.com, при помощи которого многие домашние самоделкины и ютуберы создают свои схемы и платы. Проект находится в открытом доступе по ссылке - https://oshwlab.com/donkovs/matrixboard#P1

Далее собрал ее на макетном брэдборде. Фото нет только потому, что не думал, что буду делать пост об этом. Ее вид не сильно отличался от того, что сделал автор схемы.

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

Красные дорожки – те, что должны быть на фронтальной части, а синие – на задней, на схеме есть всего один переход с фронтальной на заднюю, возможно можно было его избежать, но это мой первый опыт.


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

Лакированная проволока зачищалась не очень быстро, особенно на маленьких дорожках. К этому времени отец принес моток одножильных медных проводов в изоляции и далее я уже использовал их.


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

Для удобства, я разделил соединения по цветам. Белые (не считая четырех лакированных на фронтальной части) соответствуют фронтальной стороне на схеме, а коричневые – тыльной стороне.


Знаю, выглядит не очень красиво, можно было бы разместить провода по ровнее, а припой смыть, но как я уже говорил, выполнено временно, потому что в будущем хочу добавить еще одну матрицу из другого набора и использовать уже профильную схему на подобии МАКСимки или чего-нибудь аналогичного.


Схема готова и ее работа очень проста. Нога, отвечающая за защелкивание общая у обоих регистров, потому как пишем мы в них одновременно, эта идея мне понравилась, т.к. экономит 1 пин. С остальными все просто. Задаем сдвиговым регистрам необходимый набор данных, и они подают нужные сигналы на свои ноги. Напомню, что у конкретной модели регистров 8 выходных ног, что очень хорошо гармонирует с нашей матрицей размером 8 на 8, также имеются ноги для записи данных и самого сдвига, они и вынесены на площадку из 5-ти контактов. Вторая площадка из двух контактов – питание. Схема питается от 5-ти вольт, которые может выдавать сама Ардуинка и конечно же общий пин земли. К этим контактам подключаются сдвиговые регистры согласно схеме.


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

Программа (Software)


Как я говорил выше, затеивалось это, чтобы модуль можно было подключать к Arduino как отдельный модуль и  с меньшим количеством пинов, поэтому мозгом всей этой схемы является Arduino UNO, которая лежала в стартовом наборе. Использовал я редактор Visual Studio Code, поэтому в git репозитории лежит директория «.vscode» с моими настройками на разработку. Также, я решил, что будет безответственно не положить в репозиторий файлы скетча и схемы первоисточника, потому как автор не создавал репозиторий, и кто знает, как долго продержится первая статья на просторах Интернета. Отдельно отмечу, что я являюсь подписчиком AlexGyver, поэтому в его видео еще давно приметил удобную софтину для рисования битмапов. Ссылка на нее есть в readme md репозитория.


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


Когда увидел просьбу о публикации своей работы, решил, что имеющийся набор функций очень скуден, поэтому необходимо добавить еще что-нибудь. Поэтому практически все свободное время сегодняшнего дня я потратил на добавление функции бегущей строки. Заняло это у меня несколько часов, потому как мои знания в плюсах далеко не идеальны. Я столкнулся с тем, что еще в начальные студенческие годы побудило меня на изучение Java – указатели в C++. Пришлось освежать в памяти работу с ними, именно из-за них я перешел на Java еще на втором курсе, собственно, после этого я и перестал изучать плюсы.


Есть несколько нюансов. Чтобы не портить сами битмапы, я сделал их static, а для их отображения копировал их в рабочий фрейм функций, которые выполняют анимации.

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


Функция clr(). Очевидно, что она выполняет очистку всей матрицы, т.е. гасит все светодиоды. Написана она еще автором оригинала, на сколько я помню, я ее не исправлял.

Функция printBitmap(). Копия функции output() оригинального скетча, но с небольшими доработками. Я немного поменял вывод и добавил настройку задержки вывода, чтобы можно было регулировать ее в зависимости от нужд.

Функция printAnimation(). Принимает массив битмапов (Например покадрово нарисованную анимацию) и по очереди показывает битмапы.

Функция creeping_line(). Тоже принимает массив битмапов и показывает их с анимацией бегущей строки. Сама анимация основана на поочередном сдвиге столбцов битмапов из массива, поэтому для ее работы была написана следующая функция.

Функция bitmap_shift(). Реализует сдвиг в принятом битмапе на один столбец влево, заполняя при этом последний столбец либо пустой строкой, либо заданными данными.


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


Ссылка на репозиторий - https://github.com/donexdoc/Matrix2Shift со всеми исходниками и пояснениями.


Ну и демонстрация работы.

Либо в GIF, кому удобнее.

Что можно улучшить.


Да на самом деле тут поле не паханое:

1) Оптимизировать использование интовых переменных там, где не требуется больших значений.

2) Адаптировать функции для более гибкой настройки разрядности матрицы (сейчас все зашито под 8 на 8).

3) Возможно можно реализовать сдвиг более элегантным способом и добавить возможность сдвига более чем на 1 столбец.

4) Избавиться от бичевского delay() – как минимум, и использовать millis() для регулировки задержки.


И это только то, что приходит первое на ум, после замыленного взгляда.


Что по памяти?


Думаю, любого программиста на Arduino будет интересовать сколько скетч кушает памяти. Вот ответ от самой среды:

Скетч использует 1454 байт (4%) памяти устройства. Всего доступно 32256 байт.

Глобальные переменные используют 77 байт (3%) динамической памяти, оставляя 1971 байт для локальных переменных. Максимум: 2048 байт.


Много или нормально – решать продвинутым ардуинщикам, а для меня это в самый раз.


Если тем людям, которые просили о посте, было интересно (дайте знать в комментариях), то обещаю позже выложить еще один пост. Про интересный проект, который чуть более полезен, чем мигающие светодиоды. Там не будет пайки, но должно быть тоже интересно.


Спасибо за внимание, не судите строго, я не волшебник, а только учусь =).

Рукодельники

60.4K постов60.3K подписчиков

Правила сообщества

В сообществе запрещена торговля, обсуждение цен, ссылки на страницы с продажами, контакты автора в комментариях. Обязательна информация о материалах и инструментах в текстовом виде.

0. Соблюдайте основные правила Пикабу.


1. Будьте вежливы, старайтесь писать грамотно.


2. В публикациях используйте четкие и красивые фотографии.


3. Автор поста с тегом [моё] может оставить ссылку на свой профиль, группу или канал на других источниках, при условии, что ссылки (активные и не активные) не ведут на прямые продажи. Допускается не больше четырёх ссылок и только в конце поста (п. 8.5 основных правил).


Запрещены:

-ссылки рекламного характера/спам;

-ссылки, ведущие на магазины с указанием стоимости товара/услуги;

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

(нарушение основных правил сайта, п.8.1 и п. 8.2).

При переходе по ссылке запрещено наличие активных (кликабельных) ссылок, ведущих на вышеперечисленное в п.3, содержание таких ключевых слов как «товар», «услуга», «купить», «продам», «в наличии», «под заказ» и т.п.


3.1 Размещение контактов автора (самим автором или другими пользователями) в комментариях запрещено и подлежит удалению (п. 9.1 и 9.3 основных правил).


4. Обязательным для авторов является наличие технических характеристик изделия в публикациях (материалы, техники, авторские приемы, размеры, времязатраты и прочее) в текстовом виде.

Также помечайте свою работу тегом «Рукоделие с процессом» или «Рукоделие без процесса».


5. Пост-видео, пост-фото без текстового описания переносится в общую ленту. Даже если в видео показан подробный процесс изготовления, делайте краткое описание для тех, у кого нет возможности/желания смотреть видео.

Администрация оставляет за собой право решать, насколько описание соответствует п. 5.


6. Посты с нарушениями без предупреждения переносятся в общую ленту.

За неоднократные нарушения автор получает бан.

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

2
Автор поста оценил этот комментарий

Как же всё плохо в схемотехнике!!! До программы не смог дойти - глаза замироточили.
Итак:
1. У вас если на выходе 1 сдвигового регистра может быть любая комбинация (соответствует зажигаемым точкам), то на выходе 2 регистра будет ВСЕГДА только одна комбинация - последовательно зажигается один из рядов матрицы. Для такой простой работы применяются простые счетчики. И от Ардуино тогда нужен только один проводок управления - просто импульсы.

2. Чтобы не ловить рандомные состояния регистров при включении нужно управлять ENABLE регистров.

3. Если вы будет управлять включением (ENABLE), то можете удалить все резисторы на 220 Ом - скважность у вас 8 (у вас получается классическое ШИМ питание нагрузки). И то они будут не на всю яркость светить (она ограничена максимальным током выхода регистра)

4. У Ардуино достаточно своих выходов, один регистр можно выбросить и питать напрямую от Ардуины. А вместо второго регистра поставить счетчик.

5. На принципиальной схеме неприятные косяки:
- куча лишних перекрещиваний соединений, ненужных углов;

- на матрице вразброс сгруппированы row и col, обычно стараются расположить их по порядку и с одной стороны row, с другой col;
- входы (регистров) обычно располагают слева, упорядоченные выходы - справа;

- изображение матрицы нужно повернуть на 90 градусов.

Это всё нужно для читабельности схемы. Сейчас у вас 3 детали, но с такими привычками когда их будет 100 вы легко сможете читать схему.


P.S. Ну а чтобы вообще уйти от дополнительных компонентов могу посоветовать купить адресную RGB LED-ленту любой длины и управлять ею парой выводов Ардуины.

раскрыть ветку (1)
1
Автор поста оценил этот комментарий
Рад, что здесь есть знатоки своего дела. Только вы не просто не дошли до программы, но еще и начали, видимо, с картинок. В начале я обозначил, что пытаюсь сделать что-то более полезное из голого модуля, чем абузу на 16 точек. И пытаюсь я это сделать из подручных средств стартового набора. Не знаю как в вашем первом наборе электроники, но в моем не было счетчика, а всего два сдвиговика.

Также, в нем не было адресной ленты. Ведь суть поста не про то, чтобы создать поле светодиодов 8 на 8, а использовать ту самую матрицу из набора, которая лежит без дела у каждого начинающего прдуинщика, который купил такой же набор. (Из всего набора компонентов, что есть в этом проекте, я ничего не докупал, только позаимствовал плату из отцовского ящика).
Рандомное состояние регистров ловится не на включении, а именно на перезагрузке, и от состояния enable на старте не зависит, это было опробовано мною еще в первой модификации скетча. Суть в том, что при остановке скетча (но подаваемом питании) и следующем запуске, на какую-то долю секунды остаются некоторые пследние заженные светодиоды в матрице, что собственно не критично для этого проекта.
Выходов у ардуино хватает, но что, если параллельно с этой матрицей подключить еще элемнты или доп. модули? Например кнопки для упрощенной игры тетрис. Или микрофона, для визуализации эквалайзера. Как же для них выкроить место, особенно, если нет в наборе счетчика, и искать его - сомнительное дело в моем месте проживания.

Так же, еще в начале указывал, что не являюсь электронщиком, и взял эту схему из сети, на что указал ссылку, поэтому делал ровно по ней.
На схеме все расположено именно по выходам контактов самого модуля, поскольку делалось все для того, чтобы лучше понимать, как оно будет перекрещиваться, возможно для схемы это не очень правильно, но для меня так было нагляднее.
Не знаю где это обычно показано расположение входов/выходов регистров, но если вы посмотрите на сам даташит регистра, то заметите, что выходных ног 8, и одна из них расположена на противоположной стороне от других. К тому же, все управляющие пины расположены именно к пинам управления модулем, да и в разных схемах, которые я листал, регистры располагались по-разному, никакого "обычно" я не заметил.
Изображение матрицы дозволено крутить программно, начиная от параметров в функции shiftOut, заканчивая вашей фантазией с кодом, этим как-раз и выделяется особенность использования второго регистра. Вывел изображение именно так потому что так было удобнее ставить конструкцию на подставку для телефона.

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

Спасибо, что написали! :)

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо, что подтолкнули на написание поста)

0
Автор поста оценил этот комментарий

Мама, я в телевизоре!

Спасибо за пост, вполне достойно внимания

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо за отзыв)

показать ответы
1
Автор поста оценил этот комментарий
Поздравляю с постом) я пока не добрался до сдвиговых регистров, но уже на них посматривал какое-то время, так что мне определённо полезно)
раскрыть ветку (1)
0
Автор поста оценил этот комментарий
Спасибо) как разберусь с работой, сделаю еще один
0
Автор поста оценил этот комментарий

Тоже недавно пробовал использовать сдвиговые регистры для множества выходов, но не смог добиться стабильности при перезапуске контроллера, потому использовал расширитель портов на PCF8574T

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

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