Форум РадиоКот https://radiokot.ru/forum/ |
|
Ёлка новогодняя из светодиодиков. (чарлиплексинг) https://radiokot.ru/forum/viewtopic.php?f=25&t=174026 |
Страница 1 из 2 |
Автор: | BlackKilkennyCat [ Пн ноя 23, 2020 18:44:44 ] |
Заголовок сообщения: | Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Для обсуждения статьи https://radiokot.ru/artfiles/6598/ Добавлено after 5 hours 39 minutes 10 seconds: По просьбам трудящихся, пример очень простой программы для сей ёлки. В стиле для начинающих постараюсь, поэтому профи будет скучновато, но я всё же прошу по возможности прочитать с целью критики-исправлений-дополнений, если есть время, за что заранее благодарю. Данная программа очень проста - предполагает свечение лишь одного светодиода в единицу нормального времени. Под нормальным временем подразумевается время не менее 1/10 секунды. Никаких комбинаций с одновременным свечением нескольких светодиодов напрямую или же через быстрое попеременное вкл-выкл (то есть, динамическая индикация) здесь нету. Итак, предположим, что у нас некий абстрактный микроконтроллер, но на котором почему-то написано PIC18, что мистическим образом накладет лапу на синтаксис и радует тех, кто решил использовать именно такой мк. И есть спаянная ёлка. Будем делать эффекты. Первое, что обычно всегда приходит мне в голову, так это написать кучу состояний, неких "кадров", которые затем прокрутить. Разумеется, даже примерный подсчёт показывает, что это громадный и неэффективный объём данных, не зря же в свое время появилась gif-анимация и различные виды сжатия видео, где в каждом следующем кадре учитываются лишь изменения относительно предыдущего кадра, поэтому часовой видеофильм, показывающий неподвижную картину "Рождение Домомучительницы" будет по размеру несильно отличаться от подобного же, но идущего всего минуту: нет изменений - нет данных. Вторым приходит в голову - математика. Да, кучу светоэффектов можно описать математикой. Это очень компактно, удобно, но... не знаю, как кто, а я с трудом помню, как вычисляется дискриминант квадратного уравнения, и есть вполне оправданные сомнения, что даже если верно его помню, то не помню что с ним делать дальше. Поэтому всё максимально упростим, и поверьте, ваши родные и друзья придут в восторг от перемигивающихся зеленых огоньков и никто не догадается, как ужасно всё внутри. Мы просто создадим массивы, где каждый элемент будет соответствовать состоянию светодиода, и будем считать это "кадром" нашей анимации. В моей ёлочке 56 светодиодов, а значит будет 56 "кадров", и 10 "стволов", т.е. выводов МК. Глядя на плату уже сделанной ёлки, вижу, что под это дело был отдан весь порт C (C0..C7) и две лапы порта А (А4, А5) Ну, так и напишем: Код: #include <xc.h> #include "main.h" unsigned char leds_trisc[56] ={}; unsigned char leds_trisa4[56] ={}; unsigned char leds_trisa5[56] ={}; unsigned char leds_latc[56] ={}; unsigned char leds_lata4[56] ={}; unsigned char leds_lata5[56] ={}; Думаю, ни у кого не возникнет вопрос: - А что тут делает TRIS? А вот у меня возник. Нам же нужно зажигать светодиоды, и всё. То есть, нужны лишь выходы. Инициализируем TRIS в режим выхода, и забываем о нём, зачем его-то в массив? И я так и сделал. Все порты на выход, всем состояние "0". Прекрасно, ничего не светится. И пытаемся зажечь наш первый светодиод, подавая "1" на, например, "ствол" номер 0: ![]() Как видите, в итоге получается, что у светодиодов D10 и D1 на анодах логическая "1", то есть +V, на катодах "0", то есть -V. Ничто не мешает светиться обоим сразу, что они радостно и делают. (небольшое отвлечение для совсем юных радиолюбителей: анод и катод на символе диода легко запоминается по формуле "Аткуда Куда", сам же символ стрелкообразной формой хорошо показывает "аткуда" и "куда") Что же делать? Не нужон нам второй светодиод, он паразитный. Чтобы паразитный диод погасить, на его катоде не должен быть "0". -Идея!, - воскликнет кто-нибудь. - Давайте туда подадим "1", ведь следующий диод включен наоборот, он не будет светиться. Давайте. И обнаруживаем, что совершенно верно, ненужный светодиод больше не светится. Зато теперь светится другой, в другом ярусе... Выходит, что в одном кадре должны быть только один "0" и одна "1". Что же тогда будет на других выходах? А ничего. И это состояние называется "Z-состояние", или "Высокоимпедансное"(высокоомное), на микроконтроллере его можно получить, переведя порт в режим входа с отключением подтягивающих резисторов (если они есть). Отсюда и необходимость в массиве TRIS: каждый наш "кадр" мы будем чётко указывать пару выводов микроконтроллера, настроенных на выход. Дальше самое скучное: смотрим на ёлку, определяем, какие лапы мк для какого светодиода определить на выход, и записываем в массив. У меня получилось так: Код: unsigned char leds_trisc[56] ={ 0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xfe, //1 ярус снизу 0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xfe, //2 ярус 0xf7,0xf6,0xfa,0xdb,0xd7,0xb7,0xaf,0xef, //3 ярус 0xf7,0xf6,0xfa,0xdb,0xd7,0xb7,0xaf,0xef, //4 ярус 0xfb,0xbb,0xbf,0xf7,0x77,0x7f, //5 ярус 0xfb,0xbb,0xbf,0xf7,0x77,0x7f, //6ярус 0xfe,0xdf,0x5f,0x7e, //7 ярус 0xfe,0xdf,0x5f,0x7e}; //8 ярус unsigned char leds_trisa4[56] ={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff}; unsigned char leds_trisa5[56] ={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00, 0x00,0xff,0xff,0xff,0xff,0x00, 0x00,0xff,0xff,0xff,0xff,0x00, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff}; Можно заметить, что ярусность дублируется - строки одинаковые. Жаль, что порт 8-битный... тогда хватило бы одного массива. На самом деле, leds_trisa4 и leds_trisa5 можно объединить в один, но для простоты дальнейшего доступа к выводу порта я оставлю так, да и как пример того, что может произойти, если выводы берутся из разных портов. Ну вот, 50% работы сделано - обеспечили возможность свечения только выбранного светодиода. Теперь это и сделаем: Код: unsigned char leds_latc[56] ={ 0x01,0x04,0x04,0x10,0x10,0x40,0x40,0x00,0x00,0x01, 0x02,0x02,0x08,0x08,0x20,0x20,0x80,0x80,0x00,0x00, 0x08,0x08,0x04,0x04,0x08,0x08,0x10,0x10, 0x00,0x01,0x01,0x20,0x20,0x40,0x40,0x00, 0x04,0x04,0x00,0x00,0x80,0x80, 0x00,0x40,0x40,0x08,0x08,0x00, 0x01,0x20,0x20,0x01, 0x00,0x00,0x80,0x80}; unsigned char leds_lata4[56] ={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x01,0x01,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x01,0x01,0x00,0x00}; unsigned char leds_lata5[56] ={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; Ура! Теперь пишем "проектор" нашего "кино": Код: int i = 0; void main(void) { // инициализируем таймер, который будет генерировать прерывания, для смены "кадров" // что делает каждая строчка предлагаю разобраться самостоятельно по даташиту и/или учебнику // задача: заставить таймер бесконечно работать и генерировать событие (прерывание) T0CONbits.T08BIT = 0; T0CONbits.T0CS = 0; T0CONbits.PSA = 1; TMR0H = 0; TMR0L = 0; INTCONbits.T0IF = 0; INTCONbits.T0IE = 1; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; T0CONbits.TMR0ON = 1; // бесконечная "кинолента" while(1) { LATC = 0x00; // выключим все, чтобы во время дальнейших переключений не появились "артефакты" LATA = 0x00; TRISC = leds_trisc[i]; TRISAbits.TRISA4 = leds_trisa4[i]; TRISAbits.TRISA5 = leds_trisa5[i]; LATC = leds_latc[i]; LATAbits.LATA4 = leds_lata4[i]; LATAbits.LATA5 = leds_lata5[i]; } } Ну вот, присвоив i какое-то значение от 0 до 55 мы получим какой-то "кадр". Пора делать эффекты! Думаю, никакого труда не составляет сделать "бегущий огонёк" - просто пишем i++, и когда i станет больше 55 - снова его обнуляем. Ну и добавим возможность хаотичного зажигания и изменения скорости. Смешаем это в кучу, и позволим воле случая выбирать: Код: unsigned long ce = 0; //счётчик, который считает, через сколько кадров сменить эффект unsigned char effect = 1; // номер эффекта unsigned char speed = 1; // скорость "киноленты" //оработка прерывания таймера __interrupt() void ISR(void) { if (INTCONbits.TMR0IE && INTCONbits.T0IF) { INTCONbits.T0IF = 0; TMR0H = 100 + (speed * 10); // здесь изменяется интервал таймера, то есть "скорость киноленты" TMR0L = 0; if (++ce > 170){ // если прошло более 170 кадров - меняем эффект effect = rand()%3; // случайным образом выбираем один из трёх эффектов speed = rand()%11;// случайным образом выбираем одну из одиннадцати скоростей ce = 0; // сбрасываем счётчик кадров } switch (effect) // определяем, какой сейчас эффект { case 0: // первый эффект: случайный выбор светодиода i = rand()%56; break; case 1: // второй эффект: бегущий огонёк в одну сторону if (++i > 55) i = 0; break; case 2: // третий эффект: бегущий огонёк в другую сторону if (--i < 0) i = 55; break; } } } Вот и всё. Ничего сложного и масса возможностей для оптимизации (например, очень легко выкинуть массивы *a4 и *a5, просто добавив несколько условий проверки i определенным значениям, кол-во которых существенно меньше элементов массива) Добавлено after 7 minutes 3 seconds: P. S. Не забудьте про токоограничивающие резисторы. |
Автор: | shev1975 [ Пн ноя 23, 2020 20:10:22 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Есть трехразрядный семисегментный индикатор с 6 выводами. По индикатору приходит в голову такое. 1. Определяем тип данных АК {Анод; Катод}. 2. Для цифр каждого из трех разрядов составляем таблицу состояний с типом данных АК, 10 строк (цифры), по 7 записей (сегменты), получится 3 таблицы. 3. Далее таблица 6 (строк) анодов х 5 записей (катодов), в нее для нужных цифр выбрать состояния катодов из всех таблиц состояний: все задействованные сегменты с 1 анодом, потом со 2 и т.д. до 6 анода. 4. После этого остается прокрутить получившуюся таблицу на порте МК. По моим подсчетам 450 байт уйдет на таблицы. Может есть идеи как сделать проще или лучше? Только не надо программу, лучше алгоритм. Не знаю насколько моя безграмотная писанина понятна. |
Автор: | BlackKilkennyCat [ Пн ноя 23, 2020 20:15:27 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
лучше бы нарисовать схему индикатора. |
Автор: | shev1975 [ Пн ноя 23, 2020 20:25:56 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Да там с ума сойти можно, да и не знаю в чем нарисовать схему, могу только таблицу в экселе с номерами анодов - катодов соответственно сегментам. Сейчас перечитал и понял что накосячил немного с алгоритмом. Наверно за счет этого идея не понятна. |
Автор: | BlackKilkennyCat [ Пн ноя 23, 2020 20:27:33 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
ну... хотя бы таблицу. |
Автор: | shev1975 [ Пн ноя 23, 2020 20:39:59 ] | ||
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) | ||
Экселевский не получилось. Один сегмент битый. Схему придется рисовать наверно, понять что еще может засветиться при подаче 0 и 1, и нужно ли Z состояние.
|
Автор: | BlackKilkennyCat [ Пн ноя 23, 2020 21:22:49 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Получившаяся схема: ![]() в формате Diptrace Вложение: Diptrace может удобно менять цвета проводников. Я не вижу навскидку какой-то удобной закономерности, и отводить на это дело полкилобайта, конечно, грешно, но удобнее всего. |
Автор: | shev1975 [ Пн ноя 23, 2020 21:43:03 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Уже болит голова, давно я ее так не включал ![]() ![]() Надо попробовать составить таблицы, может тогда закономерность будет видна. |
Автор: | BlackKilkennyCat [ Пн ноя 23, 2020 21:51:05 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
если это индикатор приёмника,то возникает вопрос возможных вариантов: первый разряд вряд ли отображает 1,2,3,4,5, а последний, возможно, отображает лишь 0 и 5 |
Автор: | shev1975 [ Вт ноя 24, 2020 00:23:53 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Это не принципиально, есть разные подобные индикаторы, на них и текст и цифры, главное понять принцип. Начал писать таблицу и понял что много ерунды написал. Как составлю, попробую сделать выводы, если не получится ничего толкового, то просто выложу новые наметки алгоритма. Добавлено after 2 hours 22 minutes 17 seconds: Последняя идея такая. 1. таблица 3 х 7, для трех разрядов, соответствие сегментов - выводам, структура данных {Катод; Анод} 2. таблица символов, обычная для семисегментного индикатора. 3. массив для вывода данных 6х6, строки аноды, заполнение состояние катодов. Сношая первую и вторую таблицы заполняем массив для всех разрядов, то что не использовалось то Z, прокручиваем таблицу в порт. Плохо, проверить не получится быстро, макетка занята другим проектом. |
Автор: | shev1975 [ Чт ноя 26, 2020 21:36:54 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Эксперимент окончил. Не серьезно конечно, не используя таймеры, но своего добился, цифры зажег на индикаторе, запитал просто через резисторы. Нужен еще ШИМ, зависимый от количества светодиодов включенных одновременно, но мне лень заморачиваться. Писал на Си в среде Ардуино. Может кому пригодится. Спойлерstruct AC{ uint8_t Anode; uint8_t Cathode; }; struct AC table [3][7] = // таблица соответствия выводов сегментам, строки разряды, столбцы сегменты { { {0,5},{2,5},{4,5},{5,3},{3,5},{5,4},{0,4} }, { {4,3},{2,4},{3,4},{2,3},{5,2},{3,2},{4,2} }, { {1,2},{1,3},{4,1},{1,5},{1,4},{2,1},{3,1} } }; uint8_t digit [] = // таблица символов, обычная для семисегментного индикатора { B00111111, B00000110, B01011011, B01001111 }; uint8_t output [6][6]; // сводный массив вывода на индикатор void setup() { DDRB = B00000000; } void loop() { uint8_t first = 1, second = 2, third = 3; // цифры первого, второго и третьего разряда for (uint8_t q = 0; q < 6; q++) // инициализация массива for (uint8_t w = 0; w < 6; w++ ) if (q == w) output[q][w] = 1; else output[q][w] = 2; // 2 - Z состояние for (uint8_t i = 0; i < 7; i++) // заполнение сводной таблицы { if (bitRead(digit[first],i)) output[table[0][i].Anode] [table[0][i].Cathode] = 0; if (bitRead(digit[second],i)) output[table[1][i].Anode] [table[1][i].Cathode] = 0; if (bitRead(digit[third],i)) output[table[2][i].Anode] [table[2][i].Cathode] = 0; } for (uint8_t e = 0; e < 6; e++){ //вывод сводной таблицы for (uint8_t r = 0; r < 6; r++){ if (output[e][r] == 0) { pinMode((r + 8 ), OUTPUT); digitalWrite((r + 8 ), LOW); } else if (output[e][r] == 1) { pinMode((r + 8 ), OUTPUT); digitalWrite((r + 8 ), HIGH); } } delay (1); //DDRB = B00000000; // что то пошло не так), подсвечивался сегмент а, младшего разряда. for (uint8_t t = 0; t < 6; t++) pinMode((t + 8 ) , INPUT); // перевод порта в высокомное состояние Z } } ![]() |
Автор: | shev1975 [ Пт ноя 27, 2020 20:56:57 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Удалось обойтись без ШИМа, добавил диоды параллельно резисторам. |
Автор: | ass20 [ Сб янв 01, 2022 22:49:39 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
хорошая елка собрал к НГ на stm8 хотелось бы поднять яркость светодиодов, мож кто подскажет как,? |
Автор: | musor [ Вс янв 02, 2022 00:51:54 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
вариавнты 1поставить жирнояркие диоды 2 постапвить ключи умощнялки +уменшт резистры 3 понять простить забить... насрать+ пойти забухать... Добавлено after 2 minutes 49 seconds: shev1975, там навернфка тупа матрица но не 8х3 а иная причем я встречал индюки где часть диодоф сидела на техже ногах но в обратной поляре такие в какихто ксерах/факсах шли надергал тогла думал дохлые пока допер что на класику без внутренего чипа DC мало нок.. |
Автор: | Martian [ Вс янв 02, 2022 06:44:15 ] | ||
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) | ||
Яркость поднять несложно, но расходно по компонентам: нужно обеспечить полумостовой драйвер на каждый канал, то есть, сделать такой же порт ввода-вывода, как у микроконтроллера, только мощнее. Это потребует 20 транзисторов и 20 "ног" микроконтроллера, плюс обвязка из резисторов. Но если использовать "цифровые" транзисторы (со встроенными резисторами), то паять деталек станет значительно меньше. Использование сдвиговых регистров может помочь сохранить микроконтроллер, всё-таки стоимость последнего и дефицитность пока ещё актуальны. Получится так: ![]() В данной схеме сознательно не используется первый разряд регистра - это не сильно усложняет программу, но значительно упрощает трассировку платы. Разумеется, это не единственный вариант, но он один из самых доступных и недорогих, да и достаточно однотипные детали не так сложно монтировать. Следует учесть, что импульсный ток светодиодов имеет ограничение, и предварительно провести эксперимент: хватит ли максимального импульсного тока при нужной длительности/скважности импульса, чтобы обеспечить необходимую яркость. В архиве - схема в форматах Diptrace и PDF.
|
Автор: | ass20 [ Вс янв 02, 2022 12:55:30 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Я думал сдлеать на буферах 74HC244 поставить их 2шт и пусть ток 10мА на канал и 50 мА на микросхему Сама HC244 позволяет на ножку 20мА и суммарно на все ноги 70мА ну либо 3 HC244 и выходы запаралелить, чтоб 20мА гнать в линию и не перегружать вывод микросхемы ... |
Автор: | musor [ Вс янв 02, 2022 13:30:58 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
зачем НС они слабые и нежные-гавно кароче возми 74F244(531ап) там 1.5вт на корпус легко и не дохнет никогда я их гонял в хвост и в гриву во времена популярности ТТЛ и да пинаут тотже если че если PCB развели под НС/LS то замена на F не потребут ее менять при болшой нагрузке к верхам чипоф я клеил маленкий радиатор "алсил2 термоклем хотя и без него все работает Добавлено after 1 minute 36 seconds: есть1 условие по 1 кер кондею 0.1мк на 1 корпус прям на питание!!! иначе могут сбоить |
Автор: | Martian [ Вс янв 02, 2022 13:46:54 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
как предложенные вами варианты избирательно на каждом разряде обеспечат 3 состояния? |
Автор: | musor [ Вс янв 02, 2022 13:58:00 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
у буфероф 244/245 Z импеданс гарантирован про другое не скажу не изучал вапрос |
Автор: | Martian [ Вс янв 02, 2022 13:59:44 ] |
Заголовок сообщения: | Re: Ёлка новогодняя из светодиодиков. (чарлиплексинг) |
Если на входе Z, то и на выходе Z? |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |