Всем доброго времени суток. Хочу Вам рассказать, как сделать себе праздник (новогоднее настроение) из того что есть под рукой. А в частности: arduion nano, диодная лента WS2801 и красивые скетчи «гирлянды» работающие при помощи библиотеки Adafruit_NeoPixel.h. Может мои «открытия» для опытных ардуинщиков будут несерьезными. Но мне это пригодилось и я решил поделиться с остальными.
И так в преддверии нового года захотелось мне сделать новогоднюю гирлянду. Из имеющегося дома была диодная «лента» WS2801 на 50 диодов (на фото). Можно было бы заказать WS2811 или WS2812, но что-то мне подсказывало, что до нового года не успела бы лента приехать.
Сначала сделал для гирлянды что бы цвета шли по кругу переливами оттенков.
И вроде все красиво. Но как то это не по-новогоднему. Нужно что бы моргало и переливалось.
Но была проблема. Все они сделаны по отдельности, а хотелось что бы было разнообразие в одном флаконе.
Расстроенный я продолжил искать на просторах интернета скетчи для гирлянды.
И мне повезло. Нашел скетч в котором было реализовано более 10 режимов. Все это на 200 диодов и с возможностью указания координат расположения диод на на елки (для создания симметричных эффектов)
Оригинальный скетч для гирлянды
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6
#define LED_COUNT 200
// 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(LED_COUNT, PIN, NEO_GRB + NEO_KHZ400);
//MAX_X and MAX_Y represent the largest X and Y value from the table of Positions
//This is used to derive where the middle of the tree is in the X and Y direction.
//For example if MAX_X = 20, then LEDs at a position of 10 would be the middle of
//the tree.
#define MAX_X 18
#define MAX_Y 30
//Define the X,Y positions of each pixel. The first array element is the X
//coordinate of the first LED in the string, the second array element is the
//Y coordinate of the first LED. The third array element is the X position of
//the second LED, etc…
byte Positions[LED_COUNT*2] =
{
7, 6, 7, 7, 6, 7, 5, 8, 4, 6, 3, 7, 3, 6, 2, 6, 3, 6, 1, 7, // 0 — 9
1, 8, 2, 9, 2,10, 2,11, 2,12, 4,12, 4,12, 4,13, 4,12, 5,12, //10 — 19
5,10, 6, 9, 7,10, 8,12, 8,11, 8,13, 8,13, 8,15, 7,14, 6,13, //20 — 29
6,15, 5,14, 3,15, 3,14, 3,14, 4,17, 5,16, 4,16, 5,16, 7,17, //30 — 39
7,17, 9,16, 9,16, 10,18, 9,19, 8,20, 8,19, 7,18, 6,20, 6,18, //40 — 49
5,17, 4,17, 4,17, 6,18, 4,18, 4,18, 6,20, 6,22, 6,22, 7,20, //50 — 59
6,20, 8,21, 8,22, 8,22, 10,22, 10,23, 10,24, 9,24, 7,24, 8,23, //60 — 69
6,23, 7,23, 6,23, 5,23, 6,22, 5,21, 7,24, 6,22, 6,24, 7,25, //70 — 79
6,25, 7,26, 7,27, 7,27, 7,26, 9,26, 9,27, 9,28, 9,28, 8,28, //80 — 89
8,28, 8,27, 7,26, 7,26, 6,26, 8,28, 8,28, 9,30, 9,30, 9,30, //90 — 99
12,30, 12,29, 12,28, 13,28, 13,28, 13,27, 12,26, 11,27, 10,26, 12,25, //100-109
11,24, 12,24, 14,24, 14,25, 14,24, 14,23, 14,23, 15,22, 15,22, 13,22, //110-119
13,23, 13,22, 12,22, 13,22, 11,22, 11,22, 10,21, 11,21, 11,22, 12,21, //120-129
14,21, 13,20, 14,21, 14,21, 15,22, 16,21, 17,21, 18,19, 18,18, 16,17, //130-139
16,16, 16,16, 16,18, 16,18, 14,18, 15,19, 14,18, 12,19, 11,18, 11,18, //140-149
11,15, 10,15, 10,16, 12,15, 12,14, 13,15, 13,15, 14,15, 15,15, 16,15, //150-159
16,15, 17,16, 17,14, 17,14, 16,14, 18,13, 17,12, 18,11, 18,11, 15,11, //160-169
15,10, 14,10, 14,11, 13,11, 13,12, 11,11, 11, 9, 9, 9, 9, 8, 7, 9, //170-179
7, 7, 8, 6, 9, 8, 11, 6, 12, 6, 13, 7, 14, 7, 16, 8, 16, 8, 16,10, //180-189
16,10, 18, 9, 17, 8, 19,12, 20, 9, 19, 7, 19, 7, 18, 7, 18, 6, 17, 5 //190-199
};
/******************************************************/
void setup() {
Serial.begin(9600);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
/******************************************************/
void loop() {
solid(strip.Color(0,0,0));
while (true)
{
/* UnComment the following block if you are going to calculate
LED Positions. Extend and add calls as necessary to match
your LED count.
Serial.println(«GetLocation»);
getLocation(0); //LEDs 0-9
getLocation(1); //LEDs 10-19
getLocation(2); //LEDs 20-29
getLocation(3); //LEDs 30-39
getLocation(4); //LEDs 40-49
delay(3000);
*/
Serial.println(«Solid»);
solid(strip.Color(255,0,0));
delay(3000);
Serial.println(«Solid2»);
two_solid(strip.Color(0,255,0),strip.Color(0,0,255));
delay(3000);
Serial.println(«Dissolve»);
dissolve(strip.Color(255,0,0),strip.Color(0,255,0),5000);
delay(3000);
Serial.println(«Fade»);
fade(strip.Color(0,0,0),strip.Color(255,255,0),5000);
delay(3000);
Serial.println(«HorizWipe»);
horizWipe(false,strip.Color(0,255,255),strip.Color(0,0,255),5000);
delay(3000);
Serial.println(«centerHorizWipe»);
centerHorizWipe(strip.Color(0,255,0),strip.Color(255,0,0),5000);
delay(3000);
Serial.println(«vertWipe»);
vertWipe(false,strip.Color(255,0,0),strip.Color(0,0,255),5000);
delay(3000);
Serial.println(«vertLine»);
vertLine(false,strip.Color(0,255,0),strip.Color(255,0,0),5000);
delay(3000);
Serial.println(«vertWave»);
vertWave(strip.Color(0,255,0),strip.Color(255,0,0),150,5000);
delay(3000);
Serial.println(«vertCenterWave»);
vertCenterWave(strip.Color(255,255,0),strip.Color(0,255,255),150,5000);
delay(3000);
Serial.println(«transition»);
transition(strip.Color(255,0,0),strip.Color(0,255,0));
delay(3000);
Serial.println(«setBlock»);
setBlock(3,strip.Color(255,255,255));
delay(3000);
Serial.println(«Shimmer»);
shimmer(strip.Color(255,0,0),strip.Color(0,255,0),20000,25);
}
}
/*******************************************************/
uint32_t colorSlope(uint32_t c1, uint32_t c2, float percent)
{
uint32_t temp_color, temp_c1_component, temp_c2_component;
temp_color = 0;
temp_c1_component = (c1 & 0x00ff0000) >> 16;
temp_c2_component = (c2 & 0x00ff0000) >> 16;
temp_color = uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
temp_color = temp_color << 8;
temp_c1_component = (c1 & 0x0000ff00) >> 8;
temp_c2_component = (c2 & 0x0000ff00) >> 8;
temp_color += uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
temp_color = temp_color << 8;
temp_c1_component = (c1 & 0x000000ff);
temp_c2_component = (c2 & 0x000000ff);
temp_color += uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
return temp_color;
}
/*******************************************************/
void solid(uint32_t color)
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,color); }
strip.show();
}
/*******************************************************/
void two_solid(uint32_t color_1, uint32_t color_2)
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (i % 2 == 0)
{strip.setPixelColor(i,color_1);}
else
{strip.setPixelColor(i,color_2);}
}
strip.show();
}
/*******************************************************/
void dissolve(uint32_t c_from, uint32_t c_to, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t tick = duration/(strip.numPixels()+50);
bool temp[strip.numPixels()];
int rand;
for(uint16_t j=0; j<strip.numPixels(); j++)
{ temp[j] = false;
strip.setPixelColor(j,c_from);
}
while (elapsed_time < duration)
{
rand = random(strip.numPixels());
if (temp[rand])
{ rand = random(strip.numPixels());
if (temp[rand])
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (!temp[i]) {rand=i; i = 999;} }
}
}
temp[rand] = true;
strip.setPixelColor(rand,c_to);
strip.show();
delay(tick);
elapsed_time += tick+5;
}
for(uint16_t j=0; j<strip.numPixels(); j++)
{ strip.setPixelColor(j,c_to);}
strip.show();
} //dissolve
/*******************************************************/
// Transition all lights from color c_from to color c_to
void fade(uint32_t c_from, uint32_t c_to, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t temp_color;
while (elapsed_time < duration)
{
temp_color = colorSlope(c_from,c_to,float(elapsed_time)/float(duration));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,temp_color); }
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_to); }
strip.show();
} //fade
/***********************************************************/
// Transition of colors
void transition(uint32_t c_top, uint32_t c_bottom)
{
uint32_t elapsed_time = 0;
uint32_t temp_color;
for(uint16_t i=0; i<strip.numPixels(); i++)
{ temp_color = colorSlope(c_top,c_bottom,float(Positions[i*2+1])/float(MAX_Y));
strip.setPixelColor(i,temp_color); }
strip.show();
delay(50);
} //Transition of colors
/***********************************************************/
// Horiz Wipe from color c_from to color c_to
void horizWipe(boolean left_to_right, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t X_temp;
while (elapsed_time < duration)
{
//Locate the wipe X
X_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_X));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (left_to_right)
{if (Positions[i*2] < X_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2] > MAX_X — X_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //horizWipe
/***********************************************************/
// Horiz Wipe from color c_from to color c_to
void centerHorizWipe(uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t X_Lower,X_Upper;
while (elapsed_time < duration)
{
//Locate the wipe X
X_Lower = (uint32_t)(float(MAX_X/2) — float(elapsed_time)/float(duration)*float(MAX_X)/2);
X_Upper = (uint32_t)(float(MAX_X/2) + float(elapsed_time)/float(duration)*float(MAX_X)/2);
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (Positions[i*2] >= X_Lower && Positions[i*2] <= X_Upper )
{strip.setPixelColor(i,c_wipe); }
else
{strip.setPixelColor(i,c_orig); }
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //horizWipe
/***********************************************************/
// Vert Wipe from color c_from to color c_to
void vertWipe(boolean bottom_to_top, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t Y_temp;
while (elapsed_time < duration)
{
//Locate the wipe Y
Y_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_Y));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (bottom_to_top)
{if (Positions[i*2+1] < Y_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2+1] > MAX_Y — Y_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //vertWipe
/*******************************************************/
// Vert Line across from color c_from to color c_to
void vertLine(boolean bottom_to_top, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t Y_temp;
while (elapsed_time < duration)
{
//Locate the wipe Y
Y_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_Y));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (bottom_to_top)
{if (Positions[i*2+1] == Y_temp | Positions[i*2+1] == Y_temp+1) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2+1] == MAX_Y — Y_temp | Positions[i*2+1] == MAX_Y — Y_temp+1 ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
} //vertWipe
/*******************************************************/
// Lights up each light in the strip one-by-one, used to
// define pixel positions
void getLocation(uint32_t loc) {
uint32_t signal = loc;
for(uint16_t i=0; i<strip.numPixels();i++) {
strip.setPixelColor(i,strip.Color(0,0,0));
}
while(signal > 0)
{
if (signal >= 10)
{ for(uint16_t i=0; i< 10; i++)
{strip.setPixelColor(loc*10+i,strip.Color(255,0,0));}
signal -= 10;
}
else
{ for(uint16_t i=0; i< 10; i++)
{strip.setPixelColor(loc*10+i,strip.Color(255,255,255));}
signal -= 1;
}
strip.show();
delay(500);
for(uint16_t i=0; i<strip.numPixels();i++) {
strip.setPixelColor(i,strip.Color(0,0,0));
}
strip.show();
delay(500);
} //while on signal
for(uint16_t i=0; i < 10; i++)
{
strip.setPixelColor(loc*10+i,strip.Color(255,255,255));
strip.show();
delay(1000);
strip.setPixelColor(loc*10+i,strip.Color(0,0,0));
}
} //setupWipe()
/********************************************************/
void vertWave(uint32_t c1, uint32_t c2, uint32_t tick, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t ticker = 0;
while (elapsed_time < duration)
{
for(uint16_t i=0; i < LED_COUNT; i++)
{
if ((Positions[i*2+1] / 4) % 4 == ticker % 4)
{strip.setPixelColor(i, c1);}
else
{strip.setPixelColor(i, c2);}
}
strip.show();
delay(tick);
ticker++;
elapsed_time += tick + 5;
}
}
/********************************************************/
void vertCenterWave(uint32_t c1, uint32_t c2, uint32_t tick, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t ticker = 0;
while (elapsed_time < duration)
{
for(uint16_t i=0; i < LED_COUNT; i++)
{
if (((abs(MAX_Y/2 — Positions[i*2+1]) / 3) % 3 == ticker % 3))
{strip.setPixelColor(i, c1);}
else
{strip.setPixelColor(i, c2);}
}
strip.show();
delay(tick);
ticker++;
elapsed_time += tick + 5;
}
}
/********************************************************/
void setBlock(uint32_t block, uint32_t c)
{
uint32_t y_pos;
for(uint16_t i=0; i<strip.numPixels();i++) {
y_pos = Positions[i*2+1];
if (y_pos/(MAX_Y/6) == block)
{ strip.setPixelColor(i,c); }
}
strip.show();
}
/********************************************************/
void shimmer(uint32_t c_base, uint32_t c_shimmer, uint32_t duration, uint32_t amount)
{
uint32_t shimmer_pixel_num[amount];
float shimmer_pixel_percent[amount];
uint32_t elapsed_time = 0;
for(uint16_t i=0; i < amount; i++)
{ shimmer_pixel_num[i] = 0; }
for(uint16_t i=0; i < strip.numPixels(); i++)
{ strip.setPixelColor(i,c_base); }
while (elapsed_time < duration)
{
// See if we should start a shimmer
for(uint16_t i=0; i < amount; i++)
{
if (shimmer_pixel_num[i] == 0 & random(10) > 8)
{ shimmer_pixel_num[i] = random(199) + 1;
shimmer_pixel_percent[i] = 0.0;
}
if (shimmer_pixel_num[i] > 0)
{
if (i% 2 == 0)
{ shimmer_pixel_percent[i] += 0.02; }
else
{ shimmer_pixel_percent[i] += 0.04; }
if (shimmer_pixel_percent[i] >= 2.0)
{
strip.setPixelColor(shimmer_pixel_num[i],c_base);
shimmer_pixel_num[i] = 0;
}
else
{
strip.setPixelColor(shimmer_pixel_num[i],colorSlope(c_shimmer,c_base,abs(1.0 — shimmer_pixel_percent[i])));
}
}
}
strip.show();
delay(50);
elapsed_time += 50 + 5;
}
for(uint16_t i=0; i < strip.numPixels(); i++)
{ strip.setPixelColor(i,c_base); }
strip.show();
}
Но вот тут случилась проблема. Скетч использует библиотеку Adafruit_NeoPixel.h, а она категорически не хочет работать с диодами WS2801.
Похожая библиотека для WS2801 называется Adafruit_WS2801_Library.
Но если поменять в скетче библиотеку и немного поправив скетч (в части указания типа диодов и дополнительного контакта clock), то ничего не произойдет, так как скетч не будет компилироваться.
Опять проблемы, но мы же не будем сдаваться.
На просторах интернета была найдена похожая проблема и даже её решение (в далеком 2015).
Для того что бы скетч написанный для библиотеки Adafruit_NeoPixel.h скомпилировался с библиотекой Adafruit_WS2801_Library, нужно модифицировать эту самую библиотеку. Но для простоты работы вот вам ссылка на уже модифицированную библиотеку
Соответственно после замены файлов в библиотеке. Нужно в скетче добавить
Вот уже правленый скетч (на 50 диодов)
#include <Adafruit_WS2801.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 11
#define CLOCK_PIN 13
#define LED_COUNT 50
// 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_WS2801 strip = Adafruit_WS2801(LED_COUNT, PIN, CLOCK_PIN);
//MAX_X and MAX_Y represent the largest X and Y value from the table of Positions
//This is used to derive where the middle of the tree is in the X and Y direction.
//For example if MAX_X = 20, then LEDs at a position of 10 would be the middle of
//the tree.
#define MAX_X 40
#define MAX_Y 40
//Define the X,Y positions of each pixel. The first array element is the X
//coordinate of the first LED in the string, the second array element is the
//Y coordinate of the first LED. The third array element is the X position of
//the second LED, etc…
byte Positions[LED_COUNT*2] =
{
7, 6, 7, 7, 6, 7, 5, 8, 4, 6, 3, 7, 3, 6, 2, 6, 3, 6, 1, 7, // 0 — 9
1, 8, 2, 9, 2,10, 2,11, 2,12, 4,12, 4,12, 4,13, 4,12, 5,12, //10 — 19
5,10, 6, 9, 7,10, 8,12, 8,11, 8,13, 8,13, 8,15, 7,14, 6,13, //20 — 29
6,15, 5,14, 3,15, 3,14, 3,14, 4,17, 5,16, 4,16, 5,16, 7,17, //30 — 39
7,17, 9,16, 9,16, 10,18, 9,19, 8,20, 8,19, 7,18, 6,20, 6,18, //40 — 49
};
/******************************************************/
void setup() {
Serial.begin(9600);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
/******************************************************/
void loop() {
solid(strip.Color(0,0,0));
while (true)
{
/* UnComment the following block if you are going to calculate
LED Positions. Extend and add calls as necessary to match
your LED count.
Serial.println(«GetLocation»);
getLocation(0); //LEDs 0-9
getLocation(1); //LEDs 10-19
getLocation(2); //LEDs 20-29
getLocation(3); //LEDs 30-39
getLocation(4); //LEDs 40-49
delay(3000);
*/
Serial.println(«Solid»);
solid(strip.Color(255,0,0));
delay(3000);
Serial.println(«Solid2»);
two_solid(strip.Color(0,255,0),strip.Color(0,0,255));
delay(3000);
Serial.println(«Dissolve»);
dissolve(strip.Color(255,0,0),strip.Color(0,255,0),5000);
delay(3000);
Serial.println(«Fade»);
fade(strip.Color(0,0,0),strip.Color(255,255,0),5000);
delay(3000);
Serial.println(«HorizWipe»);
horizWipe(false,strip.Color(0,255,255),strip.Color(0,0,255),5000);
delay(3000);
Serial.println(«centerHorizWipe»);
centerHorizWipe(strip.Color(0,255,0),strip.Color(255,0,0),5000);
delay(3000);
Serial.println(«vertWipe»);
vertWipe(false,strip.Color(255,0,0),strip.Color(0,0,255),5000);
delay(3000);
Serial.println(«vertLine»);
vertLine(false,strip.Color(0,255,0),strip.Color(255,0,0),5000);
delay(3000);
Serial.println(«vertWave»);
vertWave(strip.Color(0,255,0),strip.Color(255,0,0),150,5000);
delay(3000);
Serial.println(«vertCenterWave»);
vertCenterWave(strip.Color(255,255,0),strip.Color(0,255,255),150,5000);
delay(3000);
Serial.println(«transition»);
transition(strip.Color(255,0,0),strip.Color(0,255,0));
delay(3000);
Serial.println(«setBlock»);
setBlock(3,strip.Color(255,255,255));
delay(3000);
Serial.println(«Shimmer»);
shimmer(strip.Color(255,0,0),strip.Color(0,255,0),20000,25);
}
}
/*******************************************************/
uint32_t colorSlope(uint32_t c1, uint32_t c2, float percent)
{
uint32_t temp_color, temp_c1_component, temp_c2_component;
temp_color = 0;
temp_c1_component = (c1 & 0x00ff0000) >> 16;
temp_c2_component = (c2 & 0x00ff0000) >> 16;
temp_color = uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
temp_color = temp_color << 8;
temp_c1_component = (c1 & 0x0000ff00) >> 8;
temp_c2_component = (c2 & 0x0000ff00) >> 8;
temp_color += uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
temp_color = temp_color << 8;
temp_c1_component = (c1 & 0x000000ff);
temp_c2_component = (c2 & 0x000000ff);
temp_color += uint32_t(temp_c1_component + (float(temp_c2_component) — float(temp_c1_component)) * percent);
return temp_color;
}
/*******************************************************/
void solid(uint32_t color)
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,color); }
strip.show();
}
/*******************************************************/
void two_solid(uint32_t color_1, uint32_t color_2)
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (i % 2 == 0)
{strip.setPixelColor(i,color_1);}
else
{strip.setPixelColor(i,color_2);}
}
strip.show();
}
/*******************************************************/
void dissolve(uint32_t c_from, uint32_t c_to, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t tick = duration/(strip.numPixels()+50);
bool temp[strip.numPixels()];
int rand;
for(uint16_t j=0; j<strip.numPixels(); j++)
{ temp[j] = false;
strip.setPixelColor(j,c_from);
}
while (elapsed_time < duration)
{
rand = random(strip.numPixels());
if (temp[rand])
{ rand = random(strip.numPixels());
if (temp[rand])
{
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (!temp[i]) {rand=i; i = 999;} }
}
}
temp[rand] = true;
strip.setPixelColor(rand,c_to);
strip.show();
delay(tick);
elapsed_time += tick+5;
}
for(uint16_t j=0; j<strip.numPixels(); j++)
{ strip.setPixelColor(j,c_to);}
strip.show();
} //dissolve
/*******************************************************/
// Transition all lights from color c_from to color c_to
void fade(uint32_t c_from, uint32_t c_to, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t temp_color;
while (elapsed_time < duration)
{
temp_color = colorSlope(c_from,c_to,float(elapsed_time)/float(duration));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,temp_color); }
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_to); }
strip.show();
} //fade
/***********************************************************/
// Transition of colors
void transition(uint32_t c_top, uint32_t c_bottom)
{
uint32_t elapsed_time = 0;
uint32_t temp_color;
for(uint16_t i=0; i<strip.numPixels(); i++)
{ temp_color = colorSlope(c_top,c_bottom,float(Positions[i*2+1])/float(MAX_Y));
strip.setPixelColor(i,temp_color); }
strip.show();
delay(50);
} //Transition of colors
/***********************************************************/
// Horiz Wipe from color c_from to color c_to
void horizWipe(boolean left_to_right, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t X_temp;
while (elapsed_time < duration)
{
//Locate the wipe X
X_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_X));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (left_to_right)
{if (Positions[i*2] < X_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2] > MAX_X — X_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //horizWipe
/***********************************************************/
// Horiz Wipe from color c_from to color c_to
void centerHorizWipe(uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t X_Lower,X_Upper;
while (elapsed_time < duration)
{
//Locate the wipe X
X_Lower = (uint32_t)(float(MAX_X/2) — float(elapsed_time)/float(duration)*float(MAX_X)/2);
X_Upper = (uint32_t)(float(MAX_X/2) + float(elapsed_time)/float(duration)*float(MAX_X)/2);
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (Positions[i*2] >= X_Lower && Positions[i*2] <= X_Upper )
{strip.setPixelColor(i,c_wipe); }
else
{strip.setPixelColor(i,c_orig); }
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //horizWipe
/***********************************************************/
// Vert Wipe from color c_from to color c_to
void vertWipe(boolean bottom_to_top, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t Y_temp;
while (elapsed_time < duration)
{
//Locate the wipe Y
Y_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_Y));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (bottom_to_top)
{if (Positions[i*2+1] < Y_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2+1] > MAX_Y — Y_temp ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
for(uint16_t i=0; i<strip.numPixels(); i++)
{ strip.setPixelColor(i,c_wipe); }
strip.show();
} //vertWipe
/*******************************************************/
// Vert Line across from color c_from to color c_to
void vertLine(boolean bottom_to_top, uint32_t c_wipe, uint32_t c_orig, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t Y_temp;
while (elapsed_time < duration)
{
//Locate the wipe Y
Y_temp = (uint32_t)(float(elapsed_time)/float(duration)*float(MAX_Y));
for(uint16_t i=0; i<strip.numPixels(); i++)
{ if (bottom_to_top)
{if (Positions[i*2+1] == Y_temp | Positions[i*2+1] == Y_temp+1) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
else
{if (Positions[i*2+1] == MAX_Y — Y_temp | Positions[i*2+1] == MAX_Y — Y_temp+1 ) {strip.setPixelColor(i,c_wipe); } else {strip.setPixelColor(i,c_orig); }}
}
strip.show();
delay(50);
elapsed_time += 55;
}
} //vertWipe
/*******************************************************/
// Lights up each light in the strip one-by-one, used to
// define pixel positions
void getLocation(uint32_t loc) {
uint32_t signal = loc;
for(uint16_t i=0; i<strip.numPixels();i++) {
strip.setPixelColor(i,strip.Color(0,0,0));
}
while(signal > 0)
{
if (signal >= 10)
{ for(uint16_t i=0; i< 10; i++)
{strip.setPixelColor(loc*10+i,strip.Color(255,0,0));}
signal -= 10;
}
else
{ for(uint16_t i=0; i< 10; i++)
{strip.setPixelColor(loc*10+i,strip.Color(255,255,255));}
signal -= 1;
}
strip.show();
delay(500);
for(uint16_t i=0; i<strip.numPixels();i++) {
strip.setPixelColor(i,strip.Color(0,0,0));
}
strip.show();
delay(500);
} //while on signal
for(uint16_t i=0; i < 10; i++)
{
strip.setPixelColor(loc*10+i,strip.Color(255,255,255));
strip.show();
delay(1000);
strip.setPixelColor(loc*10+i,strip.Color(0,0,0));
}
} //setupWipe()
/********************************************************/
void vertWave(uint32_t c1, uint32_t c2, uint32_t tick, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t ticker = 0;
while (elapsed_time < duration)
{
for(uint16_t i=0; i < LED_COUNT; i++)
{
if ((Positions[i*2+1] / 4) % 4 == ticker % 4)
{strip.setPixelColor(i, c1);}
else
{strip.setPixelColor(i, c2);}
}
strip.show();
delay(tick);
ticker++;
elapsed_time += tick + 5;
}
}
/********************************************************/
void vertCenterWave(uint32_t c1, uint32_t c2, uint32_t tick, uint32_t duration)
{
uint32_t elapsed_time = 0;
uint32_t ticker = 0;
while (elapsed_time < duration)
{
for(uint16_t i=0; i < LED_COUNT; i++)
{
if (((abs(MAX_Y/2 — Positions[i*2+1]) / 3) % 3 == ticker % 3))
{strip.setPixelColor(i, c1);}
else
{strip.setPixelColor(i, c2);}
}
strip.show();
delay(tick);
ticker++;
elapsed_time += tick + 5;
}
}
/********************************************************/
void setBlock(uint32_t block, uint32_t c)
{
uint32_t y_pos;
for(uint16_t i=0; i<strip.numPixels();i++) {
y_pos = Positions[i*2+1];
if (y_pos/(MAX_Y/6) == block)
{ strip.setPixelColor(i,c); }
}
strip.show();
}
/********************************************************/
void shimmer(uint32_t c_base, uint32_t c_shimmer, uint32_t duration, uint32_t amount)
{
uint32_t shimmer_pixel_num[amount];
float shimmer_pixel_percent[amount];
uint32_t elapsed_time = 0;
for(uint16_t i=0; i < amount; i++)
{ shimmer_pixel_num[i] = 0; }
for(uint16_t i=0; i < strip.numPixels(); i++)
{ strip.setPixelColor(i,c_base); }
while (elapsed_time < duration)
{
// See if we should start a shimmer
for(uint16_t i=0; i < amount; i++)
{
if (shimmer_pixel_num[i] == 0 & random(10) > 8)
{ shimmer_pixel_num[i] = random(199) + 1;
shimmer_pixel_percent[i] = 0.0;
}
if (shimmer_pixel_num[i] > 0)
{
if (i% 2 == 0)
{ shimmer_pixel_percent[i] += 0.02; }
else
{ shimmer_pixel_percent[i] += 0.04; }
if (shimmer_pixel_percent[i] >= 2.0)
{
strip.setPixelColor(shimmer_pixel_num[i],c_base);
shimmer_pixel_num[i] = 0;
}
else
{
strip.setPixelColor(shimmer_pixel_num[i],colorSlope(c_shimmer,c_base,abs(1.0 — shimmer_pixel_percent[i])));
}
}
}
strip.show();
delay(50);
elapsed_time += 50 + 5;
}
for(uint16_t i=0; i < strip.numPixels(); i++)
{ strip.setPixelColor(i,c_base); }
strip.show();
}
Такой фокус работает не всегда. Бывает и так, что в коде используются данные которых просто нет в библиотеке Adafruit_WS2801_Library. Тут уже нужно править код.
P.S. Такой же метод я попробовал для цветомузыки
Правда пришлось удалить одну строчку кода, но и без нее все работает хорошо. Теперь можно не покупать новую ленту, а использовать старую WS2801 для гирлянды или цветомузыки.
Наверное просто коряво оформлено.
if (abs(hueCurrent — hueDestination) < hueStep) {
hueDestination = random(255);
hueStep = ((hueCurrent < hueDestination) && (hueStep < 0))? hueStep: -hueStep;
}
hueCurrent += hueStep;
pushLed(hueCurrent);
FastLED.show();
delay(UPDATE_DELAY);
}
github.com/evilgeniuslabs/tree-v2
А это так…
Неужели кто-то реально сидит возле елки и переключает режимы?
Я этот скетч немного поковырял, вынес разные эффекты в отдельные функции и добавил переключение режима кнопкой, но и в оригинале оно достаточно бодро и радостно мигает.
Главная загвоздка была в том, где у гирлянды начало.
Тут вся схема. _5 Вольт, земля и подключить диоды к 11 и 13 контактам ардуины. На сайте таких поделок достаточно.
А так все необходимое легко на али находится.
P.S. Тема носит информационный характер.
P.S.: Синдром парных случаев. Или новогодний синдром? Как раз вокруг меня ленты, модули, ESP8266, Arduino…
Но мозг говорит, что руки под дилдо заточены, чтобы хотеть.
Вот уже второй год у меня будет трудится на елке библиотека эффектов WS2812 FX.
Но вот это видео покорило и я жду от автора скетча для арудино
По мне так, отличная визуализация.
stephenculley.blogspot.ru/2016/10/christmas-tree-led-pixel-ws2811-t-1000s.html
Только беда в том, что исходники для T1000S Controller.
Для ардуины обещает…
Там есть драйвер и демка. Если демка не нравится, то этот драйвер можно использовать для своих эффектов.
github.com/MartyMacGyver/ESP32-Digital-RGB-LED-Drivers/blob/master/arduino-esp32/demo1/esp32_digital_led_lib.h#L100
Но можно просто перепробовать все по очереди (если нет белого канала, то RGBW можно пропустить, конечно).
эффекты гиморно рисовать
сегодня в корпус засуну и у меня косяк был со старой лентой, там не светодиоды с мозгами, а 8211 мелкасхема отдельно, а ей на вход надо 5в, 3.3 уже не тянет
зато у меня была плашка на 8 диодов с мозгами и она переваривает 3.3, а на выходе там им еще воткнули буферный усилитель, чтоб сигнал не искажался на длинных линиях при 800кгц и вот на выходе там 5в, которые я подаю в ленту
надо только в скетче количество диодов поменять
сегодня может запилю обзор
russian.alibaba.com/product-detail/waterproof-led-back-light-3pcs-smd-5050-rgb-pixel-ws2801-digital-led-module-60701366372.html?spm=a2700.8699010.normalList.2.5525498fPf1F2Z вот такой