RGB люстра с нуля

igreemi
Offline
Зарегистрирован: 28.09.2015

Здравствуйте. Появиласть такая задумка, из старой гитары сделать люстру. В наличии имеются rgb светодиоды с общим катодом, сама гитара и свободный бп на 12вольт. С адруино ни разу не сталкивался, почитал форум, вроде возможностей у него много.
Хотелось бы сделать что то интересное)
По задумке световые переливания по гитаре с изменением цвета, управление с ик пульта и реагирование на музыку.
Что посоветуете приобрести и с чего начать?

std
Offline
Зарегистрирован: 05.01.2012

Если охота смену эффектов под бочку (туц туц), то 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й смд. Может отпугнуть, да и моща меньше, но это я так... Мне уже настолько лень сверлить плату, что я даже обычные резисторы с выводами припаиваю туда прямо так.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

std пишет:

1 кГц, что выше ардуинного родного на порядок

Прям-таки на порядок? :))))))))))

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

igreemi пишет:
...почитал форум, вроде возможностей у него много...

много, но это как любым инструментом нужно учиться пользоваться

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

std
Offline
Зарегистрирован: 05.01.2012

ЕвгенийП, у кого-то на EE подпись на эту тему, которая мне очень нравится: в МК "на порядок" значит - в два раза :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

))) выкрутился

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

std пишет:

ЕвгенийП, у кого-то на EE подпись на эту тему, которая мне очень нравится: в МК "на порядок" значит - в два раза :)

Не, МК это слишком мелко. В любом двоичном компьютере, т.к. в двоичной системе так и есть. Сдвиг влево на 1 (порядок) и есть умножение на 2 :))))

igreemi
Offline
Зарегистрирован: 28.09.2015

Ну я для начала заказал ардуино уно, модуль с микрофоном и инфракрасный модуль с пультом. Насколько понял, это все можно увязать в одно. Меня вот что интересует, где то на просторах ютуба видел как подключили обычную ргбшную ленту, судя по подключению всего к контакта rgb и общий анод\катод и она светилась всеми цветами радуги, плавно меняя цвет по всей ленте. Это реально?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

igreemi пишет:
Ну я для начала заказал ардуино уно, модуль с микрофоном и инфракрасный модуль с пультом. Насколько понял, это все можно увязать в одно. Меня вот что интересует, где то на просторах ютуба видел как подключили обычную ргбшную ленту, судя по подключению всего к контакта rgb и общий анод\катод и она светилась всеми цветами радуги, плавно меняя цвет по всей ленте. Это реально?
Вас в гугле забанили? http://cxem.net/beginner/beginner61.php

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
igreemi
Offline
Зарегистрирован: 28.09.2015

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

На практике пока поковырять не могу, т.к. не на чем пока)

З.Ы.- у меня диоды с общим катодом, как схему переделать, чтоб не плюс а минус был общим?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

у тебя просто светодиоды или с драйверами?

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

igreemi
Offline
Зарегистрирован: 28.09.2015

Просто светодиоды, R-2.5, G-3.5, B-3.5 и общий катод. Цвет формируется за счет разного напряжения на каждом из цветов. Вообщем обычный ргб сд

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

и как ты планируешь управлять? драйвер ставить или от шим ардуины?

просто если от шим ардуины, и каждый светодиод должен отдельно светится, то это глупо. для 10 светодиодов нужно 30 каналов шим

igreemi
Offline
Зарегистрирован: 28.09.2015

Так вот мне и нужен совет) если лучше драйвер ставить, то дозакажу драйвер, там же управление все равно через ардуинку будет, я правельно понял?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

купи готовую ленту с драйверами

igreemi
Offline
Зарегистрирован: 28.09.2015

К сожалению готовая лента не подходит, т.к. светодиоды будут стоять непосредственно в корпусе гитары, а снаружи будут рассеиватели.Объем работ меня не пугает) вечером скину примерный набросок того что должно получиться в итоге)

Нашел вот такой на али Arduino STM32 AVR FZ1568, но у него анод общий и еще некий colorduino v.2

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
igreemi
Offline
Зарегистрирован: 28.09.2015

Слишком громоздко) у меня рассеиватели диаметром 8мм, отверстие под светодиод 6мм, да и "буриться" сквозь гитару сантиметровыми дырками не хотелось бы, а то от нее ничего не останется)

igreemi
Offline
Зарегистрирован: 28.09.2015

Хотя наверно так и сделаю, закажу готовые, штук 50. К ним кроме ардуинки нужно будет еще что нибудь для управления?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

неа. разве что питание

igreemi
Offline
Зарегистрирован: 28.09.2015

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

igreemi
Offline
Зарегистрирован: 28.09.2015
[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]

пример сработки реле по команде из консольки

 

igreemi
Offline
Зарегистрирован: 28.09.2015

[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

igreemi
Offline
Зарегистрирован: 28.09.2015

[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]

пока не даю пуск на ленту, релюхи работают по команде, как только пуск на ленту даю, все, перестает реагировать на команды)

igreemi
Offline
Зарегистрирован: 28.09.2015

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

З.Ы. - принятие команд с серийного порта хотелось бы оставить.

#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();
}

 

igreemi
Offline
Зарегистрирован: 28.09.2015

хЕлП мИ)