Лампа настроения на ардуино своими руками

Обновлено: 08.07.2024

Лампа настроения (mood lamp) - небольшая декоративная настольная лампа, которая периодически случайным образом плавно меняет свой цвет. В сети полно разных вариантов самодельных ламп настроения (в том числе и на AVR), но просто смена цвета случайным образом - это достаточно скучно. В этой статье я расскажу о том как сделать простую лампу настроения, которая реагирует на звук.

Идея

Итак, идея в том что бы снабдить привычную лампу настроения микрофоном, и заставить её менять цвет не просто случайным образом, а в зависимости от того что она "слышит" через этот микрофон. Лампа будет работать в трех режимах (режим переключается единственной кнопкой):

- Простой режим , или режим обычной лампы настроения. Лампа просто периодически случайным образом меняет цвет.
- Реакция на резкий зву к. В этом режиме лампа не меняет цвет самопроизвольно, а делает это только когда услышит резкий звук, вроде хлопка, громкого крика или легкого удара по корпусу ламы или столу.
- Анализ частоты звука . В этом режиме лампа меняет цвет в зависимости от частоты звука который она "слышит", то есть что-то типа цветомузыки.

Реализация

С идеей понятно, приступим к реализации. Для такой лампы понадобятся, как минимум, три вещи: яркий трехцветный светодиод - что бы светить, микрофон - что бы слышать, и микроконтроллер - что бы управлять всем этим хозяйством.

Светодиод

В качестве светодиода я использовал сверхъяркий трехцветный (RGB) светодиод мощностью 3Вт (по 1Вт на каждую из цветовых компонент). Сам светодиод установлен на алюминиевой пластине-радиаторе, и выглядит вот так:

Светит достаточно ярко и имеет широкий "угол обзора" - нет яркого пятна посредине.

К сожалению, подключить такой светодиод напрямую к ножкам микроконтроллера не получится, потому что тока ему нужно около 200Ма на канал, а, например, максимально допустимый ток через ножку контроллера ATMega8 - всего 40Ма. Поэтому на каждый канал светодиода я поставил по транзистору - контроллер открывает/закрывает транзистор, меняя напряжение на базе. А транзистор зажигает/тушит светодиод, ведь максимально допустимый ток транзистора целых 800Ма (для BC337), что с головой хватает что бы зажечь светодиод.

Микрофон

В качестве микрофона используется обычный электретный микрофон (капсюль), подключенный к АЦП микроконтроллера через усилительный каскад.

В принципе, можно было бы использовать цифровой микрофон, но на нашем радиорынке оказалось гораздо проще найти электретный микрофон.

Микроконтроллер

Здесь выбор казался вполне очевидным - ATMega8. Что-то слабее использовать не получится, так как нужно три канала ШИМа (по каналу на каждый из трех цветов светодиода). Использовать что-то более мощное , казалось, не имеет смысла. Поэтому я и остановил свой выбор на микроконтроллере ATMega8.

Но здесь меня подстерегали грабли. Дело в том, что для реализации программы управляющей лампой мне понадобилось использование арифметики с плавающей точкой, а AVR-ки, к сожалению, не имеют FPU. Поэтому для дробных чисел используется программная реализация FPU, которая занимает достаточно много места в памяти микроконтроллера. В результате память ATMega8 оказалась забита под завязку. Если бы сейчас я решил собрать еще одну лампу, то наверняка поставил бы как минимум ATMega32.

Схема и печатная плата

С основными компонентами разобрались, теперь осталось объединить все это воедино:


Обвязка микроконтроллера стандартная: питание, кнопка сброса, разъем программатора.

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

На вход аналогового питания (AVCC) подключен LC-фильтр (дроссель и конденсатор), по рекомендации даташита на ATMega8 (см. раздел даташита "Analog Noise Canceling Techniques"). Правда, как оказалось - найти на нашем радиорынке подходящий дроссель достаточно проблематично, поэтому я поставил что нашел, а именно - старый советский дроссель на 120мкГн.

Кнопка BUTTON используется для переключения режимов работы лампы.

Светодиод DBG_LED использовался для отладки прошивки, и ставить его не обязательно.

В правом верхнем углу схемы изображен усилительный каскад для подключения микрофона к АЦП микроконтроллера. Сам микрофон подключается в разъем MIC.

Немного ниже изображена схема для подключения RGB светодиода. Базы транзисторов подключены к ножкам контроллера которые умеют генерировать аппаратный ШИМ (OC1A, OC1B, OC2). Катоды светодиода через транзисторы посажены на землю. Джампер JP1 нужен что бы можно было отключать канал OC2 от транзистора. Дело в том, что OC2 является по совместительству и входом MOSI для программатора, поэтому при прошивке микроконтроллера со включенным джампером светодиод начинает раздражающе моргать. Ставить его, в принципе, не обязательно.

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

Корпус

В качестве корпуса используется выпотрошенный обычный светильник. Плата прикручена болтами к нижней части корпуса. Микрофон прижат припаянным к корпусу куском провода.

Светодиод крепко держится на куске текстолита, прижатый припаянными к нему проводами. Сам кусок текстолита прикручен шурупами к деревянному брусочку, который прикручен к основной плате.

Собранная лампа в корпусе выглядит вот так:

Программная часть

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

Сначала немного об общей структуре программы. Поддержка разных режимов сделана с помощью указателей на функции, поэтому менять/добавлять новые режимы очень просто. Есть enum Mode, в котором перечислены все режимы в которых умеет работать лампа. Есть два массива с указателями на функции: mode_callbacks и mode_switch_callbacks. Массив mode_callbacks содержит указатель на главную процедуру для каждого режима. Массив mode_switch_callbacks, по аналогии, содержит указатели на функции смены режимов. Функция смены режима нужна что бы дать пользователю понять что произошло переключение в новый режим работы.

В функции main находится главный цикл который состоит ровно из трех строчек:

- mode_callbacks[mode](); Фактически это вызов главной процедуры для текущего режима работы. Она будет выполняться до тех пор пока пользователь не нажмет на кнопку.
- mode = (mode + 1) % ModeLastInvalid; Переходим к следующему режиму.
- mode_switch_callbacks[mode](); И вызываем обработчик смены режима для нового режима. Все что сейчас делают эти обработчики - мигают пять раз каким-то цветом. После выполнения этой строки мы вновь возвращаемся в начало цикла.

Еще, пожалуй, стоит упомянуть функции schedule_delay и pick_random_color.

Функция schedule_delay используется для генерации задержек. Она необходима потому что нельзя просто вызвать стандартную функцию вроде _delay_ms и уснуть, ведь нужно считывать данные с АЦП и проверять состояние кнопки (не нажал ли её пользователь). Именно эти задачи функция schedule_delay и выполняет. На самом деле, можно было бы использовать режим непрерывного преобразования в АЦП, а обработку нажатия на кнопку повесить на прерывание, но как показала практика, в режиме непрерывного преобразования шумы на АЦП больше чем в режиме одиночного преобразования.

Функция pick_random_color просто выбирает случайный цвет (в формате RGB). Вернее не совсем просто, а с одним нюансом: что бы чаще появлялись красивые "чистые цвета" (красный, зеленый, синий) введена константа COLOR_CLEAR_PROBABILITY, которая в процентах задает частоту появления "чистых" цветов. То есть если её значение равно 50, то примерно каждый второй случайный цвет будет красным, зеленым либо синим.

Режим лампы настроения

Главная процедура режима - mood_lamp_mode. Это самый простой режим, и его поведение вполне очевидно из кода: выбираем и запоминаем новый случайный цвет, плавно меняем текущий цвет лампы к выбранному цвету, "удерживаем" его некоторое время и начинаем все сначала.

Режим реакции на громкий звук

Главная процедура режима - sound_lamp_mode. В целом все похоже на предыдущий режим, с парой нюансов. Во первых, режим "удержания" цвета не ограничен по времени - переключение к выбору нового цвета произойдет не по таймауту, а если лампа "услышит громкий звук". А во вторых, во время плавного перехода к новому цвету может произойти переключение к выбору нового цвета (опять же, если лампа услышит громкий звук).

Пару слов о функции sound_lamp_mode_get_mic. Её задача - получить текущий "уровень" звука на микрофоне. Работает она следующим образом: сначала отключаются все три канала ШИМ, потом прогоняется пара холостых преобразований АЦП и запоминается значение с АЦП, затем восстанавливаются значения на ШИМ-ах. Такие костыли пришлось добавить потому что работа ШИМа сильно портит показания АЦП (я подозреваю здесь сказывается китайский блок питания, который не может обеспечить стабильное напряжение).

Режим анализа звука

Главная процедура режима - sound_analysis_mode. По сути, этот режим представляет собой последовательное выполнение двух операций: определение частоты звука, и изменение цвета на цвет соответствующий этой частоте. Рассмотрим их более подробно.

Изначально я хотел использовать дискретное преобразование Фурье для определения частоты звука. Но уместить его в восьми килобайтах памяти микроконтроллера никак не получилось, поэтому пришлось использовать другой, более примитивный способ. Суть способа состоит в подсчете пересечения звуковым сигналом нуля. Реализовано это следующим образом - звуковой сигнал записывается в буфер, затем мы проходим по этому буферу и подсчитываем, как много последовательных пар элементов лежат по разные стороны от нуля. Только вот ноль это не математический ноль, а нулевая амплитуда, для которой используется константа SOUND_AMPL_ZERO. Что бы было понятнее рассмотрим пример: пусть нулевая амплитуда у нас это 100, тогда пара значений 95 и 120 пересекают ноль, т.к. они лежат по разные стороны от нулевой амплитуды (95 меньше 100 а 120 больше 100). А вот пара 80 и 90 не пересекают, т.к. оба этих значения меньше ста. Таким образом частота это количество пересечений нуля деленное на единицу времени.

Теперь о том как на основании частоты выбрать цвет. Цветовая модель RGB для этого слабо подходит, поскольку каждый её компонент фактически контролирует три параметра: тон, насыщенность и яркость, а мне же хотелось что бы частота влияла только на тон, а яркость и насыщенность оставались постоянными. Поэтому я выбрал цветовую модель HSV. Яркость и насыщенность постоянны и равны их максимальным значениям, а тон напрямую зависит то частоты. Когда на основании частоты получено значение цвета в HSV, выполняется преобразование из HSV в RGB, и полученный цвет выводится на светодиод. Весь процесс преобразования частоты звука в цвет в модели RGB выполняется в функции convert_freq_to_rgb.

Результат

Собственно результат, как и фото процесса изготовления, можно посмотреть на этом видео:

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

Схема очень-очень-очень проста (как и положено для простого устройства):

Принципиальная схема

В отличие от известных аналогов, я сделал все на самом маленьком и дешевом микроконтроллере из доступных - attiny13. В качестве ключевых транзисторов VT1. VT3 применил IRLML2402, можно и другие аналогичные "логические". Резисторы R1. R3 ограничивают ток кристаллов мощного светодиода, их сопротивление зависит от напряжения питания и параметров самого светодиода. Надо подобрать их так, чтобы обеспечивался одинаковый ток через кристаллы (либо, если есть точные параметры светодиода, надо выбрать такие значения токов, чтобы обеспечивалась одинаковая яркость каждого кристалла). В моем случае для красного кристалла пришлось ставить 7.5 Ом, а для синего и зеленого по 5,6 Ом.

Питание на схему RGB-светильника подается на клеммы X5 (минус) и Х4 (плюс). Я использовал свой любимый китайский адаптер, который выдает как раз подходящее напряжение и имеет достаточную мощность. Однако, можно использовать отдельные источники для МК и светодиода, тогда следует обеспечить для МК питание 5 вольт, а для светодиода - сколько требуется. Светодиод на схеме не показан, но и так понятно, что подключается он к катодами к клеммам Х1. Х3, а аноды, естественно, к плюсу источника питания.

Конденсатор С1 может быть любым электролитическим, чем больше емкость, тем лучше, напряжение не менее 10 вольт. С2 - обязательно керамический, достаточно 0,1 мкФ. Оба конденсатора надо разместить как можно ближе к выводам питания МК, и при разводке платы учесть пути протекания силовых токов, чтобы МК не сбоил. Если что - соедините 1 вывод МК с плюсом питания.

Особо следует отметить роль RC-фильтра R4-C3: если планируется использование дистанционного управления, эти элементы ставить обязательно! К сожалению, при разработке платы они не были учтены. Сопротивление R4 равно 100 Ом, а емкость C4 может быть от 47 до 220 мкФ.

В схеме лампы настроения имеется приемник ИК-излучения BQ1, однако в текущей версии программного обеспечения он не используется, заложен на перспективу, т.е. можно и не устанавливать его.

Печатная плата очень проста, раз проста схема, поэтому я не привожу ее чертеж. Дело в том, что ее форма и размеры целиком определяются тем, какой именно светильник будет у вас, как вы будете крепить светодиод внутри него, какой будет радиатор светодиода (ни в коем случае не включайте мощный светодиод без радиатора!) и т.п. Я использовал светильник из магазина ИКЕА и подходящий радиатор из запасов, поэтому моя плата имеет форму бублика. На следующих фотографиях вы видите все составные части моей конструкции - все понятно и без слов.

Радиатор

Это мой радиатор (раньше на нем стоял мощный транзистор).

Печатная плата


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

Ниже - три вида с разных сторон "светильного элемента", т.е. светодиода, установленного на радиатор и соединенного с платой.

Монтаж

Монтаж

Монтаж


Крепится в светильнике все это добро при помощи слегка укороченного держателя патрона от настоящего светильника (продается он в магазине ИКЕА за 299 рублей, предназначается для лампы накаливания).

Вот этим все крепится


В готовом виде мой RGB-светильник светильник выглядит вот так:

Видео работы лампы настроения в моем исполнении я уже публиковал - можно посмотреть его на старом месте. А в самом начале статьи вы видели коллаж из фотографий светильника в разные моменты времени его работы.

Да, главное! При прошивке микроконтроллера необходимо установить следующее состояние fuse-битов: LOW BYTE 0x7A , HIGH BYTE 0xFB . Разные программаторы показывают состояние фьюзов по-разному, но все нормальные программаторы должны уметь показывать шестнадцатиричное значение fise-байтов, поэтому я привел именно их, чтобы не было никакой путаницы. На всякий случай поясняю: надо включить встроенный генератор 9,6 МГц, отключить делитель на 8, настроить схему BOD на 1,8 вольта. Все прочие можно не трогать, оставив, как было.

Вскоре я надеюсь сделать вариант светильника с дистанционным управлением.

В отличие от известных аналогов, все сделано на самом маленьком и дешевом микроконтроллере из доступных — attiny13. В качестве ключевых транзисторов VT1…VT3 применены IRLML2402, если светодиод маломощный, то можно заменить их транзисторами, только не забывайте про резистор. Резисторы R1…R3 ограничивают ток кристаллов мощного светодиода, их сопротивление зависит от напряжения питания и параметров самого светодиода. Надо подобрать их так, чтобы обеспечивался одинаковый ток через кристаллы (либо, если есть точные параметры светодиода, надо выбрать такие значения токов, чтобы обеспечивалась одинаковая яркость каждого кристалла). В моем случае для красного кристалла пришлось ставить 7.5 Ом, а для синего и зеленого по 5,6 Ом.


Конденсатор С2 может быть любым электролитическим, чем больше емкость, тем лучше, напряжение не менее 10 вольт. С1 — обязательно керамический, достаточно 0,1 мкФ, параллельно ему очень желательно поставить конденсатор на 100vra/ Оба конденсатора надо разместить как можно ближе к выводам питания МК, и при разводке платы учесть пути протекания силовых токов, чтобы МК не сбоил. Если что — соедините 1 вывод МК с плюсом питания.

При прошивке микроконтроллера необходимо установить следующее состояние fuse-битов: LOW BYTE 0x7A, HIGH BYTE 0xFB. Разные программаторы показывают состояние фьюзов по-разному, но все нормальные программаторы должны уметь показывать шестнадцатиричное значение fise-байтов, поэтому я привел именно их, чтобы не было никакой путаницы. На всякий случай поясняю: надо включить встроенный генератор 9,6 МГц, отключить делитель на 8, настроить схему BOD на 1,8 вольта. Все прочие можно не трогать, оставив, как было.

Для пультов дистанционного управления производится довольно много специализированных микросхем, но для домашнего творчества лучше и проще использовать микроконтроллер. Я выбрал attiny13, как наиболее миниатюрный среди недорогих и дешевых микроконтроллеров. Так как каждый порт этого контроллера способен выдавать ток до 40 мА, то ИК-светодиод запросто можно подключать к микроконтроллеру без дополнительных ключевых транзисторов, тем более что можно соединить три порта для увеличения суммарной нагрузочной способности. А теперь внимание — вопрос знатокам: если у attiny13 всего 8 ножек, 2 из которых питающие, а одна — вход сброса, использовать который нежелательно (так как в этом случае повторная прошивка микроконтроллера будет сильно затруднена), сколько остается свободных выводов для подключения 5-и кнопок? Правильный ответ: две.

Интересуетесь, как можно подключить 5 кнопок к двум выводам микроконтроллера? Да все очень просто! Ведь в выбранном нами микроконтроллере есть встроенное АЦП, а значит кнопками можно коммутировать напряжения с резисторного делителя, и тогда МК будет способен определить нажатую кнопку по входному напряжению.

Однако, не все так уж просто, потому как для пульта дистанционного управления очень важно минимальное потребление энергии в режиме ожидания, и именно поэтому основную часть времени микроконтроллер должен находиться в режиме сна, т.е. практически в полностью отключенном состоянии. Естественно нельзя использовать делитель напряжения, постоянно подключенный к батареи питания пульта, чтобы не разрядить ее быстро. Придется подключить делитель к одному из свободных выводов и подавать на него питание только в нужные моменты. И тут снова вопрос: нужный момент — это когда нажата кнопка, не так ли? И получается, что нажатие кнопки мы должны определить по напряжению, которое подается только после нажатия кнопки…


Главное, что надо учитывать, это то, что сопротивления в делителе могут быть совсем не любого номинала. Дело в том, что встроенная подтяжка — это резистор порядка 30-40 килоом, а значит для надежного появления низкого логического уровня при нажатии любой кнопки сопротивление резисторов в делителе (если они все одинаковые — это удобно) не должно быть больше 10-15 килоом. Я остановился на сопротивлении 10К.Пульт работает в стандарте RC5, причем для управления яркостью я использовал стандартные команды, а для выбора цвета — команды изменения уровня. Код семейства выбран соответствующий — осветительные устройства, поэтому пульты от магнитол и телевизоров не будут влиять на наш светильник (и наоборот).

Исходник программы пульта содержит подробные комментарии, там все просто, надеюсь, проблем разобраться у желающих не возникнет. Ну а для непрограммистов я предлагаю готовую прошивку для МК. Следует отметить, что SMD-микроконтроллер нужно программировать или в специальном адаптере, или прямо в схеме, припаяв к нему проводки. В последнем случае надо после программирования соединить между собой припоем выводы 7-6-5, а вывод 1 соединить с питанием. Если потребуется повторная перепрошивка — надо соответственно освободить выводы, фьюзы для Мк нужно выставлять следующим образом:


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

Сделаем с помощью Arduino самую крутую атмосферную лампу, которая создаст дома настроение и удивит ваших друзей или вторую половину.

Классный проект от сайта и канала на YouTube "how-td". Мы видели пару подобных проектов, сделанных из дерева и акрилового стекла, но автор решил сделать свой собственный, более интересный, вариант.

Делаем атмосферную лампу с помощью Arduino

Шаг 1. Выбираем материалы

Шаг 1: Материалы

Шаг 1: Материалы

Шаг 1: Материалы

Шаг 1: Материалы

Шаг 1: Материалы

Прежде всего - выбираем материалы. Вы можете выбрать все, что захотите, но в примере использованы: грецкий орех 1/2", амарант 1/8" и прозрачный акриловый лист толщиной 1/4 дюйма.

Шаг 2. Резка и склейка лампы

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Шаг 2: Резка

Вырезаем все с помощью авто-пилы на квадратные куски 3 на 3 дюйма. Затем вырезаем отверстия в "грецком орехе" и "акрилах" примерно по 2 дюйма для электронных компонентов. Склейте все части вместе и оставьте их высохнуть.

Осторожно размалывайте края на ленточном шлифовальном станке и почистите всё шлифовальной бумагой, сеткой 220, 400, 800. С помощью дремели вырезаем пространство для платы Arduino и микро USB.

Шаг 3. Электроника


Шаг 3: Электроника

Шаг 3: Электроника

Пришло время для электроники и нам понадобятся:

Шаг 4. Пайка элементов лампы

Шаг 4: Пайка элементов лампы

Шаг 4: Пайка элементов лампы

Шаг 4: Пайка элементов лампы

Шаг 4: Пайка элементов лампы

Шаг 4: Пайка элементов лампы

Припаяйте диоды к второму цифровому выходу Arduino, а микрофон выводите на второй аналоговый вывод, Ground (земля) к Groung и VCC на 5 вольт.

Шаг 5. Код скетча

Загрузите скетч и если он отлично работает - время клеить компоненты на свои места.

Сам код скетча такой:

Шаг 6. Финальный шаг

Шаг 5: Финальный шаг

Шаг 5: Финальный шаг

Чтобы сделать нижнюю часть, печатаем простой лист размером 3 на 3 дюйма, который вы можете сделать с помощью другого куска дерева. Последний шаг, который, вероятно, лучше сделать прежде чем устанавливать электронику - смазать древесину датским маслом, чтобы получить более привлекательный вид и защитить поверхность. Вероятно, это всё, что хотел рассказать сегодня.

Видео урока

На этом всё. Наша крутая лампа готова.

Читайте также: