DIY или Сделай Сам / [Из песочницы] RGB светлячок на Attiny13

в 9:49, , рубрики: attiny13, avr, DIY, микроконтроллеры, метки: , , ,

Приветствую Вас, коллеги, товарищи сопутствующие и просто интересующиеся!
Намедни смастерил девайс, который можно использовать как основу для оригинального подарка, сувенир или просто сделать ради собственного удовольствия, если таковое вам доставляет возня с современной микроэлектроникой. Сразу видео демонстрация устройства:
К сожалению, камера не может передать оттенки и переливы свечения RGB-светодиода, в живую это выглядит намного симпатичнее. Однако, если тем не менее вы заинтересованы, то далее много букв и картинки.

Предпосылками для создания устройства явились непреодолимая тяга к всё и вся заполоняющим микроконтроллерам, статья товарища Ariman (Творим оригинальный подарок при помощи химии физики и электроники) — за что ему ещё раз отдельный респект и уважуха, и желание сделать чего-нибудь интересное своими руками.
Сперва я предлагаю вашему вниманию quick assembly manual, а далее, для любознательных, подробности внутреннего устройства и ТТХ.
Итак, нам понадобится:
1. Микроконтроллер Atmel Attiny13 — 1 шт.
2. RGB светодиод — 1 шт.
3. Макетная плата типа CRS 044 — 1 шт.
4. Резистор 1 МОм, smd — 1 шт.
5. Медная проволока (жила из витой пары) — 30 см.
6. Батарейка CR2032 — 1 шт.
7. Скрепка — 1 шт.
image
Также предполагается наличие паяльника, нехитрого инструмента для работы с электроникой и прямые руки.
Первым делом отрезаем от макетной платы кусок размером примерно 3х3 см. Размер определяется габаритами батарейки, которая должна поместится на обозначенном кусочке, с учетом зазора для проволочного сенсора по бортам.
image
После выпиливания куска платы, разгибаем скрепку, которую мы будем использовать как контакт-держатель батарейки. Скрепку изгибаем нужным образом и закрепляем в отверстиях платы. Просовываем батарейку и подгибаем, что бы плотно держалась. Также из медной проволочки делаем второй контакт для отрицательного полюса батарейки.
image
Оба контакта припаиваем к макетной плате. Ещё раз всовываем батарейку и проверяем надежность её крепления. Скрепку лучше поджимать поплотнее, пробуйте пока батарейка не будет хорошо держаться.
image
А теперь будем шить. Но не микроконтроллер, а вспоминаем навыки шитья ниткой и иголкой. Стежок за стежком, по периметру, медной проволочкой обходим нашу платку, а концы выводим в обозначенном месте. Это будет наш сенсор. Один момент, на углах главной диагонали проволочку перекусываем и закрепляем. Потому, как оказалось в дальнейшем ("… опыт, сын ошибок трудных...") такой большой сенсор плохо калибруется и приводит к некачественному детектированию прикосновения. Так что роль сенсора остается лишь за двумя сторонами квадрата нашей платы, остальная часть носит декоративный характер (на фотке сенсор не перекушен, т.к. всё это выяснилось уже после пробных испытаний. Но перерезанный сенсор видно на последней фотке готового устройства).
image
Ну вот мы и добрались до нашего микроконтроллера. Какая же это всё таки замечательная штука! На малюсенькой площадке с всего 8-ю лапками и тебе АЦП, и таймер, и аппаратный ШИМ, и генератор у него встроенный и электричество ты ему только покажи, а он уже работает. Что ещё нужно для счастья, тем более что цена этому удовольствию всего 75 американских копеек. Есть конечно и некоторые недостатки, но — что же, мир не идеален. Ладно, хватит лирики, продолжаем.
Итак, припаиваем нашу тиньку на подготовленную площадку. СТОП!.. Чуть не забыл. Вот теперь будем шить.
Скачиваем готовую кошерную прошивку и заливаем её любым удобным способом, лично я использовал простейший LPT программатор, правда доточил его немного под себя, но это не суть важно — схема простая как табурет, работает надёжно как молоток. Фьюзы не трогаем.
Вот теперь припаиваем нашу тиньку на подготовленную площадку: 4-й вывод (земля, минус источника) к проволочному контакту от центра батарейки, 8-й вывод (питание, плюс источника) к скрепке, 2-й вывод к проволочке от сенсора. Сбоку цепляем smd резистор (1 МОм), между выводами 2 и 3. Если smd резистора под рукой не окажется, подойдет и обычный какой удастся впихнуть.
image
Дело осталось за малым — RGB-светодиод. RGB-светодиод нам нужен тот, который с четырьмя выводами (бывают, однако, как ни странно, и с 2-мя — их не берите). Три из них, это аноды диодов красного, зеленого и синего цветов, один вывод — общий. Линзу светодиода нужно предварительно наплавить прозрачным силиконовым термоклеем. Если этого не сделать, то светиться он будет не очень красиво, т.к. излучатели дают пучки, которые почти не смешиваются и в целом смотрятся не айс. Так что греем термопистолет и густо наносим расплавленный силикон на головку светодиода, тут можно проявить свои скульптурные способности, попытавшись изобразить цветочек, жучка или что получится.
image
Затем припаиваем светодиод к микрухе, общий на 4-ю ножку (земля), красный на 5-ю, синий на 6-ю, зеленый на 7-ю (расположение цветов имеет значение, т.к. для зеленого используется программная коррекция яркости).
image
Ну вот и всё! Смело и ловко вставляем батарейку — должны по очереди засветится 3 цвета, каждый в течение 1 сек. За это время вы должны убрать руки от устройства, потому что затем немедля стартует калибровка сенсора, о чем нам сигнализирует задорное мигание в течение около 4-х секунд. В этот период фиксируется состояние сенсора когда к нему не прикасаются. После того как иллюминация закончится, можете брать светлячка в руки и наблюдать за завораживающими переливами красок, игрой света и полутонов.

Если вы ещё не бежите в ближайший магазин радиоэлектроники за деталями, то предлагаю вашему вниманию разгадку фокуса, т.е. как всё это работает. Также, возможно, кое-что покажется интересным и тем кто в теме. Как я уже писал, основой конструкции явилась вышеупомянутая статья. Поэтому за описанием основ и работы сенсора я отсылаю вас к ней, там всё очень хорошо разжевано. Моим усовершенствованием является подключение к тиньке RGB и рефакторинг кода. Поясню подробнее: 13-я тинька, конечно, прекрасна, но вот только аппаратных ШИМ каналов у неё всего 2, а для управления RGB светодиодом, как нам подсказывает Кэп, нужно как минимум 3 канала. Отсюда возникает вопрос: где взять ещё один ШИМ канал? На вопрос, на простой есть ответ такой — не будем мы искать ещё один ШИМ, и вообще не будем юзать аппаратный шим, а запилим свой программный ШИМ — православный, сколькиугодноканальный! От громких лозунгов перейдем к реальной практике. Надеюсь, что такое ШИМ, скважность, объяснять не надо?(Вопрос риторический).
Итак, дано:
1. Частота ШИМ канала — не менее 100 Гц, вообще-то глаз и до 50-ти мерцание практически не замечает, но реальные пацаны меньше чем на 100 не смотрят. Т.о. длительность импульса со скважность 100% должна быть 10 мс. В эти 10 мс мы должны запихнуть регулировку яркости, минимум 100 уровней. Тогда получаем, что минимальная длительность импульса — 0,1 мс (на скважности 1%).
2. Частота внутреннего таймера микроконтроллера — зависит от а)частоты тактового генератора, которая, т.к. мы используем внутренний, может быть 4,8 или 9,6 МГц; б)делителя генератора тактовой частоты; в)делителя самого таймера. С помощью таймера мы должны иметь возможность отсчитывать интервалы 0,1 мс, т.е. обрабатывать события на частоте минимум 10 КГц.
Короче, в результате теоретико-эмпирических изысканий были получены такие результаты. Тактовая частота контроллера 9,6 МГц, таймер работает с делением 1/256 = на частоте 37,5 КГц. Для того, что бы иметь возможность обрабатывать события на этой частоте, устанавливаем режим работы таймера срабатыванием по совпадению. Т.е. как только счётчик таймера совпадает с установленным в регистре ORCA0 значением, происходит прерывание — а мы тут как тут. При этом установленное значение регистра ORCA0, как некоторые из вас уже догадались, должно быть 0. Яркость будем регулировать не 100, а 256-ю уровнями (контроллер то 8-ми битный, так оно сподручнее, да и оттенков больше), тогда получаем частоту ШИМ 37500/256=146 Гц, что более чем удовлетворительно.
Рассмотрим поподробнее обработку прерывания:

//глобальные переменные
unsigned char wave_counter=0;//счётчик ШИМ цикла

unsigned char red_bs=0;//яркость светодиода1 (0-255)
unsigned char green_bs=0;//яркость светодиода2 (0-255)
unsigned char blue_bs=0;//яркость светодиода3 (0-255)

interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
PORTB.RED=(wave_counter<red_bs);
PORTB.GREEN=(wave_counter/2<green_bs);
PORTB.BLUE=(wave_counter<blue_bs);
wave_counter++;
}

яркость каждого светодиода задается глобальными переменными red_bs, green_bs, blue_bs и меняется основной программой согласно плану спецэффектов. Счётчик wave_counter крутится по кругу. Когда яркость светодиода больше значения счётчика, он светится, в противном случае потушен. Т.о. если яркость 255, то это соответствует 100% скважности. Деление на 2 в зелёном светодиоде я сделал для того, что бы повысить его яркость, т.к. визуальная его светимость оказалась меньше остальных, по-видимому специфика спектральной характеристики. В общем, гурманы и интересующиеся могут оценить весь исходник.
Многое ещё можно было бы написать и по поводу регулировки общей яркости, и по поводу обработки сенсора, и размера программы и объема памяти (эх, тиня, вот ещё одно больное место), настройки сторожевого таймера и режима пониженного энергопотребления (кстати, как показал замер, в спячке схема кушает 0,06 мА)… Можно было бы приложить осцилоглофограммы, что бы повысить наглядность и понятность для начинающих, обсудить использование функции rand() и подискутировать о противопоставлении прелестей программирования на ассемблере удобству и мощности оптимизации кода компилятора CodeVisionAVR. Но, как говорил незабвенный Козьма Прутков:«Нельзя объять необъятное», а народная мудрость гласит — «Хорошего понемногу». Надеюсь, у меня ещё будет возможность поделиться с вами изысками в это области, чего и вам желаю, также профессиональных, творческих и всяческих успехов.
Присутствующих дам — с наступающим!

Автор: Anderwonder


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js