Цветомузыка на WS2812
- Войдите на сайт для отправки комментариев
Написал к новому году цветомузыкальную программку 'ЦМУ' для персонального компьютера и скетчи для управления лентой 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 умеет выводить звук одновременно и на аудио ресивер и на ПК как показано ниже
Звуковой поток поступающий на ПК попадает на устройство по умолчанию, на вход «виртуального аудио кабеля», а его выход служит источником звука в программе цветомузыки.
Оставляйте в комментариях к проекту код своих красивых динамических и цветомузыкальных подпрограмм, чтобы каждый, кому она понравится, мог добавить её в свой скетч.
Творите, выдумывайте, пишите, делитесь и каждый сможет сделать такое устройство, какое пожелает.
Всех с наступающим новым годом!!!
Демонстрационные видео работы ЦМУ в цветомузыкальном режиме:
Радуга: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); }
Здравствуйте, есть проблемка с лентой,
сделал всё как у вас написано, использовав скетч без wifi, запитал ленту с 46 светодиодами от 5V блока питания по схеме подключения и использовав программу cmu последней 5-ой версии. Настроил виртуальный аудио, в программе прыгают бары, выбран режим Радуга, а лента просто горит радужным светом и красный огонёк бегает по ней всей, без перерыва. Причём если менять режимы, то ничего не происходит.
Когда в программе ЦМУ меняю режимы на ардуино нано V3, мигает дико огонёк синий, полагаю что скрипт отрабатывает нормально. Но вот что с лентой происходит не ясно, можете помочь разобраться с ней?! Вечером если нужно будет, попробую фото подключения и ленты выложить!
P.S. Я сам в этом деле новичок. Думаю может ещё где-то в скетче надо параметры менять, не только количество светодиодов, увы дальше не знаю как и что там менять...
Здравствуйте, есть проблемка с лентой,
P.S. Я сам в этом деле новичок. Думаю может ещё где-то в скетче надо параметры менять, не только количество светодиодов, увы дальше не знаю как и что там менять...
Сначала лучше поиграться с примерами из библиотек FastLED и Adafruit_NeoPixel. Тогда и вам возможно будет понятнее что не так с лентой.
Посмотрите мои статьи на муське
https://mysku.ru/blog/diy/58060.html
https://mysku.ru/blog/diy/57947.html
Там же можно скачать последнюю версию программы.
Спасибо за оперативность, вечером после работы попробую, потом отпишусь!
Здравствуйте, в общем пробовал я загружать другие разные библиотеки (FastLED, Adafruit_NeoPixel и из стандартных примеров), лента работает на отлично, даже подключив через Prismatik включал режим захвата с виртуального аудио кабеля, и работала лента мигала под музыку. Но когда пробовал загрузить COMtoLED.ino и меняв настройки ну так же как и на предыдущих библиотеках. То лента напрочь отказывалась работать. Сравнивал файлы, есть различия в названиях переменных и конфиге, но изменение их не дало результата. Надо ещё почитать покопать, может попробовать что-то собрать из примеров и др. библиотек. Может что и выйдет. Позже отпишусь!