Цветомузыка на 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 и меняв настройки ну так же как и на предыдущих библиотеках. То лента напрочь отказывалась работать. Сравнивал файлы, есть различия в названиях переменных и конфиге, но изменение их не дало результата. Надо ещё почитать покопать, может попробовать что-то собрать из примеров и др. библиотек. Может что и выйдет. Позже отпишусь!