Это устройство может стать приятным подарком или украшением полки любого человека.
Компоненты
Приступим, первое что нужно для разработки любого устройства это как минимум нужно подготовить все необходимые радиокомпоненты или хотя бы основные составляющие.
- Резисторы 150 ом 0.25 Ватт — 7 шт.
- Конденсаторы 50 вольт 1 микрофарад — 5 шт.
- Кварцевый резонатор 16 мгц — 1 шт.
- Разъём типа гребёнка ( потребуется 18 контактов ) — 1 шт.
- Сдвиговый регистр 74ch595 корпус DIP — 1 шт.
- Панель под микросхему 74ch595 корпус DIP (16 ножек) — 1 шт.
- Светодиоды 5мм Three вольта — 35 шт.
- Микроконтроллер ATmega328p корпус DIP — 1 шт.
- Панель под микросхему ATmega328p корпус DIP (28 ножек) — 1 шт.
- Монтажная плата 5×7 — 1 шт.
Рекомендую при необходимости купить флюс, припой и паяльник.
Я намеренно не указываю марку проводов которая вам подойдет, так как совсем не владею информацией о их параметрах могу посоветовать МГТФ вполне возможно что подойдут, если вы знаете какие провода точно оптимальны, оставьте информацию в комментариях или мне в личные сообщения jsusdev
Я не буду вам советовать какие-либо конкретные интернет магазины потому что это было давно и не правда.
Сдвиговый регистр 74ch595
Наверно для многих новичков, станет не по себе от понимания принципов работы микросхемы 74ch595 вне этой статьи. Сейчас я попробую максимально доступно объяснить как она работает и чем будет полезна в конкретном случае с моей LED-матрицей.
Проще говоря микросхема предназначена для увеличения количества цифровых пинов.
Распиновка. Внимание рисунок имеет незначительные неточности в маркировке контактов, это сделано для более простого усвоения и понимания работы.
Самые загадочные контакты, управления которые вызывают интерес:
- output pin * — контакты вывода
- DS — (Serial Data Input) контакт который определяет состояние напряжения на контактах вывода
- SH — (Shift Register Clock Input) контакт который записывает состояние которое определенно в DS
- ST — (Storage Register Clock Input) контакт который открывает микросхему для записи и закрывает, устанавливая на контакты вывода нужные состояния определенные DS
Уверен визуальный пример поможет вам осознать происходящие лучше.
Если нет то я оставил и интерактивную версию: 74ch595.swf все кнопочки работают можно понажимать.
Если вы осознали как это работает, то единственное что мне осталось так это добавить пример кода для работы с микросхемой.
Этот код только для окончательного понимания как это работает программно. Код который можно загрузить будет в спойлере ниже.
int ST = 7; int SH = 6; int DS = 5; digitalWrite(ST, 1); // начало записи в байт for (int i = 0; i < 8; i++) { digitalWrite(SH, 1); // начало записи бита digitalWrite(DS, 1); // < --- последний аргумент это бит который будет записан digitalWrite(SH, 0); // конец записи бита } digitalWrite(ST, 0); // конец записи в байт
int ST = 7; int SH = 6; int DS = 5; void setup() { pinMode(7, 1); pinMode(6, 1); pinMode(5, 1); } void loop() { digitalWrite(ST, 1); // начало записи в байт for (int i = 0; i < 8; i++) { digitalWrite(SH, 1); // начало записи бита digitalWrite(DS, 1); // < --- последний аргумент это бит который будет записан digitalWrite(SH, 0); // конец записи бита } digitalWrite(ST, 0); // конец записи в байт }
Теперь когда вы овладели работой с микросхемой. Можно приступить к следующему пункту.
Подготовка к разработке матрицы
Для того чтобы светодиоды «встали» на плату необходимо обточить мелкую окантовку. Внимание нужно именно обточить, потому что есть еще не мало способов от нее избавиться, так как светодиоды очень хрупкие на самом деле, желательно обрабатывать их аккуратно, процесс выпаивания в случае чего мне ни разу, не давался легко.
Хотелось бы обратить особое внимание на конденсаторы, я не могу объяснить их необходимость специальным языком, но без них светодиоды не затухают до конца и от этого устройство выглядит неоптимизированным, конденсаторы стабилизируют ток между контроллером и светодиодом.
В финальном исполнение установить конденсаторы получилось только так, хотя раскрою секрет подобное устройство было не одно, на одном из них конденсаторы крепились с обратной стороны на одну ножку в том месте где сейчас проходит провод питания к 74ch595.
Не стоит беспокоиться о количестве проводов на фото, далее покажу как все устроено.
Совсем забыл и вы наверно упустили из внимания что на устройстве в визуально расположено всего 6 резисторов но на самом деле их 7 один из них находится прямо под 74ch595.
Стоит добавить что кварцевый генератор (16 мгц) можно заменить на 24 мгц, это существенно ускорит работу, но такие изменения применимы только к готовому устройству, так как ATmega328p просто не прошивается на кварцевом генераторе 24 мгц.
Разработка матрицы
Принципиальная схема устройства.
Внимание светодиоды расположены «минусом» к ATmega328p и в тоже время «плюсом» к 74ch595. Расположение компонентов на плате.
Обратная часть (вариант без конденсаторов)
3D-модель, которую можно повертеть в редакторе Google SketchUp. Саму модель можно скачать тут: 3D_Schema.skp
Когда мы запаяли все компоненты, можно припаивать провода.
Стартуем:
Соединяем контакты rx, tx, reset и светодиоды. (светодиоды соединены отрезанными от них ножками):
Соединяем компоненты питание и кварцевый генератор:
Соединяем светодиоды с 74ch595:
Соединяем светодиоды с ATmega328p и ATmega328p и 74ch595:
Соединяем конденсаторы:
Поздравляю физическая часть закончена:
Наверняка устройство сразу не оживет без прошивки но можно попробовать стандартный blink Arduino. (Да в некоторых случаях действительно может заработать).
У меня Blink заработал. если у вас хоть что-то на первом ряду будет мигать значит все ок если нет то читаем дальше.
Разработка программы
Чтобы микроконтроллер управлял своими контактами их надо «инициализировать»
Да. я мог сделать иначе например: использовать массив и цикл чтобы сократить количество кода в функции, вообще множество программных решений которые я принял в процессе реализации губительны с какой-то позиции, например для программируемой памяти (Flash) но позитивны для динамической. (RAM) Мне удалось снизить использование динамической памяти с 69% до 23%
Хочу отдельно заметить что отсутствие динамической памяти очень критично для устройства оно просто может зависнуть в любой момент из за нехватки памяти, в данном случае динамической памяти всего 2 Кб, а программируемой 32 Кб.
Поэтому примите и смиритесь или сделайте лучше!
// функция инициализации void init() { pinMode(5, 1); pinMode(6, 1); pinMode(7, 1); pinMode(9, 1); pinMode(10, 1); pinMode(11, 1); pinMode(12, 1); pinMode(13, 1); digitalWrite(5,0); digitalWrite(6,0); digitalWrite(7,0); digitalWrite(9,0); digitalWrite(10,0); digitalWrite(11,0); digitalWrite(12,0); digitalWrite(13,0); };
Для управления матрицей я разработал такую функцию она является ключевой по сути.
void path(char bits[5]) { for (int l = 0;l < 5;l++) { digitalWrite(9, 1); digitalWrite(10, 1); digitalWrite(11, 1); // эта часть просто отключает пины digitalWrite(12, 1); digitalWrite(13, 1); if (l == 1) digitalWrite(13, 0); if (l == 2) digitalWrite(12, 0); if (l == 3) digitalWrite(11, 0); // эта часть включает пины в зависимости от условия if (l == 4) digitalWrite(10, 0); if (l == 0) digitalWrite(9, 0); // эта часть нужна для управления регистром, см. пункт выше digitalWrite(7, 1); for (int i = 0; i < 8;i++) { digitalWrite(6, 1); digitalWrite(5, (bits[l] >> i) & 1); /* (bits[l] >> i) * такой вот способ преобразовывать * из 10 в 2, спасибо * чуваку который мне * помог с этим условием */ digitalWrite(6, 0); } digitalWrite(7, 0); delay(2); // каким то образом эта строчка помогает избавиться мерцания } };
Каждый элемент массива это одна колонка светодиодов.
char Matrx_symbol[5] = { 127, // 1 0, // 2 0, // 3 0, // 4 0 // 5 }; path(Matrx_symbol);
Нумерование колонок идет справа налево то есть зеркально массиву.
Что это за магические цифры в массиве?
Проще говоря колонка светодиодов это байт вмещающий число в десятичной системе счисления от Zero до 127, этим числом мы определяем каким светодиодам нужно зажечься.
Конечно мы не будем собирать свои символы путем грубого или осознанного перебора бит в байте. Я разработал страницу на которой можно сформировать любой символ Symbol creater.
Все предельно просто и легко, мы просто выбираем курсором нужны светодиоды и получаем массив который можно использовать в качестве символа.
Функция в которой определены символы, изначально я планировал что функцию можно будет совершенствовать расширяя количество символов, сейчас их 87 но я предполагал что их может быть до 255 но увы наверно в этом релизе нет, так как интерпретатор Arduino не определяет символы код которых выше чем 127.
Буквально только что я об этом узнал в 5:31 по МСК
Функция которая конвертирует строку в набор перебираемых символов. Принимает два параметра это саму строку «Hellow world!» и вторым параметром время между переключением символов в мс.
void message(String textual content, int Delay) { int len = textual content.size(); for (int i = 0; i < len; i++) { for (int Delay_ = 0; Delay_ < Delay/15; Delay_++){ if (text[i] == 32) { char Symbol[5] = {0,0,0,0,0}; path(Symbol); } // if (text[i] == 43) { char Symbol[5] = {8,8,62,8,8}; path(Symbol); } // + if (text[i] == 45) { char Symbol[5] = {8,8,8,8,8}; path(Symbol); } // - if (text[i] == 61) { char Symbol[5] = {20,20,20,20,20}; path(Symbol); } // = if (text[i] == 95) { char Symbol[5] = {1,1,1,1,1}; path(Symbol); } // _ if (text[i] == 41) { char Symbol[5] = {62,65,0,0,0}; path(Symbol); } // ) if (text[i] == 40) { char Symbol[5] = {0,0,0,65,62}; path(Symbol); } // ( if (text[i] == 123) { char Symbol[5] = {0,65,65,54,8}; path(Symbol); } // { if (text[i] == 125) { char Symbol[5] = {8,54,65,65,0}; path(Symbol); } // } if (text[i] == 62) { char Symbol[5] = {8,20,34,65,0}; path(Symbol); } // > if (textual content[i] == 60) { char Symbol[5] = {0,65,34,20,8}; path(Symbol); } // < if (textual content[i] == 46) { char Symbol[5] = {0,0,1,0,0}; path(Symbol); } // . if (textual content[i] == 44) { char Symbol[5] = {0,0,3,2,0}; path(Symbol); } // , if (textual content[i] == 63) { char Symbol[5] = {48,72,69,64,48}; path(Symbol); } // ? if (textual content[i] == 33) { char Symbol[5] = {0,0,125,0,0}; path(Symbol); } // ! if (textual content[i] == 64) { char Symbol[5] = {58,69,93,65,62}; path(Symbol); } // @ if (textual content[i] == 35) { char Symbol[5] = {20,127,20,127,20}; path(Symbol); } // # if (textual content[i] == 36) { char Symbol[5] = {38,73,127,73,50}; path(Symbol); } // $ if (textual content[i] == 37) { char Symbol[5] = {19,11,4,50,49}; path(Symbol); } // % if (textual content[i] == 94) { char Symbol[5] = {0,32,64,32,0}; path(Symbol); } // ^ if (textual content[i] == 58) { char Symbol[5] = {0,0,0,34,0}; path(Symbol); } // : if (textual content[i] == 42) { char Symbol[5] = {8,20,42,20,8}; path(Symbol); } // * if (textual content[i] == 38) { char Symbol[5] = {2,53,73,73,54}; path(Symbol); } // & if (textual content[i] == 34) { char Symbol[5] = {0,112,0,112,0}; path(Symbol); } // " if (textual content[i] == 59) { char Symbol[5] = {0,0,0,38,2}; path(Symbol); } // ; if (textual content[i] == 48) { char Symbol[5] = {62,65,65,65,62}; path(Symbol); } // 0 if (textual content[i] == 49) { char Symbol[5] = {0,1,127,33,16}; path(Symbol); } // 1 if (textual content[i] == 50) { char Symbol[5] = {49,73,69,67,49}; path(Symbol); } // 2 if (textual content[i] == 51) { char Symbol[5] = {54,73,73,65,34}; path(Symbol); } // 3 if (textual content[i] == 52) { char Symbol[5] = {5,127,37,20,12}; path(Symbol); } // 4 if (textual content[i] == 53) { char Symbol[5] = {6,73,73,73,114}; path(Symbol); } // 5 if (textual content[i] == 54) { char Symbol[5] = {38,73,73,73,62}; path(Symbol); } // 6 if (textual content[i] == 55) { char Symbol[5] = {96,80,79,64,64}; path(Symbol); } // 7 if (textual content[i] == 56) { char Symbol[5] = {54,73,73,73,54}; path(Symbol); } // 8 if (textual content[i] == 57) { char Symbol[5] = {62,73,73,73,50}; path(Symbol); } // 9 if (textual content[i] == 97) { char Symbol[5] = {1,62,37,37,18}; path(Symbol); } // a if (textual content[i] == 65) { char Symbol[5] = {3,28,36,28,3}; path(Symbol); } // A if (textual content[i] == 98) { char Symbol[5] = {6,9,9,9,126}; path(Symbol); } // b if (textual content[i] == 66) { char Symbol[5] = {6,57,73,73,127}; path(Symbol); } // B if (textual content[i] == 99) { char Symbol[5] = {18,33,33,33,30}; path(Symbol); } // c if (textual content[i] == 67) { char Symbol[5] = {34,65,65,65,62}; path(Symbol); } // C if (textual content[i] == 100) { char Symbol[5] = {126,9,9,9,6}; path(Symbol); } // d if (textual content[i] == 68) { char Symbol[5] = {62,65,65,65,127}; path(Symbol); } // D if (textual content[i] == 101) { char Symbol[5] = {26,37,37,37,30}; path(Symbol); } // e if (textual content[i] == 69) { char Symbol[5] = {65,65,73,73,127}; path(Symbol); } // E if (textual content[i] == 102) { char Symbol[5] = {0,32,36,31,4}; path(Symbol); } // f if (textual content[i] == 70) { char Symbol[5] = {64,64,72,72,127}; path(Symbol); } // F if (textual content[i] == 103) { char Symbol[5] = {62,73,73,74,48}; path(Symbol); } // g if (textual content[i] == 71) { char Symbol[5] = {38,73,73,65,62}; path(Symbol); } // G if (textual content[i] == 104) { char Symbol[5] = {0,7,8,8,63}; path(Symbol); } // h if (textual content[i] == 72) { char Symbol[5] = {127,8,8,8,127}; path(Symbol); } // H if (textual content[i] == 105) { char Symbol[5] = {0,0,47,0,0}; path(Symbol); } // i if (textual content[i] == 73) { char Symbol[5] = {0,65,127,65,0}; path(Symbol); } // I if (textual content[i] == 106) { char Symbol[5] = {0,94,1,1,2}; path(Symbol); } // j if (textual content[i] == 74) { char Symbol[5] = {126,1,1,1,6}; path(Symbol); } // J if (textual content[i] == 107) { char Symbol[5] = {0,16,9,6,63}; path(Symbol); } // okay if (textual content[i] == 75) { char Symbol[5] = {64,33,18,12,127}; path(Symbol); } // Ok if (textual content[i] == 108) { char Symbol[5] = {0,1,63,0,0}; path(Symbol); } // l //if (textual content[i] == 76) { char Symbol[5] = {1,1,1,1,127}; path(Symbol); } // L if (textual content[i] == 109) { char Symbol[5] = {15,16,24,16,15}; path(Symbol); } // m if (textual content[i] == 77) { char Symbol[5] = {63,64,56,64,63}; path(Symbol); } // M if (textual content[i] == 110) { char Symbol[5] = {31,32,32,32,63}; path(Symbol); } // n if (textual content[i] == 78) { char Symbol[5] = {127,4,8,16,127}; path(Symbol); } // N if (textual content[i] == 111) { char Symbol[5] = {14,17,17,17,14}; path(Symbol); } // o if (textual content[i] == 79) { char Symbol[5] = {62,65,65,65,62}; path(Symbol); } // O if (textual content[i] == 112) { char Symbol[5] = {0,24,36,36,63}; path(Symbol); } // p if (textual content[i] == 80) { char Symbol[5] = {56,68,68,68,63}; path(Symbol); } // P if (textual content[i] == 113) { char Symbol[5] = {31,36,36,36,24}; path(Symbol); } // q if (textual content[i] == 81) { char Symbol[5] = {61,66,65,65,62}; path(Symbol); } // Q if (textual content[i] == 114) { char Symbol[5] = {0,48,16,32,63}; path(Symbol); } // r if (textual content[i] == 82) { char Symbol[5] = {56,69,70,68,63}; path(Symbol); } // R if (textual content[i] == 115) { char Symbol[5] = {0,18,37,41,18}; path(Symbol); } // s //if (textual content[i] == 83) { char Symbol[5] = {38,73,73,73,50}; path(Symbol); } // S if (textual content[i] == 116) { char Symbol[5] = {0,2,17,62,16}; path(Symbol); } // t if (textual content[i] == 84) { char Symbol[5] = {64,64,127,64,64}; path(Symbol); }// T if (textual content[i] == 117) { char Symbol[5] = {29,2,1,1,30}; path(Symbol); } // u if (textual content[i] == 85) { char Symbol[5] = {126,1,1,1,126}; path(Symbol); } // U if (textual content[i] == 118) { char Symbol[5] = {60,2,1,2,60}; path(Symbol); } // v if (textual content[i] == 86) { char Symbol[5] = {124,2,1,2,124}; path(Symbol); } // V if (textual content[i] == 119) { char Symbol[5] = {30,1,6,1,30}; path(Symbol); } // w if (textual content[i] == 87) { char Symbol[5] = {126,1,6,1,126}; path(Symbol); } // W if (textual content[i] == 120) { char Symbol[5] = {17,10,4,10,17}; path(Symbol); } // x if (textual content[i] == 88) { char Symbol[5] = {99,20,8,20,99}; path(Symbol); } // X if (textual content[i] == 121) { char Symbol[5] = {56,4,6,57,0}; path(Symbol); } // y if (textual content[i] == 89) { char Symbol[5] = {112,8,7,8,112}; path(Symbol); } // Y if (textual content[i] == 122) { char Symbol[5] = {17,25,21,19,17}; path(Symbol); } // z if (textual content[i] == 90) { char Symbol[5] = {97,81,73,69,67}; path(Symbol); } // Z if (textual content[i] == 76) { char Symbol[5] = {24,60,30,60,24}; path(Symbol); } // L if (textual content[i] == 83) { char Symbol[5] = {6,113,1,113,6}; path(Symbol); } // S } }
Теперь когда мы «разобрали» принцип работы функций данной программы в контроллере, нужно его оформить.
class Jsus { public: void init() { pinMode(5, 1); pinMode(6, 1); pinMode(7, 1); pinMode(9, 1); pinMode(10, 1); pinMode(11, 1); pinMode(12, 1); pinMode(13, 1); digitalWrite(5,0); digitalWrite(6,0); digitalWrite(7,0); digitalWrite(9,0); digitalWrite(10,0); digitalWrite(11,0); digitalWrite(12,0); digitalWrite(13,0); }; void path(char bits[5]) { for (int l = 0;l < 5;l++) { digitalWrite(9, 1); digitalWrite(10, 1); digitalWrite(11, 1); digitalWrite(12, 1); digitalWrite(13, 1); if (l == 1) digitalWrite(13, 0); if (l == 2) digitalWrite(12, 0); if (l == 3) digitalWrite(11, 0); if (l == 4) digitalWrite(10, 0); if (l == 0) digitalWrite(9, 0); digitalWrite(7, 1); for (int i = 0; i < 8;i++) { digitalWrite(6, 1); digitalWrite(5, (bits[l] >> i) & 1); digitalWrite(6, 0); } digitalWrite(7, 0); delay(2); } }; void message(String textual content, int Delay) { int len = textual content.size(); for (int i = 0; i < len; i++) { for (int Delay_ = 0; Delay_ < Delay/15; Delay_++){ if (text[i] == 32) { char Symbol[5] = {0,0,0,0,0}; path(Symbol); } // if (text[i] == 43) { char Symbol[5] = {8,8,62,8,8}; path(Symbol); } // + if (text[i] == 45) { char Symbol[5] = {8,8,8,8,8}; path(Symbol); } // - if (text[i] == 61) { char Symbol[5] = {20,20,20,20,20}; path(Symbol); } // = if (text[i] == 95) { char Symbol[5] = {1,1,1,1,1}; path(Symbol); } // _ if (text[i] == 41) { char Symbol[5] = {62,65,0,0,0}; path(Symbol); } // ) if (text[i] == 40) { char Symbol[5] = {0,0,0,65,62}; path(Symbol); } // ( if (text[i] == 123) { char Symbol[5] = {0,65,65,54,8}; path(Symbol); } // { if (text[i] == 125) { char Symbol[5] = {8,54,65,65,0}; path(Symbol); } // } if (text[i] == 62) { char Symbol[5] = {8,20,34,65,0}; path(Symbol); } // > if (textual content[i] == 60) { char Symbol[5] = {0,65,34,20,8}; path(Symbol); } // < if (textual content[i] == 46) { char Symbol[5] = {0,0,1,0,0}; path(Symbol); } // . if (textual content[i] == 44) { char Symbol[5] = {0,0,3,2,0}; path(Symbol); } // , if (textual content[i] == 63) { char Symbol[5] = {48,72,69,64,48}; path(Symbol); } // ? if (textual content[i] == 33) { char Symbol[5] = {0,0,125,0,0}; path(Symbol); } // ! if (textual content[i] == 64) { char Symbol[5] = {58,69,93,65,62}; path(Symbol); } // @ if (textual content[i] == 35) { char Symbol[5] = {20,127,20,127,20}; path(Symbol); } // # if (textual content[i] == 36) { char Symbol[5] = {38,73,127,73,50}; path(Symbol); } // $ if (textual content[i] == 37) { char Symbol[5] = {19,11,4,50,49}; path(Symbol); } // % if (textual content[i] == 94) { char Symbol[5] = {0,32,64,32,0}; path(Symbol); } // ^ if (textual content[i] == 58) { char Symbol[5] = {0,0,0,34,0}; path(Symbol); } // : if (textual content[i] == 42) { char Symbol[5] = {8,20,42,20,8}; path(Symbol); } // * if (textual content[i] == 38) { char Symbol[5] = {2,53,73,73,54}; path(Symbol); } // & if (textual content[i] == 34) { char Symbol[5] = {0,112,0,112,0}; path(Symbol); } // " if (textual content[i] == 59) { char Symbol[5] = {0,0,0,38,2}; path(Symbol); } // ; if (textual content[i] == 48) { char Symbol[5] = {62,65,65,65,62}; path(Symbol); } // 0 if (textual content[i] == 49) { char Symbol[5] = {0,1,127,33,16}; path(Symbol); } // 1 if (textual content[i] == 50) { char Symbol[5] = {49,73,69,67,49}; path(Symbol); } // 2 if (textual content[i] == 51) { char Symbol[5] = {54,73,73,65,34}; path(Symbol); } // 3 if (textual content[i] == 52) { char Symbol[5] = {5,127,37,20,12}; path(Symbol); } // 4 if (textual content[i] == 53) { char Symbol[5] = {6,73,73,73,114}; path(Symbol); } // 5 if (textual content[i] == 54) { char Symbol[5] = {38,73,73,73,62}; path(Symbol); } // 6 if (textual content[i] == 55) { char Symbol[5] = {96,80,79,64,64}; path(Symbol); } // 7 if (textual content[i] == 56) { char Symbol[5] = {54,73,73,73,54}; path(Symbol); } // 8 if (textual content[i] == 57) { char Symbol[5] = {62,73,73,73,50}; path(Symbol); } // 9 if (textual content[i] == 97) { char Symbol[5] = {1,62,37,37,18}; path(Symbol); } // a if (textual content[i] == 65) { char Symbol[5] = {3,28,36,28,3}; path(Symbol); } // A if (textual content[i] == 98) { char Symbol[5] = {6,9,9,9,126}; path(Symbol); } // b if (textual content[i] == 66) { char Symbol[5] = {6,57,73,73,127}; path(Symbol); } // B if (textual content[i] == 99) { char Symbol[5] = {18,33,33,33,30}; path(Symbol); } // c if (textual content[i] == 67) { char Symbol[5] = {34,65,65,65,62}; path(Symbol); } // C if (textual content[i] == 100) { char Symbol[5] = {126,9,9,9,6}; path(Symbol); } // d if (textual content[i] == 68) { char Symbol[5] = {62,65,65,65,127}; path(Symbol); } // D if (textual content[i] == 101) { char Symbol[5] = {26,37,37,37,30}; path(Symbol); } // e if (textual content[i] == 69) { char Symbol[5] = {65,65,73,73,127}; path(Symbol); } // E if (textual content[i] == 102) { char Symbol[5] = {0,32,36,31,4}; path(Symbol); } // f if (textual content[i] == 70) { char Symbol[5] = {64,64,72,72,127}; path(Symbol); } // F if (textual content[i] == 103) { char Symbol[5] = {62,73,73,74,48}; path(Symbol); } // g if (textual content[i] == 71) { char Symbol[5] = {38,73,73,65,62}; path(Symbol); } // G if (textual content[i] == 104) { char Symbol[5] = {0,7,8,8,63}; path(Symbol); } // h if (textual content[i] == 72) { char Symbol[5] = {127,8,8,8,127}; path(Symbol); } // H if (textual content[i] == 105) { char Symbol[5] = {0,0,47,0,0}; path(Symbol); } // i if (textual content[i] == 73) { char Symbol[5] = {0,65,127,65,0}; path(Symbol); } // I if (textual content[i] == 106) { char Symbol[5] = {0,94,1,1,2}; path(Symbol); } // j if (textual content[i] == 74) { char Symbol[5] = {126,1,1,1,6}; path(Symbol); } // J if (textual content[i] == 107) { char Symbol[5] = {0,16,9,6,63}; path(Symbol); } // okay if (textual content[i] == 75) { char Symbol[5] = {64,33,18,12,127}; path(Symbol); } // Ok if (textual content[i] == 108) { char Symbol[5] = {0,1,63,0,0}; path(Symbol); } // l //if (textual content[i] == 76) { char Symbol[5] = {1,1,1,1,127}; path(Symbol); } // L if (textual content[i] == 109) { char Symbol[5] = {15,16,24,16,15}; path(Symbol); } // m if (textual content[i] == 77) { char Symbol[5] = {63,64,56,64,63}; path(Symbol); } // M if (textual content[i] == 110) { char Symbol[5] = {31,32,32,32,63}; path(Symbol); } // n if (textual content[i] == 78) { char Symbol[5] = {127,4,8,16,127}; path(Symbol); } // N if (textual content[i] == 111) { char Symbol[5] = {14,17,17,17,14}; path(Symbol); } // o if (textual content[i] == 79) { char Symbol[5] = {62,65,65,65,62}; path(Symbol); } // O if (textual content[i] == 112) { char Symbol[5] = {0,24,36,36,63}; path(Symbol); } // p if (textual content[i] == 80) { char Symbol[5] = {56,68,68,68,63}; path(Symbol); } // P if (textual content[i] == 113) { char Symbol[5] = {31,36,36,36,24}; path(Symbol); } // q if (textual content[i] == 81) { char Symbol[5] = {61,66,65,65,62}; path(Symbol); } // Q if (textual content[i] == 114) { char Symbol[5] = {0,48,16,32,63}; path(Symbol); } // r if (textual content[i] == 82) { char Symbol[5] = {56,69,70,68,63}; path(Symbol); } // R if (textual content[i] == 115) { char Symbol[5] = {0,18,37,41,18}; path(Symbol); } // s //if (textual content[i] == 83) { char Symbol[5] = {38,73,73,73,50}; path(Symbol); } // S if (textual content[i] == 116) { char Symbol[5] = {0,2,17,62,16}; path(Symbol); } // t if (textual content[i] == 84) { char Symbol[5] = {64,64,127,64,64}; path(Symbol); }// T if (textual content[i] == 117) { char Symbol[5] = {29,2,1,1,30}; path(Symbol); } // u if (textual content[i] == 85) { char Symbol[5] = {126,1,1,1,126}; path(Symbol); } // U if (textual content[i] == 118) { char Symbol[5] = {60,2,1,2,60}; path(Symbol); } // v if (textual content[i] == 86) { char Symbol[5] = {124,2,1,2,124}; path(Symbol); } // V if (textual content[i] == 119) { char Symbol[5] = {30,1,6,1,30}; path(Symbol); } // w if (textual content[i] == 87) { char Symbol[5] = {126,1,6,1,126}; path(Symbol); } // W if (textual content[i] == 120) { char Symbol[5] = {17,10,4,10,17}; path(Symbol); } // x if (textual content[i] == 88) { char Symbol[5] = {99,20,8,20,99}; path(Symbol); } // X if (textual content[i] == 121) { char Symbol[5] = {56,4,6,57,0}; path(Symbol); } // y if (textual content[i] == 89) { char Symbol[5] = {112,8,7,8,112}; path(Symbol); } // Y if (textual content[i] == 122) { char Symbol[5] = {17,25,21,19,17}; path(Symbol); } // z if (textual content[i] == 90) { char Symbol[5] = {97,81,73,69,67}; path(Symbol); } // Z if (textual content[i] == 76) { char Symbol[5] = {24,60,30,60,24}; path(Symbol); } // L if (textual content[i] == 83) { char Symbol[5] = {6,113,1,113,6}; path(Symbol); } // S } } }; }; Jsus matrix;
Код для старта.
void setup() { matrix.init(); } void loop() { matrix.message("Fuck RKN!", 400); }
Тут можно найти готовый к загрузке в Arduino cкетч.
Результаты разработки
2018. Текущая версия устройства:
2017. Текущая версия устройства (не оптимизированная):
2016. Первая тестовая версия устройства. Еще даже без микросхем на плате:
Все необходимые ссылки можно найти в репозитории на Github проекта: Arduino-matrix-module.
Если статья не ответила на какие то вопросы реализации, пишите их в комментариях.
Всё, вроде ничего не забыл. Поки чмоки лавки лавки.
Источник