На Хабре публиковались уже похожие конструкции лампы, управляемые от компьютера и автономные ([2, 3]). Моя реализация умеет делать динамическое освещение в 6-ти режимах, рассчитана на питание от USB, и в программе поддержки уделено особое внимание восстановлению работоспособности при «горячем» отключении и подключении лампы, а также восстановлению работы после выхода компьютера из спячки. Конструкция, программное обеспечение и принцип работы подробно рассматриваются в этой статье.
[Первые эксперименты]
Когда изучал возможности микроконтроллеров Atmel, захотелось создать USB девайс - не просто питающийся от USB, а настоящий, управляемый от программы на компьютере. Наткнулся на статью [1], и очень заинтересовала идея реализации USB протокола на микроконтроллере без аппаратной реализации USB (применена библиотека V-USB). Пример для ПО хоста (программа для компьютера) в статье был на C#, что еще больше заинтриговало, и была собрана макетная плата на AtMega32.
Подключение к USB сделал через те же ножки микроконтроллера, как в [1]. Все порты вывел наружу и отдельно сделал ISP-разъем для программирования. Установил светодиод, подключенный к одной из ножек порта PORTB.
Логика работы прошивки (firmware микроконтроллера) такова, что она ждёт команд на исполнение и только. Прошиваем один раз микроконтроллер и всё! Остальную работу можно полностью делать в ПО хоста на C# (в программе на компьютере), а именно – управлять регистрами микроконтроллера напрямую, записывать и считывать из них (при этом будет автоматически меняться яркость лампы). Следовательно, можно инициализировать таймеры, прерывания, порты, АЦП из ПО хоста точно так же, как это делают программисты-железячники в firmware для микроконтроллера, причем на этот раз ничего не нужно перепрошивать.
Пример из статьи [1] заработал, научился читать\записывать в любой порт нолики и единички, читать\записывать регистры микроконтроллера, а также опробовал чтение АЦП и вывод ШИМ на ножку OC1.A (PD5).
В микроконтроллере ATmega16 (ATmega32) имеется 4 аппаратных канала ШИМ (OC0 порт PB3, OC1A порт PD5, OC1B порт PD4, OC2 порт PD7), из которых один (OC1B порт PD4) использовать не получится, потому что он задействован для сигнала DATA- USB. При желании его можно освободить, если поменять номер ножки порта в файле Firmware\usbconfig.h, строка #define USB_CFG_DMINUS_BIT 4, перекомпилировать код и перепрошить микроконтроллер, но я не стал с этим разбираться.
В тестовом устройстве подключил мощный RGB светодиод к соответствующим ножкам ШИМ и поигрался оттенками цветов светодиода. В программе было задействовано 3 канала ШИМ, для чего потребовалась доработка оригинального класса-обертки ATMega16.cs на C# из [1]. Макетную плату дополнил повторителями на полевых транзисторах N-MOSFET, и вот что из этого получилось:
Схема была проверена на тестовом ПО (далее описание элементов интерфейса программы сверху вниз):
• Set color – вызываем стандартную палитру цветов, и задаём оттенок на светодиоде. Полученные значения R, G, B в диапазоне [0x00 … 0xFF] без преобразований записываются в регистры ШИМ микроконтроллера. • Ползунки R, G, B меняют текущее значение каждого из цветов на светодиоде. • Beauty – организован примитивный random для трех значений цветов и плавное перетекание, с задержкой, из старого значения в новое. • Delay – собственно та самая задержка, один шаг (значение) меняется за X миллисекунд. • Bright – яркость. Каждое из значений цвета умножалось на 10/bright, на минимальных значениях можно наблюдать резкие шаги “переливания” цветов. • Timer 255 – ВКЛ\ВЫКЛ таймера, который считает от 0x00 до 0xFF и обратно, и выводит текущее значение в двоичном коде на одну из шин микроконтроллера. • ADC Read – чтение текущего значения АЦП на канале 0.
[Software - ПО хоста]
После прочтения статей [2, 3] решил сделать свой бар с блэкджеком и шлю... свою лампу :).
Примечание: ИМХО [2] – хороший проект, но не понравился сложный конструктив крепления светодиода, так и реализация связи между лампой и компьютером. Понравилась реализация функций программы. [3] – слишком примитивная реализация, нет связи с ПК, но полностью автономная.
После тестирования программы выявились недостатки и недоработки при использовании лампы в повседневной жизни. Например, если отключить лампу от USB и подключить обратно, то запущенная управляющая программа переставала видеть USB-устройство лампы. Другая проблема - после выхода компьютера из спящего режима при включенной программе\лампе - лампу программа находила, но так как питания по USB на лампе во время спящего режима нет, то инициализация таймеров (ШИМ) и портов ввода/вывода сбрасывалась, что в программе не учитывалось - это тоже было исправлено.
Программное обеспечение состоит из шести основных блоков, как показано на диаграмме:
Последний блок взаимодействует уже непосредственно с драйвером для Лампы Настроения. USB Device – это ATmega16 (или ATmega32), с прошивкой, основанной на V-USB (подробнее см. [6]).
Алгоритм работы программы разбит на два функциональных блока: основной и вспомогательный.
Основной блок: • Загрузка\Сохранение конфигурации. • Поиск устройства при старте программы. • Сообщения в трее Windows. • Генерирование пакетов данных на для отображения текущего просчитанного оттенка цвета. • Модели генерирования цвета\оттенка. • Работа с USB. • Запуск работы вспомогательного таймера (выход из режима сна, восстановление подключения лампы) при надобности.
Вспомогательный блок программы работает на программном таймере только тогда, когда не обнаружена лампа. После восстановления программного подключения к лампе будет заново произведена инициализация микроконтроллера и остановлена работа таймера.
Немного комментариев по исходным кодам, показаны изменения в файле atmega1632_usb.cs относительно оригинального класса-обертки ATMega16.cs (в оригинале по ссылке [1] файл модуля класса-обертки назывался ATMega16.cs):
// новая переменная private usb_device* currentdev; // динамическое отслеживание устройства USB public bool IsOpenDev(); // поиск устройства USB public bool ATMegaSearch(ushort vid, ushort pid); /* Здесь также опущены добавленные адреса регистров и функции для работы с ними, которые отсутствовали в оригинале [1]. */
Отправка данных цвета светодиодов работает примерно так (здесь код в листинге максимально упрощён):
////////////////////////////////////////////////////////////// // Процедура отправки данных в USB-устройство public void SendToDev() { // проверяем - открыто ли USB-устройство? if (!dev.IsOpenDev()) { // если нет – выставляем глобальный флаг DevReady = false; notifyIcon1.ShowBalloonTip(400, "Ошибка", "USB Лампа Настроения не найдена!", ToolTipIcon.Error); timer1.Start(); // таймер, запускающий поиск USB-устройства } else { // проверяем готовность устройства (не был ли режим сна) if (dev.PINA != 0x10) InitPWM(); // если да – инициализируем USB-устройство // (порты, прерывания, ШИМ, таймеры и т.п.) if (DevReady) { // если готов - принимай данные dev.OCR1AL = Colors[0]; dev.OCR2 = Colors[1]; dev.OCR0 = Colors[2]; } } } ////////////////////////////////////////////////////////////// // Таймер запускает процедуру поиска USB устройства private void timer1_Tick(object sender, EventArgs e) { CheсkUSBDev(); } ////////////////////////////////////////////////////////////// // Тут проверяем, есть ли подходящий USB-девайс, и если есть, // инициализируем его public void CheсkUSBDev() { if (dev.ATMegaSearch(vid, pid)) { // заново инициализация портов, таймеров в МК DevReady = true; InitPWM(); // выключаем таймер цикличного поиска Timer1.Stop(); } }
При запуске программы строка PORTA = 0x10 разблокирует работу ШИМ повторителей на IRFL9014, и устройство будет готово к работе.
Внешний вид последней версии программы:
Возможности программы: • Умеет сидеть в трее • Можно выбрать один из 6-ти режимов работы лампы • Можно регулировать Яркость и Скорость смены цвета • Есть установка постоянного оттенка из палитры • Есть точная настройка в консоли каналов R, G, B • Имеется Сохранение и Загрузка последнего состояния и настроек программы в файл settings.ini • Автоматическое определение подключения и отключения лампы, немедленно происходит запуск последнего режима при загрузке программы \ подключении лампы • Выводятся сообщения в трее о событиях или ошибках
Описание режимов работы лампы: • "Random" - генерируется случайный цвет, и к нему переходит свечение RGB-светодиода (с плавным изменением от текущего состояния) • "RandomAlt" - тоже самое, но с одним различием - перетекаем последовательно по каждому из каналов, сначала R, потом G и в конце B • "HSV Model" - изменяются по кругу все яркие оттенки HSV модели цветов • "Pulse RGB" - пульсирующий цвет, по кругу R, G, и B • "PulseRandom" - пульсирующий случайный оттенок • "PulseWhite" - пульсирующий белый
Назначение файлов исходного кода программы из архива [5], папка !software\USB Mood Lamp\:
AboutForm.cs – форма “О Программе” atmega1632_usb.cs – класс, описывающий микроконтроллер, и функции работы с LibUSB драйвером ConsoleForm.cs – форма “Консоль”, показывающая текущие настройки цифрами, и позволяющая настроить яркость каждого из каналов csINI.cs – Open Source библиотека - дополнение к Visual Studio, для простой работы с ini-файлами MainForm.cs – форма “Настройки” PWM.cs – все модели генерирования оттенков цвета Settings.cs – класс для работы с настройками USBWork.cs – функции для работы с USB
Скрипт-файл для создания установщика на основе скомпилированной программы написан для Inno Setup. Все имеется в архиве [5]. Если в системе Windows не установлена библиотека LibUSB и драйверы, то программа не запустится (вылетает с ошибкой при попытке обращения к LibUSB). Поэтому сначала надо подключить запрограммированную макетную плату (Лампу), и установить на неё драйвера. Драйвера можно взять из архива [5], или скачать последнюю возможную версию с официального сайта [4].
Примечание: программа явно не пример хорошего кода (реализации идеи), прошу не пинать за это. C# знаю еще не очень хорошо, только начинаю осваивать этот язык. И что самое главное – я больше железячник, чем программист, но стараюсь накапливать знания во всём :)!
[Hardware & firmware]
На уровне железа устройство функционально разделено на четыре основных блока:
Полная схема, далее пояснения по её блокам:
1. Стандартная схема V-USB подключения микроконтроллера к компьютеру. 2. Собственно сам микроконтроллер ATmega16 (или ATmega32). Кварц на 16 МГц, АЦП подключен к питанию через фильтр RC - несмотря на то, что не используется вообще. Разъём для программирования не показан. 3. Схема-защёлка для ШИМ-повторителей. 4. ШИМ-повторители с RC-фильтрами на входе.
Примечание: RC-фильтр понадобился из-за особенностей работы Fast PWM режима AtMega32\16. Без фильтра мне так и не удалось добиться отсутствия слабого свечения светодиода при значениях во всех регистрах OCR=0. Если не инвертировать выходной сигнал ШИМ, и применить RGB-светодиод с общим анодом и полевые транзисторы N-типа, то проблемы со слабым свечением не возникает, и RC-фильтры не нужны.
Печатная плата выполнена по популярной в определенных кругах лазерно-утюжной технологии, в одностороннем варианте, с использованием SMD компонентов. Резисторы R12, R13 используются как перемычки на плате. RC-цепочки R15C7R18, R16C8R19, R17C9R20 используются как фильтры кратковременных импульсов, от которых я не смог избавиться при работе ШИМ в инвертированном режиме.
Первоначальный вариант платы в Sprint Layout v4.0:
Переразведённый вариант в Altium Designer:
Примечание: первый вариант печатной платы делался в Sprint Layout, и схема была только в голове, поэтому возможны ошибки или неточности при переносе в Altium Designer. Плата в разводке Altium Designer еще НЕ была собрана и протестирована.
[Конструкция лампы настроения]
В качестве корпуса выбрана лампа Grono от IKEA. Она имеет красивый матовый корпус и нишу внизу, удобную для размещения управляющей платы. Внутри лампа выглядит так:
Мощный 3-ваттный RGB-светодиод крепится на радиаторе, который в свою очередь зажимается оригинальными усиками крепления удаленной лампы накаливания (поэтому вообще не требуется никаких болтов или клея).
Провода от платы до RGB-светодиода проходят в пазах крепления удаленной лампы накаливания, взамен старого провода на 220 вольт.
Плата имеет форму круга, с выступом под разъем MiniUSB на месте провода на 220 вольт в оригинальном конструктиве лампы. Крепление платы осуществляется одним болтом, который насквозь проходит через крепление для лампы, и внутри светильника прикручивается гайкой с шайбой.
Вид на разъём MiniUSB собранной лампы:
Процесс сборки лампы:
Готовая лампа днём:
Вечером и ночью смотрится намного эффектнее и ярче. Через открытую верхнюю часть лампы также проходит свет, и можно наблюдать красивую игру света и тени на потолке.
[Вместо заключения]
Есть идея дополнить лампу режимом привязки к музыке. Можно использовать библиотеку NAudio или другую, но к сожалению у меня руки так и не дошли до реализации.
Лампу можно построить и на ATmega8. Модуль класса для него был написан по подобию класса для ATmega16\32, в нем содержатся адреса регистров из даташита ATmega8 (см. файл atmega8_usb.cs). Для ATmega8 была немного переписана программа для ПО хоста. Конструкция была успешно опробована на макетной плате.
Сейчас изучаю AT90USB162 (микроконтроллер с аппаратным интерфейсом USB) и делаю Лампу Настроения v2.0 с расширенным функционалом. Прошивка firmware будет сделана на основе USB HID библиотеки LUFA. Планируется:
• При необходимости – автономная работа, без ПК. • Пульт с ... акселерометром/гироскопом. • 10-ваттный RGB-светодиод. • Блок питания на 12v. • Новые функции при работе от ПК.
Первая макетная платка на чипе AT90USB162:
P.S. Лампа изготавливалась как хенд-мейд подарок одному прекрасному человеку, и никакой коммерческой выгоды не преследовалось.
[Ссылки]
1. AVR-USB-MEGA16: измеряем и контролируем температуру. 2. Создание USB-гаджета с нуля или еще одна лампа настроения site:habrahabr.ru. 3. Лампа настроения! site:habrahabr.ru. 4. libusb-win32 site:sourceforge.net. 5. 110802usb-mode-lamp.ZIP - исходные коды и бинарники, драйвер, фотографии, схема, прошивка, печатная плата. 6. Projects Based on V-USB site:obdev.at - проекты, которые основаны на V-USB. |
Комментарии
К сожалению, в магазинах и на радиорынке был найден мощный RGB светодиод только с общим катодом. Логичнее же - как Вы и написали, сделать схему на светодиоде с общим анодом.
Для изучения МК в целом на мой взгляд, AVR прекрасно подходит по двум вещам: простота (как пайки корпуса, так и в плане программировани я) так и их распространённо сть. Вы попробуйте не в столице поискать STM (я к примеру из Краснодара), не найдете. Только заказывать (а это время).
И конечно же, как Вам ранее написали - V-USB библиотека и совместимость (обилие примеров) с высокоуровневым и языками (в данном случае C#). И зачем STM с навороченным USB аппаратным, когда с головой хватает софтового USB 1.1?
А из-за цены только одного МК переделывать все, нагромоздив себе же кучу граблей... это на мой взгяд глупо.
microsin: как я уже писал (повторять написанное в прошлом комментарии не буду) - дело, увы, не только в цене. Дайте мне для STM32 удобные примеры кода для построения USB-устройств на аппаратном USB - буду с радостью STM32 использовать, даже если они будут дороже. Пока что рулят только чипы от Atmel, благо для них есть библиотеки V-USB и LUFA.
microsin: откуда Вы берете такие цены? Наверное в недо-Чипе? ATmega32 в России стоит не дороже 60 рублей, а где дороже - там накрутка. Чип STM не применен по той простой причине, что для него нет таких замечательных примеров кода, как для ATmega32 (нет библиотеки V-USB). Так что Cortex-ам еще есть куда расти.
RSS лента комментариев этой записи