История одной случайной поделки

Доброго всем дня!

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

Работа над внешним видом

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

У этих деревях будет вторая жизнь!У этих деревях будет вторая жизнь!

Имея в качестве исходного материала данные бруски было решено разделить ими световые дорожки из эпоксидной смолы. Должно было получиться что-то типа этого:

Первоначальный проект внешнего видаПервоначальный проект внешнего вида

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

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

Болванка со световодами из эпоксидной смолы после фрезеровкиБолванка со световодами из эпоксидной смолы после фрезеровки

Электроника

Самый простой и быстрый путь доделать светильник — воткнуть по светодиоду на каждую дорожку и готово. Просто и крайне бюджетно. А можно немного заморочиться и сделать более веселую динамичную подсветку. Например, воткнуть RGBW светодиоды и рули как хочешь. Осталось придумать, как это реализовать минимальными финансовыми усилиями. С источниками света все достаточно просто: купил три RGBW светодиода SK6812RGBW-NW с пиксельной адресацией (4000–4500K). А вот при выборе контроллера немного замялся. Изначально, использовать контроллеры Atmel или того хуже готовые платки на их основе (аля ардуино) мне не позволяла «религия». Скажу сразу, что это не просто из принципа. Раньше я сам использовал Atmel, но это было реально очень давно… Лет 20 назад. У меня это были первые процы с перепрограммируемой Flash памятью! После микросхем ROM с УФ-стиранием это было чудо! Но время шло… Мир менялся. Появились другие интересные камни. И мне пришлось отойти от Atmel в первую очередь по причине возникших вопросов к их надежности и убогости неудобства средств разработки. Но на мгновение я наступил себе на горло подумал, что вдруг они сейчас продаются по цене пыли под ногами. Ан нет! Даже наипростейший Tiny85 стоит дороже малюсенького ARMа STM32F030F4P6! А они и рядом не стояли! Плюс среда разработки для AVR даже близко не сравнится с IAR или Keil. Короче выбор был очевиден — STM32F030F4P6. Причем в данном случае выбор основывался не на возможностях камней (для такой задачи пойдет любой), а чисто на финансовой составляющей. За 120руб (на тот момент, но сейчас момент упущен) я получил 32-Бит, Cortex-M0, 48МГц, 16КБ Flash и возможность бесплатно вполне законно работать в нормальной среде Keil (там официальное ограничение на генерацию кода не более 32Кб).

На основе этого камня я сделал для себя платку для будущих «мелких» проектов.

Схема простенькой управлялки  для светильникаСхема простенькой управлялки для светильника

Здесь всё крайне примитивно. Только линейник для питания проца, 5-вольтовый преобразователь уровня на пару линий (изначально девайс задумывался именно для управления адресными светодиодами) и «Hello world» светодиод. Резонатора нет, только внутреннее тактирование. Почти все свободные ноги на всякий случай вывел на внешний разъем. Получилось достаточно компактно и дешево.

Смонтированный контроллер светильникаСмонтированный контроллер светильника

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

Вот что получилось по платкам для светильникаВот что получилось по платкам для светильника

Механика

Чтобы спрятать все сопли и придать светильнику эстетичный вид надо было что-то придумать с оформлением сего девайса. А поскольку я в этом деле (конструкторском) не настоящий сварщик, то взял бесплатный FreeCAD и сваял парочку несложных деталек.

651caec0c94c2b977b708a6c58cac3c2.jpg

В собранном виде часть излучающей подставки выглядит так:

Вид со стороны излучателейВид со стороны излучателейНе самая привлекательная часть светильникаНе самая привлекательная часть светильника

С механикой пока все. Теперь во все это необходимо вдохнуть жизнь.

Программа

Самое главное, что требовалось сделать в первую очередь — это научиться управлять светодиодами. При этом управление должно быть по возможности «в фоне» и не мешать выполнению «логики» программы. Если все получится, то можно двигаться дальше.

В светильнике я решил использовать адресные светодиоды SK6812RGBW. У них кроме RGB светодиодов есть еще отдельный белый. Нужен он или нет — вопрос второй. Просто хотелось. А получить нормальный белый цвет просто мешая RGB ну никак не получится.

У выбранного светодиода управление осуществляется по одной линии (если понадобится, то плата физически может поддерживать адресные светодиоды с управлением и по двум линиям):

85b8a4003b6d28a74afef0dd493f99f8.png

Кодирование нужного состояния (»0» или »1») зависит от ширины высокого и низкого состояния линии управления.

14ddbf40e8552dfd3f09550e16364538.png

Необходимо лишь соблюсти эту временную диаграмму. Легко сказать. Понятное дело, что «ногодрыганье» в моем случае полная утопия. Именно поэтому, еще на этапе подготовки «железки» было решено выделить для этой цели линии SPI. Это аппаратный блок микроконтроллера и, к тому же, достаточно быстрый для данной задачи. Но неуверенность оставалась. Проведя поиск идей в инете и поняв, что мне ничего не подходит, я с чистой совестью принялся ваять драйвер самостоятельно. Извиняюсь, слишком громко сказано. Принялся ваять нечто, что позволит вывести на три адресных светодиода нужную мне информацию.

Если коротко, то получилось следующее:

  • были подобраны настройки PLL и SPI так, чтобы ширина бита данных SPI (MOSI) была 0.1uS. Используя это значение легко сделать необходимые величины для протокола обмена с SK6812 (0.3uS, 0.6uS, 0.9uS)
    SK6812:»0» — 1(0.3uS)+0(0.9uS)
    »1» — 1(0.6uS) + 0(0.6uS)

  • кодировка одного бита для протокола управления SK6812 по времени занимает 1.2uS. Для получения этой ширины надо передать по времени 12 бит по протоколу SPI (с текущей настройкой).

  • получается для передачи пакета управления одним SK6812W (32 бита) надо передать 32×12 = 384 бита (48 байт → 24 слова). У нас 3 светодиода, поэтому надо зарезервировать 24×3 = 72 слова +1 — стартовый ноль +1 — финишный ноль, чтобы линия данных по завершении передачи осталась в нуле (надо обеспечить RESET состояние). В результате получается для управления 3 RGBW светодиодами необходимо зарезервировать 74 слова памяти.

  • для быстрой пересылки «в фоне» подготовленных данных из массива памяти в SPI был настроен канал DMA.

В результате я получил простую в использовании процедуру, на которую не влияют никакие внешние факторы (например, прерывания), которые могут сбить синхронизацию при пересылки инфы на светодиоды. Да, она съела много ОЗУ в качестве временного хранилища, но в данном случае это не критично.

Вот что надо сделать для обновления информации на трех каналах девайса:

Color_LED1 = 0xFF000000;
Color_LED2 = 0x00FF0000;
Color_LED3 = 0x0000FF00;
Refresh_LED();

Таким образом кодируется информация для светодиодовТаким образом кодируется информация для светодиодов

В данном примере на LED1 включится зеленый цвет, на LED2 — красный, а на LED3 — синий. За белый отвечает самый младший байт. В данном примере он не используется.

Процедура обновления информации на светодиодах формирует тот самый временный массив для SPI и запускает канал DMA. Все остальное — не наша забота. Все делается аппаратно.

void Refresh_LED (void)
{
	// новая информация по светодиодам
	// содержится в переменных:
	// Color_LED1 (32 бита)
	// Color_LED2 (32 бита)
	// Color_LED3 (32 бита)
	
	// подготовка массива к передаче
	// длительность 280uS
	PrepareColorData();   
	
	// подготовка канала DMA к передаче
	// физическая длительность передачи 120uS
	DMA1_Channel3->CCR &=~ DMA_CCR_EN;
	DMA1_Channel3->CNDTR = LED_DATA_BUFFER_SIZE;
	DMA1_Channel3->CCR |= DMA_CCR_EN;				
	
	// общее время обновления информации 280uS. 
	// Тратится только на подготовку массива. 
	// Передача идет в фоне и на общее время 
	// обновления не влияет
}

56d10c91c884201928891156b4784e36.gif

Промежуточный результат меня вполне устроил. Главное, что все работало так, как я предполагал. Оставалось только дописать управляющую логику да собрать наконец все до кучи. Кстати, в процессе сборки встал вопрос из чего сделать симпатичный контакт для датчика касания. Тут я не стал долго думать, а взял обыкновенный декоративный гвоздь для обивки двери да и «вбил» его в корпус. Получилось вполне симпатично.

Вот, что в результате у меня получилось:

Файлы проекта: электроника, механика, софт.

Спасибо за то, что дочитали до конца!

© Habrahabr.ru