Цветомузыка на WS2812

juraspb
Offline
Зарегистрирован: 12.12.2017

Написал к новому году цветомузыкальную программку 'ЦМУ' для персонального компьютера и скетчи для управления лентой WS2812 или аналогичными под Arduino для неё.

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

Управление лентой может осуществляться как непосредственно ардуинкой подключённой к COM порту, скетч СOMtoLEF.ino, так и через радиомост на nRF24L01, скетчи COMtoRF и RFtoLED. 

Cхемы подключения 

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

Цифровую обработку аудио потока выполняет ПК. Цветомузыкальные программы формируются ардуинками на основе данных о спектральном составе текущего фрагмента фоногаммы полученных от ПК. В цветомузыкальном режиме для формирования цветовых программ используются выходы 19 цифровых полосовых фильтров получаемых от ПК. Значения на выходе цифровых фильтров в постоянном темпе передаются персональным компьютером и содержатся в массиве readData[].

В динамическом режиме цветовые программы формируются на основании номера программы и данных о цветах и темпе полученных от ПК. Выполнение динамической программы в процессе выполнения не требует подключения к ПК. 

В программе можно выбрать одну из 6-ти цветомузыкальных программ или одну из 12-ти динамических. Реализованы в прилагаемых скетчах 3 цветомузыкальные и 6 динамические подпрограмм. Остальные программы вы можете составить сами.

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

Цветомузыкальные программы:

Радуга;

МИКС;

Двутавр;

Магия — оставлена под вашу реализацию. 

Сказка — оставлена под вашу реализацию. 

Динамика — оставлена под вашу реализацию.

Динамические программы:

1 — theaterChaseRainbow — из примеров к библиотеке Adafruit_NeoPixel;

2 — rainbowCycle — из примеров к библиотеке Adafruit_NeoPixel;

3 — мерцающие огни;

4, 5, 6 — простые варианты бегущих огней; 

7..12 — оставлены под вашу реализацию.

Также на вкладке динамические вы можете установить цвет свечения всей ленты  выбором цвета на цветном поле;



Динамические программы могут выполняться автономно, без подключения к ПК. Если вы хотите использовать контроллер ленты автономно вам будет необходимо подключить к одному или нескольким цифровым входам платы arduino кнопки, а к одному из аналоговых входов потенциометр. Кнопки будут использоваться для переключения номера программы, а потенциометр для изменения параметра программы (темп, яркость, цвет). Подключение кнопок и потенциометра к arduino можно найти в стандартных примерах. Напишите и внесите в скетч контроллера ленты код, изменяющий номер подпрограммы prog и значения параметра param, в зависимости от нажатых кнопок и положения потенциометра. Можно для переключения динамических программ использовать ИК приёмник и пульт от телевизора. Подключение ИК приёмника к arduino также можно найти в стандартных примерах.



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

Мой вариант аудио подключения.

У меня аудио ресивер с airplay и проигрыватель я естественно использую c поддержкой airplay т.е. ITUNES. Кроме того ITUNES умеет выводить звук одновременно и на аудио ресивер и на ПК как показано ниже

 

dd07cf.jpg

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

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

Творите, выдумывайте, пишите, делитесь и каждый сможет сделать такое устройство, какое пожелает. 

Всех с наступающим новым годом!!!

Демонстрационные видео работы ЦМУ в цветомузыкальном режиме:

Радуга:https://www.youtube.com/watch?v=h9zbtLpKtf0

МИКС:https://www.youtube.com/watch?v=cG75_M9zmLE

Двутавр:https://www.youtube.com/watch?v=zZWn22kSqRA

Архив: https://1drv.ms/u/s!AnhvZp98C-GCoxTsDAZT_Nmktz8Z

COMtoLED.ino

#include <Adafruit_NeoPixel.h>
 
#define ledPin 13       // светодиод на плате arduino
#define stripPin 2      // выход управления светодиодной лентой
#define stripLed 60     // количество светодиодов в ленте
#define bandPass 15     // число полос ЦМУ (используемых в программах)
#define ledDist 4
#define LedtoColor 4

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(stripLed, stripPin, NEO_GRB + NEO_KHZ800);

const uint32_t PROGMEM
  colorTab[]={
      0xFF0000,0xFF1100,0xFF2200,0xFF3300,0xFF4400,0xFF5500,0xFF6600,0xFF7700,0xFF8800,0xFF9900,0xFFAA00,0xFFBB00,0xFFCC00,0xFFDD00,0xFFEE00,0xFFFF00,  //красный - жёлтый
      0xFFFF00,0xEEFF00,0xDDFF00,0xCCFF00,0xBBFF00,0xAAFF00,0x99FF00,0x88FF00,0x77FF00,0x66FF00,0x55FF00,0x44FF00,0x33FF00,0x22FF00,0x11FF00,0x00FF00,  //жёлтый — зелёный
      0x00FF00,0x00FF11,0x00FF22,0x00FF33,0x00FF44,0x00FF55,0x00FF66,0x00FF77,0x00FF88,0x00FF99,0x00FFAA,0x00FFBB,0x00FFCC,0x00FFDD,0x00FFEE,0x00FFFF,  //зелёный — циан (голубой)
      0x00FFFF,0x00EEFF,0x00DDFF,0x00CCFF,0x00BBFF,0x00AAFF,0x0099FF,0x0088FF,0x0077FF,0x0066FF,0x0055FF,0x0044FF,0x0033FF,0x0022FF,0x0011FF,0x0000FF,  //голубой — синий
      0x0000FF,0x1100FF,0x2200FF,0x3300FF,0x4400FF,0x5500FF,0x6600FF,0x7700FF,0x8800FF,0x9900FF,0xAA00FF,0xBB00FF,0xCC00FF,0xDD00FF,0xEE00FF,0xFF00FF,  //синий — пурпур (маджента)
      0xFF00FF,0xFF00EE,0xFF00DD,0xFF00CC,0xFF00BB,0xFF00AA,0xFF0099,0xFF0088,0xFF0077,0xFF0066,0xFF0055,0xFF0044,0xFF0033,0xFF0022,0xFF0011,0xFF0000}; //маджента — красный

typedef union{
    struct {
      uint8_t b,g,r,w;
    };
    uint32_t dw;
} TColor;

typedef union{
    struct {
      uint8_t b0,b1;
    };
    uint16_t w;
} TWord;

uint8_t inCounter = 0;
boolean inComplete = false;
char prog = '2';
uint8_t param = 5;
uint8_t progStep = 0;
uint8_t progDir = 0;
TColor clN[5] = {{255,0,0,0},{0,255,0,0},{0,0,255,0},{0,255,255,0},{255,0,255,0}};
uint8_t stepN[5] = {0,0,0,0,0};
uint8_t waitN[5] = {10,20,20,10,30};
uint8_t waitNc[5] = {10,20,20,10,30};

char inStr[64];       // a string to hold incoming data
char readData[64];    // a string to hold incoming data

void setup() {
  // initialize serial:
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  Serial.begin(115200);
  // reserve 32 bytes for the inputString:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // print the string when a newline arrives:
  if (inComplete) {
    inComplete = false;
    cmdExecute();
    readData[1]=0;
    Serial.println(readData); // Подтверждение - команда выполнена
  }
  else {
    progStep++;
    switch (prog) {
      case '1': { theaterChaseRainbow(param); break; }
      case '2': { rainbowCycle(param); break; }
      case '3': { sub1(param); break; }
      case '4': { sub2(param); break; }
      case '5': { sub3(param); break; }
      case '6': { sub4(param); break; }
//      case '7': { sub5(param); break; }
//      case '8': { sub6(param); break; }
//      case '9': { sub7(param); break; }
//      case 'A': { sub8(param); break; }
//      case 'B': { sub9(param); break; }
//      case 'D': { sub10(param); break; }
    }
  }
}

void setMode() {
  prog = readData[0];
  param = readData[1];
}

void cmdExecute() {

      switch (readData[0]) {
      case 'p': { param = readData[1]; break; }  
      case 'r': { setMode(); zmu1();  break; }
      case 's': { setMode(); zmu2(); break; }
      case 't': { setMode(); zmu3(); break; }
      case 'u': { setMode(); zmu4(); break; }
      case 'v': { setMode(); zmu5(); break; }
      case 'x': { setMode(); zmu6(); break; }
      case 'm': { setMode(); ColorWhite(param); break; }
      case '1': { setMode(); theaterChaseRainbow(param); break; }
      case '2': { setMode(); rainbowCycle(param); break; }
      case '3': { setMode(); sub1(param); break; }
      case '4': { setMode(); readColor(); sub2(param); break; }
      case '5': { setMode(); readColor(); sub3(param); break; }
      case '6': { setMode(); readColor(); sub4(param); break; }
//      case '7': { setMode(); readColor(); sub5(param); break; }
//      case '8': { setMode(); readColor(); sub6(param); break; }
//      case '9': { setMode(); readColor(); sub7(param); break; }
//      case 'A': { setMode(); readColor(); sub8(param); break; }
//      case 'B': { setMode(); readColor(); sub9(param); break; }
//      case 'D': { setMode(); readColor(); sub10(param); break; }
        case 'c': { strip.clear(); strip.show(); break; }
      }
}

void zmu4() {
  // Ваш код  
}

void zmu5() {
  // Ваш код  
}

void zmu6() {
  // Ваш код  
}

void sub5() {
  // Ваш код
}

void sub4(uint8_t wait) {
   TColor cl;
   uint8_t i;

   for(i=0; i<4; i++) {
     waitN[i]--;  
     if (waitN[i]==0){
       waitN[i]=waitNc[i];
       stepN[i]++;
       if (stepN[i]>stripLed-1) stepN[i]=0;
       cl.dw = strip.Color(clN[i].r, clN[i].g, clN[i].b);
       if (i%2==0) strip.setPixelColor(stepN[i], cl.dw);
              else strip.setPixelColor(stripLed-1-stepN[i], cl.dw);    
     }
   }
   strip.show();
   delay(wait);
}

void sub3(uint8_t wait) {
  TColor cl;
  
  if (progStep>stripLed-1) {
    progStep=0;
    progDir=!progDir;
  }
  if (progDir==0) {
    cl.dw = strip.Color(clN[1].r, clN[1].g, clN[1].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  else {
    cl.dw = strip.Color(clN[2].r, clN[2].g, clN[2].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  strip.show();
  delay(wait);
}

void sub2(uint8_t wait) {
  TColor cl;
  
  if (progStep>stripLed-1) {
    progStep=0;
    progDir=!progDir;
  }
  if (progDir==0) {
    cl.dw = strip.Color(clN[1].r, clN[1].g, clN[1].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  else {
    cl.dw = strip.Color(0, 0, 0);
    strip.setPixelColor(progStep, cl.dw);
  }
  strip.show();
  delay(wait);
}

void sub1(uint8_t wait) {
  long rn1,rn2;
  TColor cl;
  // Напишите свой код
  rn1 = random(stripLed-1);
  rn2 = random(stripLed-1);
  cl.dw = strip.Color(255, 255, 255);
  strip.setPixelColor(rn1, cl.dw);
  strip.setPixelColor(rn2, cl.dw);
  strip.show();
  delay(10);
  cl.dw = strip.Color(0, 0, 0);
  strip.setPixelColor(rn1, cl.dw);
  strip.setPixelColor(rn2, cl.dw);
  strip.show();
}

void zmu3() {
  TColor cl;
  TWord akk;
  uint8_t i,k,j,n;

  for(i=0; i<15; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/15]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      n=i*ledDist/2;
      for(k=0; k<ledDist/2; k++) {
        strip.setPixelColor(n+k, cl.dw);
        strip.setPixelColor(stripLed-(n+k)-1, cl.dw);
      }
  }
  strip.show();
}

void zmu2() {
  TColor cl;
  TWord akk;
  uint8_t i,k,j;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(i+k*bandPass, cl.dw);
  }
  strip.show();
}

void zmu1() {
  TColor cl;
  TWord akk;
  uint8_t n,i,k,j;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      n=i*ledDist;
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(n+k, cl.dw);
  }
  strip.show();
}

void ColorWhite(uint8_t colorNumber) {
  uint8_t i;
  uint16_t br;
  TColor cl;
  if (colorNumber<48) {
    colorNumber *= 2;
    if (colorNumber>95) colorNumber=95; 
    cl.dw = pgm_read_dword(&colorTab[colorNumber]);
    cl.dw = strip.Color(cl.r, cl.g, cl.b);
    for(i=0; i<stripLed; i++) strip.setPixelColor(i, cl.dw);
  }
  else {
    br = 63 - colorNumber;
    br *= 16;
    if (br>239) colorNumber = 255;
    cl.dw=strip.Color(br, br, br);
    for(i=0; i<stripLed; i++) strip.setPixelColor(i, cl.dw);
    strip.show();
  }
  strip.show();
}

void readColor() {
  uint8_t i;
  uint8_t j = 2;

  for(i=0; i<5; i++) {
     clN[i].r=readData[j++];
     clN[i].g=readData[j++];
     clN[i].b=readData[j++];
  }
  for(i=0; i<5; i++) waitNc[i]=readData[j++];
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i;

    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + progStep) & 255));
    }
    strip.show();
    delay(wait);
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+progStep) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

//  SerialEvent
void serialEvent() {
  uint8_t i;
  
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    if (inChar != char(253)) {
     inStr[inCounter++] = inChar;
     if (inChar == char(254)) {
       i=0;
       while (inStr[i]!=char(254)) {
         readData[i]=inStr[i];
         i++;
       }
       readData[i]=inStr[i];
       inCounter = 0;          // Устанавливаем счётчик принятых символов на начало входного буфера
       inComplete = true;
    }
    } else inCounter = 0;      // Устанавливаем счётчик принятых символов на начало входного буфера
  }
}

COMtoRF.ino

#include <SPI.h>        // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h>   // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>       // Подключаем библиотеку для работы с nRF24L01+
RF24    radio(9, 10);   // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)

char    rfData[22];     // Создаём массив для передачи данных
uint8_t rfCounter = 0;
char    serData[32];    // a string to hold incoming data
uint8_t serCounter = 0;
boolean stringComplete = false;

void setup(){
    Serial.begin(115200);
    radio.begin();                             // Инициируем работу nRF24L01+
    radio.setChannel(5);                       // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
    radio.setDataRate     (RF24_1MBPS);        // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
    radio.setPALevel      (RF24_PA_HIGH);      // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
    radio.openWritingPipe (0x1234567890LL);    // Открываем трубу с идентификатором 0x1234567890 для передачи данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
}

void loop(){
  uint8_t i;
  
    if (rfCounter>0) {
      radio.write(&rfData[0],22);
      rfCounter=0;
      Serial.write(rfData,22);
    }
}

//  SerialEvent
void serialEvent() {
  uint8_t i;
  
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    if (inChar != char(253)) {
     if (inChar == char(254)) {
       for(i=0; i<22; i++) rfData[i]=serData[i];
       rfCounter = 22;
       serCounter = 0;          // clear the input string:
     }
     else {
      serData[serCounter++] = inChar;
      serCounter &= 0x1F;
     }
    } else serCounter = 0;      // clear the input string: 
  }
}

RFtoLED.ino

#include <SPI.h>                   // Подключаем библиотеку  для работы с шиной SPI
#include <nRF24L01.h>              // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                  // Подключаем библиотеку  для работы с nRF24L01+
#include <Adafruit_NeoPixel.h>

#define stripLed 240     // количество светодиодов в ленте
#define bandPass 17      // полос (групп светодиодов)
#define stripPin 2       // выход управления светодиодной лентой
#define ledDist 14
#define LedtoColor 14

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(stripLed, stripPin, NEO_GRB + NEO_KHZ800);

RF24      radio(9, 10);    // Создаём объект radio   для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)

const uint32_t PROGMEM
  colorTab[]={
      0xFF0000,0xFF1100,0xFF2200,0xFF3300,0xFF4400,0xFF5500,0xFF6600,0xFF7700,0xFF8800,0xFF9900,0xFFAA00,0xFFBB00,0xFFCC00,0xFFDD00,0xFFEE00,0xFFFF00,  //красный - жёлтый
      0xFFFF00,0xEEFF00,0xDDFF00,0xCCFF00,0xBBFF00,0xAAFF00,0x99FF00,0x88FF00,0x77FF00,0x66FF00,0x55FF00,0x44FF00,0x33FF00,0x22FF00,0x11FF00,0x00FF00,  //жёлтый — зелёный
      0x00FF00,0x00FF11,0x00FF22,0x00FF33,0x00FF44,0x00FF55,0x00FF66,0x00FF77,0x00FF88,0x00FF99,0x00FFAA,0x00FFBB,0x00FFCC,0x00FFDD,0x00FFEE,0x00FFFF,  //зелёный — циан (голубой)
      0x00FFFF,0x00EEFF,0x00DDFF,0x00CCFF,0x00BBFF,0x00AAFF,0x0099FF,0x0088FF,0x0077FF,0x0066FF,0x0055FF,0x0044FF,0x0033FF,0x0022FF,0x0011FF,0x0000FF,  //голубой — синий
      0x0000FF,0x1100FF,0x2200FF,0x3300FF,0x4400FF,0x5500FF,0x6600FF,0x7700FF,0x8800FF,0x9900FF,0xAA00FF,0xBB00FF,0xCC00FF,0xDD00FF,0xEE00FF,0xFF00FF,  //синий — пурпур (маджента)
      0xFF00FF,0xFF00EE,0xFF00DD,0xFF00CC,0xFF00BB,0xFF00AA,0xFF0099,0xFF0088,0xFF0077,0xFF0066,0xFF0055,0xFF0044,0xFF0033,0xFF0022,0xFF0011,0xFF0000}; //маджента — красный
      
typedef union{
    struct {
      uint8_t b,g,r,w;
    };
    uint32_t dw;
} TColor;

typedef union{
    struct {
      uint8_t b0,b1;
    };
    uint16_t w;
} TWord;      

char readData[22];           // Буфер команды
char prog = '2';
uint8_t param = 0;
uint8_t progStep = 0;
uint8_t progDir = 0;
TColor clN[5] = {{255,0,0,0},{0,255,0,0},{0,0,255,0},{0,255,255,0},{255,0,255,0}};
uint8_t stepN[5] = {0,0,0,0,0};
uint8_t waitN[5] = {10,20,20,10,30};
uint8_t waitNc[5] = {10,20,20,10,30};

void setup(){ 
    // initialize serial:
    Serial.begin(115200);
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'

    radio.begin();                              // Инициируем работу nRF24L01+
//    radio.setAutoAck(false);

    radio.setChannel(5);                        // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
    radio.setDataRate     (RF24_1MBPS);         // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
    radio.setPALevel      (RF24_PA_HIGH);       // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
    radio.openReadingPipe (1, 0x1234567890LL);  // Открываем 1 трубу с идентификатором 0x1234567890 для приема данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)

    radio.startListening  ();                   // Включаем приемник, начинаем прослушивать открытые трубы
}

void loop(){

    if(radio.available()){        // Если в буфере имеются принятые данные, то получаем номер трубы, по которой они пришли, по ссылке на переменную pipe
      radio.read(&readData, 22);  // Приём команды
      cmdExecute();       
    }
    else {
      progStep++;
      switch (prog) {
        case '1': { theaterChaseRainbow(param); break; }
        case '2': { rainbowCycle(param); break; }
        case '3': { sub1(param); break; }
        case '4': { sub2(param); break; }
        case '5': { sub3(param); break; }
        case '6': { sub4(param); break; }
//      case '7': { sub5(param); break; }
//      case '8': { sub6(param); break; }
//      case '9': { sub7(param); break; }
//      case 'A': { sub8(param); break; }
//      case 'B': { sub9(param); break; }
//      case 'D': { sub10(param); break; }
      }
    }
}

void setMode() {
  prog = readData[0];
  param = readData[1];
}


void cmdExecute() {
     
      switch (readData[0]) {
      case 'p': { param = readData[1]; break; }  
      case 'r': { setMode(); zmu1();  break; }
      case 's': { setMode(); zmu2(); break; }
      case 't': { setMode(); zmu3(); break; }
      case 'u': { setMode(); zmu4(); break; }
      case 'v': { setMode(); zmu5(); break; }
      case 'x': { setMode(); zmu6(); break; }
      case 'm': { setMode(); ColorWhite(param); break; }
      case '1': { setMode(); theaterChaseRainbow(param); break; }
      case '2': { setMode(); rainbowCycle(param); break; }
      case '3': { setMode(); sub1(param); break; }
      case '4': { setMode(); readColor(); sub2(param); break; }
      case '5': { setMode(); readColor(); sub3(param); break; }
      case '6': { setMode(); readColor(); sub4(param); break; }
//      case '7': { setMode(); readColor(); sub5(param); break; }
//      case '8': { setMode(); readColor(); sub6(param); break; }
//      case '9': { setMode(); readColor(); sub7(param); break; }
//      case 'A': { setMode(); readColor(); sub8(param); break; }
//      case 'B': { setMode(); readColor(); sub9(param); break; }
//      case 'D': { setMode(); readColor(); sub10(param); break; }
        case 'c': { strip.clear(); strip.show(); break; }
      }
}

void zmu4() {
  TColor cl;
  uint8_t i,k;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      // Ваш код  
      // .....
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(i*LedtoColor+k, cl.dw);
      // Ваш код  
  }
  strip.show();
}

void zmu5() {
  TColor cl;
  uint8_t i,k;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      // Ваш код  
      // .....
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(i*LedtoColor+k, cl.dw);
      // Ваш код  
  }
  strip.show();
}

void zmu6() {
  TColor cl;
  uint8_t i,k;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      // Ваш код  
      // .....
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(i*LedtoColor+k, cl.dw);
      // Ваш код  
  }
  strip.show();
}

void sub5() {
  // Ваш код
}

void sub4(uint8_t wait) {
   TColor cl;
   uint8_t i;

   for(i=0; i<4; i++) {
     waitN[i]--;  
     if (waitN[i]==0){
       waitN[i]=waitNc[i];
       stepN[i]++;
       if (stepN[i]>stripLed-1) stepN[i]=0;
       cl.dw = strip.Color(clN[i].r, clN[i].g, clN[i].b);
       if (i%2==0) strip.setPixelColor(stepN[i], cl.dw);
              else strip.setPixelColor(stripLed-1-stepN[i], cl.dw);    
     }
   }
   strip.show();
   delay(wait);
}

void sub3(uint8_t wait) {
  TColor cl;
  
  if (progStep>stripLed-1) {
    progStep=0;
    progDir=!progDir;
  }
  if (progDir==0) {
    cl.dw = strip.Color(clN[0].r, clN[0].g, clN[0].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  else {
    cl.dw = strip.Color(clN[1].r, clN[1].g, clN[1].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  strip.show();
  delay(wait);
}

void sub2(uint8_t wait) {
  TColor cl;
  
  if (progStep>stripLed-1) {
    progStep=0;
    progDir=!progDir;
  }
  if (progDir==0) {
    cl.dw = strip.Color(clN[0].r, clN[0].g, clN[0].b);
    strip.setPixelColor(progStep, cl.dw);
  }
  else {
    cl.dw = strip.Color(0, 0, 0);
    strip.setPixelColor(progStep, cl.dw);
  }
  strip.show();
  delay(wait);
}

void sub1(uint8_t wait) {
  long randomNumber;
  TColor cl;
  // Напишите свой код
  randomNumber = random(stripLed-1);
  cl.dw = strip.Color(255, 255, 255);
  strip.setPixelColor(randomNumber, cl.dw);
  strip.show();
  delay(10);
  cl.dw = strip.Color(0, 0, 0);
  strip.setPixelColor(randomNumber, cl.dw);
  strip.show();
}

void zmu3() {
  TColor cl;
  TWord akk;
  uint8_t i,k,j,n;

  for(i=0; i<17; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/17]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      n=i*ledDist/2;
      for(k=0; k<ledDist/2; k++) {
        strip.setPixelColor(n+k, cl.dw);
        strip.setPixelColor(stripLed-(n+k)-1, cl.dw);
      }
  }
  strip.show();
}

void zmu2() {
  TColor cl;
  TWord akk;
  uint8_t i,k,j;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(i+k*bandPass, cl.dw);
  }
  strip.show();
}

void zmu1() {
  TColor cl;
  TWord akk;
  uint16_t r,g,b;
  uint8_t n,i,k,j;

  for(i=0; i<bandPass; i++) {
      cl.dw = pgm_read_dword(&colorTab[96*i/bandPass]);
      j=readData[i+2];
      akk.w = cl.r * j;
      akk.w = akk.b1 * akk.b1; 
      cl.r = akk.b1;
      akk.w = cl.g * j;
      akk.w = akk.b1 * akk.b1; 
      cl.g = akk.b1;
      akk.w = cl.b * j;
      akk.w = akk.b1 * akk.b1; 
      cl.b = akk.b1;
      cl.dw = strip.Color(cl.r, cl.g, cl.b);
      n=i*ledDist;
      for(k=0; k<LedtoColor; k++) strip.setPixelColor(n+k, cl.dw);
  }
  strip.show();
}

void ColorWhite(uint8_t colorNumber) {
  uint8_t i;
  uint16_t br;
  TColor cl;
  if (colorNumber<48) {
    colorNumber *= 2;
    if (colorNumber>95) colorNumber=95; 
    cl.dw = pgm_read_dword(&colorTab[colorNumber]);
    cl.dw = strip.Color(cl.r, cl.g, cl.b);
    for(i=0; i<stripLed; i++) strip.setPixelColor(i, cl.dw);
  }
  else {
    br = 63 - colorNumber;
    br *= 16;
    if (br>239) colorNumber = 255;
    cl.dw=strip.Color(br, br, br);
    for(i=0; i<stripLed; i++) strip.setPixelColor(i, cl.dw);
    strip.show();
  }
  strip.show();
}

void readColor() {
  uint8_t i;
  uint8_t j = 2;

  for(i=0; i<5; i++) {
     clN[i].r=readData[j++];
     clN[i].g=readData[j++];
     clN[i].b=readData[j++];
  }
  for(i=0; i<5; i++) waitNc[i]=readData[j++];
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i;

    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + progStep) & 255));
    }
    strip.show();
    delay(wait);
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+progStep) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

 

 

 

 

wuko
Offline
Зарегистрирован: 07.02.2018

Здравствуйте, есть проблемка с лентой, 

сделал всё как у вас написано, использовав скетч без wifi, запитал ленту с 46 светодиодами от 5V блока питания по схеме подключения и использовав программу cmu последней 5-ой версии. Настроил виртуальный аудио, в программе прыгают бары, выбран режим Радуга, а лента просто горит радужным светом и красный огонёк бегает по ней всей, без перерыва. Причём если менять режимы, то ничего не происходит. 

Когда в программе ЦМУ меняю режимы на ардуино нано V3, мигает дико огонёк синий, полагаю что скрипт отрабатывает нормально. Но вот что с лентой происходит не ясно, можете помочь разобраться с ней?! Вечером если нужно будет, попробую фото подключения и ленты выложить!

P.S. Я сам в этом деле новичок. Думаю может ещё где-то в скетче надо параметры менять, не только количество светодиодов, увы дальше не знаю как и что там менять...

 

arduinec
Offline
Зарегистрирован: 01.09.2015

wuko пишет:

Здравствуйте, есть проблемка с лентой, 

P.S. Я сам в этом деле новичок. Думаю может ещё где-то в скетче надо параметры менять, не только количество светодиодов, увы дальше не знаю как и что там менять...

Сначала лучше поиграться с примерами из библиотек FastLED и Adafruit_NeoPixel. Тогда и вам возможно будет понятнее что не так с лентой.

juraspb
Offline
Зарегистрирован: 12.12.2017
Измените настройки под вашу ленту
 
#define stripPin 2     // выход управления светодиодной лентой
#define stripLed 120   // количество светодиодов в ленте
 
на
 
#define stripPin __    // ваш выход управления светодиодной лентой
#define stripLed 46   // количество светодиодов в вашей ленте
 
Если не поможет то предыдущий коментатор прав. Загрузите пример strandtest от Adafruit_NeoPixel и проверьте что всё работает.

Посмотрите мои статьи на муське

https://mysku.ru/blog/diy/58060.html

https://mysku.ru/blog/diy/57947.html

Там же можно скачать последнюю версию программы.

 
wuko
Offline
Зарегистрирован: 07.02.2018

Спасибо за оперативность, вечером после работы попробую, потом отпишусь!

wuko
Offline
Зарегистрирован: 07.02.2018

Здравствуйте, в общем пробовал я загружать другие разные библиотеки (FastLED, Adafruit_NeoPixel и из стандартных примеров), лента работает на отлично, даже подключив через Prismatik включал режим захвата с виртуального аудио кабеля, и работала лента мигала под музыку. Но когда пробовал загрузить COMtoLED.ino и меняв настройки ну так же как и на предыдущих библиотеках. То лента напрочь отказывалась работать. Сравнивал файлы, есть различия в названиях переменных и конфиге, но изменение их не дало результата. Надо ещё почитать покопать, может попробовать что-то собрать из примеров и др. библиотек. Может что и выйдет. Позже отпишусь!