RGB люстра с нуля
- Войдите на сайт для отправки комментариев
Пнд, 28/09/2015 - 01:34
Здравствуйте. Появиласть такая задумка, из старой гитары сделать люстру. В наличии имеются rgb светодиоды с общим катодом, сама гитара и свободный бп на 12вольт. С адруино ни разу не сталкивался, почитал форум, вроде возможностей у него много.
Хотелось бы сделать что то интересное)
По задумке световые переливания по гитаре с изменением цвета, управление с ик пульта и реагирование на музыку.
Что посоветуете приобрести и с чего начать?
Если охота смену эффектов под бочку (туц туц), то 2 способа:
1. Если лень делать, покупаем датчик звукового давления. Там микросхема, микрофон и рещистор, синий такой. Расплата - будет срабатывать если кто-то хлопнет дверью, сквозняк и т. п. Короче, давление бывает не только звуковое.
2. Если не лень, собирается предусилитель с фильтром, с нормальным разъёмом стерео. Даже можно отдельную ардуину приспособить под FFT, но это долгая тема и я упоминаю чисто из академических соображений.
Далее вступает количество модулируемых каналов, по одному на цвет. Из коробки дуина имеет 6 PWM выходов, причём по два на каждый из имеющихся у неё трёх таймеров (два 8-разрядных и один 16-разрядный). То есть подключите библиотеку IRRemote для пульта, она забирает себе вроде таймер T0 (или T1, хз), то есть два выхода станут из PWM обычными дискретными. Решений опять же два:
1. Настоящий PWM. Микросхемы типа TLC5940 и т. п. Плюсы - частота ШИМ 1 кГц, что выше ардуинного родного на порядок (но там возможно и побыстрее, если знать регистры процессора), а также на многих есть встроенный драйвер тока для светиков, то есть можно цеплять ленту прямо к ногам. Там же и защита от превышения тока, удобно. Минус - минимум 4 юаня за микруху.
2. BAM (binary angle modulation), разновидность программной модуляции, которая "почти ШИМ". Делается на сдвиговых регистрах (74595). Плюсы - регистр стоит 35 фэней, то есть за те же ~4 юаня будет не 16 каналов а 192 (сто девяносто два). Минус - требует определённое время процессора, т. о. программа не бесконечная. Существует приемлемый баланс.
Остальное думаю по ходу работы будет ясно, ну или появятся более конкретные вопросы.
Да, дешёвые транзюки с низким Rds(on) - IRFZ48N, IRFR024N, как раз для этих целей - выдерживают десятки вольт, коммутируют без радиатора единицы ампер, управляются уровнями, близкими к 5 В. Собсно. понимают от 4 В. 024й смд. Может отпугнуть, да и моща меньше, но это я так... Мне уже настолько лень сверлить плату, что я даже обычные резисторы с выводами припаиваю туда прямо так.
1 кГц, что выше ардуинного родного на порядок
много, но это как любым инструментом нужно учиться пользоваться
хоть и упростили сильно, и на ардуине много чего можно сделать намного быстрее чем на любой другой платформе, но все равно обезьяна с зоопарка на ардуине комп не соберет, голова очень нужна
ЕвгенийП, у кого-то на EE подпись на эту тему, которая мне очень нравится: в МК "на порядок" значит - в два раза :)
))) выкрутился
ЕвгенийП, у кого-то на EE подпись на эту тему, которая мне очень нравится: в МК "на порядок" значит - в два раза :)
Ну я для начала заказал ардуино уно, модуль с микрофоном и инфракрасный модуль с пультом. Насколько понял, это все можно увязать в одно. Меня вот что интересует, где то на просторах ютуба видел как подключили обычную ргбшную ленту, судя по подключению всего к контакта rgb и общий анод\катод и она светилась всеми цветами радуги, плавно меняя цвет по всей ленте. Это реально?
http://arduino.ru/forum/programmirovanie/ws2812-kak-realizovat-indikatsiyu
Это я видел, я пока не могу понять какреализовать, чтоб на одной ленте менялись цвета сд от первого к десятому скажем. По принципу бегущей строки, т.е. первый светодиод красный и он изменяя цвета должен дойти до последнего оставляя след.
На практике пока поковырять не могу, т.к. не на чем пока)
З.Ы.- у меня диоды с общим катодом, как схему переделать, чтоб не плюс а минус был общим?
у тебя просто светодиоды или с драйверами?
для того что ты хочешь нужно вообще разобраться как формируются цвета, без этого тяжело тебе будет
Просто светодиоды, R-2.5, G-3.5, B-3.5 и общий катод. Цвет формируется за счет разного напряжения на каждом из цветов. Вообщем обычный ргб сд
и как ты планируешь управлять? драйвер ставить или от шим ардуины?
просто если от шим ардуины, и каждый светодиод должен отдельно светится, то это глупо. для 10 светодиодов нужно 30 каналов шим
Так вот мне и нужен совет) если лучше драйвер ставить, то дозакажу драйвер, там же управление все равно через ардуинку будет, я правельно понял?
купи готовую ленту с драйверами
К сожалению готовая лента не подходит, т.к. светодиоды будут стоять непосредственно в корпусе гитары, а снаружи будут рассеиватели.Объем работ меня не пугает) вечером скину примерный набросок того что должно получиться в итоге)
Нашел вот такой на али Arduino STM32 AVR FZ1568, но у него анод общий и еще некий colorduino v.2
тогда купи это
http://ru.aliexpress.com/item/10pcs-WS2811-IC-Built-in-WS2812B-ws2812-28...
Слишком громоздко) у меня рассеиватели диаметром 8мм, отверстие под светодиод 6мм, да и "буриться" сквозь гитару сантиметровыми дырками не хотелось бы, а то от нее ничего не останется)
Хотя наверно так и сделаю, закажу готовые, штук 50. К ним кроме ардуинки нужно будет еще что нибудь для управления?
неа. разве что питание
Дурацская почта. Вообщем пришел только минимальный набор. Поэтому буду ломать то что есть) вообщем цель на данном этапе такая, есть ардуина уно, светодиоды с драйверами и плата с двумя реле. Попробывал готовые скетчи, все ок, все работает, но не могу допереть как объединить скетчи и сделать сработку командами с пк.
Скажем так, одна команда должна запускать скетч для светодиодов, и по одной команде на включение/выключение двух релюх
[code] byte relay1 = 2; //объявление переменных для управлением реле и указание PINа подключения byte relay2 = 3; //тип byte, поскольку реле принимает два значения (0 или 1) int val; //переменная для хранения значения, присылаемого в Serial void setup() { //функция начальной настройки микроконтроллера (вызывается едноразово, при подаче питания) Serial.begin(9600); //инициализируем Serial порт на работу со скоростью 9600 бод pinMode(relay1, OUTPUT); //PIN2 реле №1 работает как выход digitalWrite(relay1, HIGH); //поддержание высокого уровня на выходе (реле выключено) pinMode(relay2, OUTPUT); //аналогично для реле №2..3..4 digitalWrite(relay2, HIGH); } void loop() { //циклическая функция if(Serial.available() > 0){ //если что-то пришло в Serial-порт val = Serial.parseInt(); //то записать это значение в переменную val switch(val){ //проверяем содержимое val case 11: //если пришел код 11 digitalWrite(relay1, LOW); //то включить реле 1 break; //выйти из switch case 10: //если пришел код 10 digitalWrite(relay1, HIGH);//то выключить реле 1 break; //выйти из switch //далее аналогично реле №1 case 21: digitalWrite(relay2, LOW); break; case 20: digitalWrite(relay2, HIGH); break; } //скобка закрытия switch } //скобка закрытия проверки Serial-порта } //закрытие циклической функции loop [/code]пример сработки реле по команде из консольки
[code] #include "Ai_WS2811.h" #define NUM_PIXELS 3 #define DATA_PIN 8 Ai_WS2811 ws2811; struct CRGB { unsigned char g; unsigned char r; unsigned char b; } *leds; //some initial values void setup() { ws2811.init(DATA_PIN,NUM_PIXELS); leds = (struct CRGB*)ws2811.getRGBData(); } void loop(){ rainbow(); } /** * Color climb function **/ void rainbow(){ while(1) { for(int i = 255; i >= 0; i--) { int val = i; for (int led = 0; led < NUM_PIXELS; led++) { val = (val + 255/NUM_PIXELS) % 255; setHue(val, led); } ws2811.sendLedData(); delay(100); } } } /** * HVS to RGB comversion (simplified to the range 0-255) **/ void setHue(int h, uint8_t n) { //this is the algorithm to convert from RGB to HSV double r=0; double g=0; double b=0; double hf=h/42.5; // Not /60 as range is _not_ 0-360 int i=(int)floor(h/42.5); double f = h/42.5 - i; double qv = 1 - f; double tv = f; switch (i) { case 0: r = 1; g = tv; break; case 1: r = qv; g = 1; break; case 2: g = 1; b = tv; break; case 3: g = qv; b = 1; break; case 4: r = tv; b = 1; break; case 5: r = 1; b = qv; break; } leds[n].r = constrain((int)255*r,0,255); leds[n].g = constrain((int)255*g,0,255); leds[n].b = constrain((int)255*b,0,255); } [/code]а это то что нужно вживить к релюхам)
тоесть надо как то сделать по принципу работы реле, я отправляю команду, включается лента с эффектом готовым, при отправке команды на выключение - выключается. и соответственно оставить в работе эти два реле
ссылка на полный скетч для ленты:
http://digitrode.ru/computing-devices/mcu_cpu/164-upravlyaem-svetodiodami-ws2812-s-pomoschyu-arduino.html
[code] #include "Ai_WS2811.h" byte relay1 = 2; //объявление переменных для управлением реле и указание PINа подключения byte relay2 = 3; //тип byte, поскольку реле принимает два значения (0 или 1) byte relay3 = 8; int val; //переменная для хранения значения, присылаемого в Serial Ai_WS2811 ws2811; struct CRGB { unsigned char g; unsigned char r; unsigned char b; } *leds; void setup() { //функция начальной настройки микроконтроллера (вызывается едноразово, при подаче питания) Serial.begin(9600); //инициализируем Serial порт на работу со скоростью 9600 бод pinMode(relay1, OUTPUT); //PIN2 реле №1 работает как выход digitalWrite(relay1, HIGH); //поддержание высокого уровня на выходе (реле выключено) pinMode(relay2, OUTPUT); //аналогично для реле №2..3..4 digitalWrite(relay2, HIGH); pinMode(relay3, OUTPUT); { ws2811.init(relay3,NUM_PIXELS); leds = (struct CRGB*)ws2811.getRGBData(); } digitalWrite(relay3, HIGH); } void loop() { //циклическая функция if(Serial.available() > 0){ //если что-то пришло в Serial-порт val = Serial.parseInt(); //то записать это значение в переменную val switch(val){ //проверяем содержимое val case 11: //если пришел код 11 digitalWrite(relay1, LOW); //то включить реле 1 break; //выйти из switch case 10: //если пришел код 10 digitalWrite(relay1, HIGH);//то выключить реле 1 break; //выйти из switch //далее аналогично реле №1 case 21: digitalWrite(relay2, LOW); break; case 20: digitalWrite(relay2, HIGH); break; case 31: digitalWrite(relay3, LOW); { rainbow(); } break; case 30: digitalWrite(relay3, HIGH); break; } //скобка закрытия switch } //скобка закрытия проверки Serial-порта } //закрытие циклической функции loop void rainbow(){ while(1) { for(int i = 255; i >= 0; i--) { int val = i; for (int led = 0; led < NUM_PIXELS; led++) { val = (val + 255/NUM_PIXELS) % 255; setHue(val, led); } ws2811.sendLedData(); delay(10); } } } void setHue(int h, uint8_t n) { //this is the algorithm to convert from RGB to HSV double r=0; double g=0; double b=0; double hf=h/42.5; // Not /60 as range is _not_ 0-360 int i=(int)floor(h/42.5); double f = h/42.5 - i; double qv = 1 - f; double tv = f; switch (i) { case 0: r = 1; g = tv; break; case 1: r = qv; g = 1; break; case 2: g = 1; b = tv; break; case 3: g = qv; b = 1; break; case 4: r = tv; b = 1; break; case 5: r = 1; b = qv; break; } leds[n].r = constrain((int)255*r,0,255); leds[n].g = constrain((int)255*g,0,255); leds[n].b = constrain((int)255*b,0,255); } [/code]пока не даю пуск на ленту, релюхи работают по команде, как только пуск на ленту даю, все, перестает реагировать на команды)
пришел ик приемник. нужена помощь. подключил, тестовая программа работает корректно. принимает коды стабильно с одной кнопки одни и те же, а вот в моем скетче отказывается. начинает выдавать разные коды. подозреваю ошибку в коде, но не могу понять, что не так.
З.Ы. - принятие команд с серийного порта хотелось бы оставить.
#include "IRremote.h" #include "FastLED.h" #define NUM_LEDS 30 //количество светодиодов/микросхем #define DATA_PIN 8 //пин подключения ленты #define COOLING 55 #define SPARKING 120 #define FRAMES_PER_SECOND 60 #define RECV_PIN 11 IRrecv irrecv(RECV_PIN); decode_results results; int pos0 = 0; int pos1 = 1; int val; int start = 0; CRGB leds[NUM_LEDS];//создаем массив цветов uint8_t b_r;//значение красного цвета uint8_t b_g;//значение зеленого цвета uint8_t b_b;//значение синего цвета void setup() { Serial.begin(9600);//открываем программный сериал irrecv.enableIRIn(); // запускаем ИК приемник FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);//инициализируем управление светодиодной лентой } void loop() { if (irrecv.decode(&results)) { Serial.println(results.value); // вывод приходящих с пульта команд if (results.value == 3772790473) // если пришел с пульта код кнопки А { start ++; } irrecv.resume(); // ждем новой команды } if(start > 6) { // Если номер эффекта превышает существующее start = 0; } // то отсчет начинается с нуля if(start == 0) CLOSED(); if(start == 1) snowdown(); if(start == 2) juggle(); if(start == 3) bpm(); if(start == 4) sinelon(); if(start == 5) confetti(); if(start == 6) addGlitter(); if(Serial.available() > 0){ //если что-то пришло в Serial-порт val = Serial.parseInt(); //то записать это значение в переменную val switch(val){ //проверяем содержимое val case 3: //если пришел код 3 start ++; break; } } } uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current uint8_t gHue = 0; // rotating "base color" used by many of the patterns void CLOSED() { CRGB::Black; FastLED.show(0); } void snowdown(){ // Просто огонёк со шлейфом бегает в одну сторону fadeToBlackBy( leds, NUM_LEDS, 40); //fadeToBlackBy( leds1, NUM_LEDS, 40); pos1 = pos1+1; if(pos1 > NUM_LEDS-1) pos1 = 0; leds[pos1] += CHSV( 65, 255, 192); //leds1[pos1] += CRGB(255, 255, 255); delay(50); FastLED.show(); } void juggle(){ // eight colored dots, weaving in and out of sync with each other fadeToBlackBy( leds, NUM_LEDS, 20); byte dothue = 0; for( int i = 0; i < 8; i++) { leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255); dothue += 32; } delay(100); FastLED.show(); } void bpm(){ // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); for( int i = 0; i < NUM_LEDS; i++) { //9948 leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); } delay(200); FastLED.show(); } void sinelon(){ // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( leds, NUM_LEDS, 20); int pos = beatsin16(13,0,NUM_LEDS); leds[pos] += CHSV( gHue, 255, 192); FastLED.show(); } void confetti(){ // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); delay(10); FastLED.show(); } void addGlitter(){ if( random8()) { leds[ random16(NUM_LEDS) ] += CRGB::White; } delay(100); FastLED.show(); }хЕлП мИ)