А похвалимся художественной самодеятельностю на WS2812?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А до репитеров раскидайте матрицы по разным пинам, к примеру, да выводите на все разом (не с гледиатора, а fastled-ом, к примеру). По питанию будет такая же нагрузка. Сразу и узнаете - сигнал ослабевает или БП плох.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А причем тут сигнальная линия, тут именно питание. Диод сам себе репетир. По питанию нужно толстыми проводами  подпаяться  к середине, потом к серединам половинок  и тд ленты , как бц усилить шитающую шину. Там токи не маленткие получаются. 

А шкаф навел на мысль, что из куска ленты получится очень неплохая гаишная люста :)

romster
Offline
Зарегистрирован: 15.04.2013

я уже вроде писал, про то, что глюки появляются в конце последовательности матриц(с 3-й и до 6-й), ладно выложу фотки, там сразу понятней будет.

romster
Offline
Зарегистрирован: 15.04.2013

https://ibb.co/kGXivG

фотка с ПК в программе glediator

https://ibb.co/jYMU2w

как это работает на светодиодной панели

https://ibb.co/gdibhw

вроде все хорошо, но если убавить яркость, то начинается, см. далее

https://ibb.co/mqkHpb

вот такого типа артефакты.

Панель стостоит из 6-ти матриц 10х10, 2 ряда по 3 в каждом:

123

456

Питание подходит к каждой матрице параллельно. Странно, что при максимальной нагрузке на БП FSP 300w белый цвет, никаких глюков не наблюдается, а при снижении интенсивности свечения (примерно до 30%) калбасит пол экрана. При чем первая матрица всегда стабильно работает, даже когда выбран самый минимум свечения (диоды на ней тусклю тлеют нужным цветом), а все остальные калбасятся.

arduinec
Онлайн
Зарегистрирован: 01.09.2015

romster пишет:

при снижении интенсивности свечения (примерно до 30%)

А интенсивность свечения как снижается: программным путём или аппаратным?

romster
Offline
Зарегистрирован: 15.04.2013

arduinec пишет:

romster пишет:

при снижении интенсивности свечения (примерно до 30%)

А интенсивность свечения как снижается: программным путём или аппаратным?

программным, ползунок в glediator.

arduinec
Онлайн
Зарегистрирован: 01.09.2015

romster пишет:

arduinec пишет:

romster пишет:

при снижении интенсивности свечения (примерно до 30%)

А интенсивность свечения как снижается: программным путём или аппаратным?

программным, ползунок в glediator.

Давали уже совет в посте #51: подать на все светодиоды одинаковый цвет с помощью библиотеки FastLED (например). Затем подать тот цвет на 30-50% меньше.

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

romster пишет:

вроде все хорошо, но если убавить яркость, то начинается...

Почитал датащит и не нашел ничего про конденсаторы. думаю в нем проблема. Логика такая, когда яркость большая передаются на лампы значения яркости "большие", так как они передаются интервалами. А когда значения яркости маленькие их импульсы "короче" и они "съедаются" конденсаторами... как то так.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вобщем, посмотрел я свои пиксели на 2801 - стоит четыре резистора и кондер. Номиналов под пластиком не видать, но я нашел на алиэкспрессе картинку модуля без корпуса: https://ae01.alicdn.com/kf/HTB1BJYuHVXXXXbhXpXXq6xXFXXX6/10-F14-9-WS2801.jpg

По даташиту резисторов должно быть 6 шт (по 2шт на канал), но, как я понял, китайцы на печатке сделали один общий и три индивидуальных. Видать - это как-то портит "картинку" по формировании цвета. Потому что я вот сейчас прям вижу, что при Fadeout пурпурного пикселя он превращается в красный, а фиолетовый скатывается в синий. А под конец еще и мерцает на малой яркости. Управляю ими через fastled (допускаю, что он неправильно может перемешивать, но мерцание - это явно проблемы внутричиповых ШИМ-ов).

Специально этот вопрос не исследовал, так как на ёлке это не особо важно, а даже и забавно смотрится, но вот на каком-нить панно, конечно, случился бы конфуз. 

romster
Offline
Зарегистрирован: 15.04.2013

sadman41 пишет:

А до репитеров раскидайте матрицы по разным пинам, к примеру, да выводите на все разом (не с гледиатора, а fastled-ом, к примеру). По питанию будет такая же нагрузка. Сразу и узнаете - сигнал ослабевает или БП плох.

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

romster
Offline
Зарегистрирован: 15.04.2013

вот схема включения с 5-й стр. даташита

0.1 мкф шунтирует питание каждого пикселя

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Ясно, Вы просто написали "на вход", я подумал что на din их повесили...
Кстати сейчас дописываю свою новогоднюю гирлянду, как допишу поделюсь

romster
Offline
Зарегистрирован: 15.04.2013

ну да, я поставил один конденсатор шунтирующий питание у первого пикселя каждой из 6-ти матриц панели.

Кстати, конденсаторы видно на фотках, я их припаял со стороны диодов, временно.

з.Ы. утром проверил еще одну интересную вещь, у меня припасены 2 бабины по 300 светодиодов, я подключил их и они не артефачат вообще, при любой интенсивности свечения. Остается дождаться конденсаторов, уже заказал.

https://ibb.co/ftyc5G

Logik
Offline
Зарегистрирован: 05.08.2014

Logik пишет:

А зачем специализированая микросхема? Ардуино справится. БПФ по 64 точкам должно хватить вполне. Можна и больше, но не требуется вроде. Раз в 50мсек набрать 64 отсчета (при дискретизации 10КГц получим 6,4мсек), засунуть в ленту (пусть 500 светодиодов, значить 12мсек)   посчитать БПФ за 50-6,4-12=31,6мсек  вполне реально. Здесь microsin.net/programming/avr/real-time-digital-audio-processing-using-arduino.html   судя по последнему графику за 25мсек считается. Значить еще порядка 6мсек на фильтры, эффекты и прочую лабудень останется.

измерил скорость БПФ из либки

FFT for arduino

guest openmusiclabs.com 8.10.12
 
Для однобайтовой точности при 128 точках  считает за 37мсек. Для 64 точек будет около 15мсек, т.к. сложность его o(n* log(n))
 
 
Logik
Offline
Зарегистрирован: 05.08.2014

В одной из тем  обсуждалось какое максимальное кол-во светодиодов можна подключить. Я там код для безбуферного вывода эффекта  запостил. Нет буфера - нет ограничения по ОЗУ. Перетяну сюда чтоб не терялось.

//прерывания в OutFrame не разрешать!!!!!!!!!
COLOR c;

COLOR m[]={{50,  0, 0},
           {200, 0, 0},
           {250, 50, 0},
           {50,  250, 50},
           {0,   50,  250}
         };
         
void GetColor(word n, word t)
{
  if((n>=t) && (n<t+5))
  {
     c.RED=m[n-t].RED;
     c.GREEN=m[n-t].GREEN;
     c.BLUE=m[n-t].BLUE;
     return;
  }
  c.RED=0;
  c.GREEN=0;
  c.BLUE=0;
}

void loop()
{
  for(;;)
  { 
  for(word t=0;t<40;t++)
  {
   for(word n=0;n<40;n++)
   {
     GetColor(n, t);
     OutFrame(&c, 3);
   }
   asm volatile ("sei \n\t");
   delay(200); 
  }
  }
}

проверен, выводит так https://www.youtube.com/watch?v=mUzARyG3ahw

GennOk
Offline
Зарегистрирован: 30.03.2015

Привет всем! Собрал к Новому году на ATtiny85 вот такие очки очки 2Очки

Имеет пять встроенных эфффектов. Которые циклически меняются. Могут работать от аккумулятора с сотового на 4,2 вольта, но я питаю от маленького повербанка на 2500ма. Будут установлены на шляпу а-ля SteamPunk. Код, может кому пригодится. 

#include <Adafruit_NeoPixel.h>
        
    #define PIN 0
     
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(48, PIN);
     
    uint8_t mode = 0, // Эффект по умолчанию
    offset = 0; // Position of spinny eyes
    uint32_t color = 0xFF0000; // Start red
    uint32_t prevTime;
    //Путь пикселей при змейке - 48 всего
    byte sine1[] = {43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,47,46,45,44,3,2,1,0,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4};
    byte sine2[] = {43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,47,46,45,44,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,1,2,3};

    void setup() {
    pixels.begin();
    pixels.setBrightness(120); // Пол яркости
    prevTime = millis();
    }
     
    void loop() {
    uint8_t i;
    uint32_t t;
    int r = random(255);
    int g = random(255);
    int b = random(255);

     
    switch(mode) {
   case 0: // Хаотичные блики - вспышки разных диодов в разное время!
      i = random(48);
      pixels.setPixelColor(i, color);
      pixels.show();
      delay(15);
      pixels.setPixelColor(i, 0);
      break;
   case 1: // Spinny wheels (Вращение 3 по 3 покругу)
      for(i=0; i<24; i++) {
      uint32_t c = 0;
      if(((offset + i) & 7) < 2) c = color; // 4 pixels on...
      pixels.setPixelColor( i, c); // Первое очко
      pixels.setPixelColor(47-i, c); // Второе очко (инверсия)
      }
      pixels.show();
      offset++;
      delay(80);
      break;
   case 2: // rainbow
     uint16_t i, j;
     for(j=0; j<256; j++) {
      for(i=0; i<24; i++) {
       pixels.setPixelColor(i, Wheel((i+j) & 255));
       pixels.setPixelColor(47-i, Wheel((i+j) & 255));
       }
      pixels.show();
      delay(80);
  }
        break;
   case 3: // Zmeyka1
       for(i=0; i<48; i++) {
        pixels.setPixelColor(sine2[i], pixels.Color(0, 0, 0));
          for (byte j=0; j<8; j++){
            pixels.setPixelColor(sine2[(j+i+1)%48], Wheel((i+j) & 255)); //random RGB color value
          }
        pixels.show();
        delay(80);
      }
      break;
   case 4: // Zmeyka2
      for(i=0; i<48; i++) {
        pixels.setPixelColor(sine1[i], pixels.Color(0, 0, 0));
          for (byte j=0; j<8; j++){
            pixels.setPixelColor(sine1[(j+i+1)%48], Wheel((i+j) & 255)); //random RGB color value
          }
        pixels.show();
        delay(80);
      }
       break;
   case 5: // rainbowCycle
      for(j=0; j<256; j++) { // 5 cycles of all colors on wheel
       for(i=0; i<24; i++) {
        pixels.setPixelColor(i, Wheel(((i * 256 / pixels.numPixels()) + j) & 255));
        pixels.setPixelColor(47-i, Wheel(((i * 256 / pixels.numPixels()) + j) & 255));
        }
       pixels.show();
       delay(80);
}
         break; 
}
     
    t = millis();
    if((t - prevTime) > 8000) { // Каждые< 8 seconds...
    mode++; // Следующий уровень
    if(mode > 5) { // Если последний уровень
    mode = 0; // Уровни сначала
    color >>= 8; // Следующий цвет R->G->B
    if(!color) color = 0xFF0000; // Сброс на красный
    }
    for(i=0; i<48; i++) pixels.setPixelColor(i, 0);
    prevTime = t;
    }
}


// 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 pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
} 
    

 

romster
Offline
Зарегистрирован: 15.04.2013

Прикольно получилось, сразу вспоминается ролик на ютубу "очки нннада ?"

Logik
Offline
Зарегистрирован: 05.08.2014

А мне эти очки про Верку Сердючку напомнили.

GennOk
Offline
Зарегистрирован: 30.03.2015

визуально мои выглядят вот так https://youtu.be/ct7Dk6OK47k

romster
Offline
Зарегистрирован: 15.04.2013

Проблема с артефактами решена, допаял керамику 104 (допаял, не к каждому ws2812b, а через 1 светодиод) и все заработало , как надо, доволен, как слон ))

вот минимальная аркость по Glediator

https://ibb.co/jjDF9w

вот яркость 5О% по Glediator

https://ibb.co/fbX8Uw

вот яркость 1ОО% по Glediator

https://ibb.co/bwrP2G

я не наблюдаю каких либо вспонтанных всплесков яркости, как раньше, все 1 в 1, как на экране ПК в Glediator.

Всех с наступающим Новым Годом !!!    Ура, товарищи!

pasha413
Offline
Зарегистрирован: 27.11.2016

Здравствуйте. Никто не делал на ёлку несколько вертикальных гирлянд на ws2812, как реализовать, весь интернет перерыл, ничего особо не нашел (кроме видео работы). Взял код от звёзды на ws2812 http://samopal.pro/ws2812-5/, но при большом кол-во светодиодов, начинает гаснуть и глючит...
Поделитесь плиз кодом для примера.

arduinec
Онлайн
Зарегистрирован: 01.09.2015

pasha413 пишет:
при большом кол-во светодиодов, начинает гаснуть и глючит

Хватает ли питания всем светодиодам?

romster
Offline
Зарегистрирован: 15.04.2013

А вы готовые гирлянды полоски брали? Может у вас тоже конденсатор керамических нет в обаязке?

pasha413
Offline
Зарегистрирован: 27.11.2016

romster пишет:
А вы готовые гирлянды полоски брали? Может у вас тоже конденсатор керамических нет в обаязке?
у меня 2 ленты по 5м, порезаны на отрезки по 49 светиков (так уж получилось). Попробую по питанию каждой ленты по кондеры подпаять 0.1мкФ.
Кстати: все ленты подключены последовательно, питание подключено вначале первой и в конце последней.

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

pasha413 пишет:
Здравствуйте. Никто не делал на ёлку несколько вертикальных гирлянд на ws2812, как реализовать, весь интернет перерыл, ничего особо не нашел (кроме видео работы). Взял код от звёзды на ws2812 http://samopal.pro/ws2812-5/, но при большом кол-во светодиодов, начинает гаснуть и глючит... Поделитесь плиз кодом для примера.

1. Глюки наступают при падении напряжени на ленте (примерно до 3.3В). Питание лучше подавать параллельно на каждый отрезок ленты

2. Arduino на Atmega329 имеет 2К памяти. Буфер ленты кушает 3Байта на один пиксел. При учете что еще и под программу паямять нужна - максимальное количество диодоы WS2812 - 300-450. Для преодоление этого нужно менять контроллер с большим количеством памяти - Atmega2560/ESP8266/ESP32. А еще лучше купить специализированный T1000S в котором можно эффекты задавать вплоть до захвата видео с экрана

3. Ленты WS2812 последнее время идут очень низкого качества - глюки постоянны. Конденсаторы всех мастей помогают, но не очень сильно. Приходится кобинировать различными участками добиваясь максимального результата.

4. При работе большого количества WS2812 блок питание должне быть с запасом и иметь минимальные пульсации на выходе.

pasha413
Offline
Зарегистрирован: 27.11.2016

Пробовал на esp8266, ничего не меняется. Скорее всего дело в ленте, в прошлом году на ёлке висела лента 5м и проблем не было, в этом году порезал ее на отрезки.

romster
Offline
Зарегистрирован: 15.04.2013

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

Logik
Offline
Зарегистрирован: 05.08.2014

И не только ленты испоганились. Купил два десятка  дискретных WS2812b, так без плясок с обвязками дето треть глючит. Если лента длинная то я бы питал ей с двух концев и про подключение питания посреди ленты думал. Ну и конденсаторы - электролиты с низким внуиренним сопротивлением и керамикой не побрезговал бы.

pasha413
Offline
Зарегистрирован: 27.11.2016

На моих лентах стоят конденсаторы, добавил по 1мкФ на входе каждой ленты. запустил на Wemod D1 mini

Самое интересное, что когда отключил подпитку с другого конца гирлянды перестали глючить (мерцать белым цветом) ленты, только 6я в конце периодически не работает (питалова нехватает). Блок питания стоит на 8А.

romster
Offline
Зарегистрирован: 15.04.2013

Я к своей сборке из 20*30 =600 диодов подпаивал только керамику, и все заработало. А сборка из 10*10 без кирамики от ардуины питается и все отлично.

pasha413
Offline
Зарегистрирован: 27.11.2016

Здравствуйте. никак не могу осилить, наверное простейший код:

имеется 3 гирлянды по 4 светодиода, общее число 12

#define lights_number 3    // Число гирлянд
#define lights_pixel 4         // Число светодиодов в гирлянде
#define total_pixels  lights_pixel*lights_number // общее число светодиодов

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

pasha413
Offline
Зарегистрирован: 27.11.2016

Допустим такой пример, как запустить 3 ленты паралельно?

#include "FastLED.h"          // библиотека для работы с лентой

#define ray_number  3          // Число лучей
#define ray_pixel   4          // Число пикселей в луче
#define led_count ray_pixel*ray_number  // число светодиодов
#define led_pin      6          // пин, куда подключен DIN ленты
struct CRGB leds[led_count];

void setup() {
  LEDS.setBrightness(15);  // ограничить максимальную яркость
  LEDS.addLeds<WS2812, led_pin, GRB>(leds, led_count);  // настрйоки для нашей ленты (ленты на WS2811, WS2812, WS2812B)
  LEDS.show();             // отослать команду
}

void loop() {
  for(int i = 0; i < led_count; i++) { 
    leds[i] = CRGB::Blue;
    FastLED.show();
    leds[i] = CRGB::Black;
    delay(250);
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

У фастледа в мануале есть отдельный раздел "параллельный вывод на разные страйпы".

pasha413
Offline
Зарегистрирован: 27.11.2016

sadman41 пишет:

У фастледа в мануале есть отдельный раздел "параллельный вывод на разные страйпы".

нашел только подключение нескольких гирлянд к разным пинам...это немного не то

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

pasha413 пишет:

sadman41 пишет:

У фастледа в мануале есть отдельный раздел "параллельный вывод на разные страйпы".

нашел только подключение нескольких гирлянд к разным пинам...это немного не то

"С точки зрения банальной эрудиции"(с) разные гирлянды можно подключить либо к разным пинам, либо к одному.

Если к разным - "немного не то", то "то" - это все к одному? ;)))

pasha413
Offline
Зарегистрирован: 27.11.2016

да, у меня все ленты (ws2812 последовательно, так меньше проводов).

сейчас пробую подключить каждую на отдельный пин.

pasha413
Offline
Зарегистрирован: 27.11.2016

Вот то что нашел в интернете:

https://47mkr.ru/viewtopic.php?t=2

#include <EEPROM.h>
#include "FastLED.h"
//const int bright_rezistor_pin = A7; // Резистор регулировки яркости (10к)
//const int rainbowspeed_rezistor_pin = A6; // Резистор регулировки скорости смены цвета в радуге (10к)
//const int fps_rezistor_pin = A5; // Общая скорость эффектов (кадров в секунду) (10к)
const int btn_changeeffect_pin = 2; // Кнопка смены эффектов
//const int btn_2_pin = 3; // Резерв
//const int btn_3_pin = 4; // Резерв

int bright_rezistor = 400; // Стартовое значение резистора яркости
int fps_rezistor = 400; // Стартовое значение резистора скорости еффектов (fps)

int btn_changeeffect_flag = 0;
int btn_changeeffect_state = HIGH;
int last_btn_changeeffect_state = HIGH;
long last_btn_changeeffect_debounce_time = 0;
const int debounceDelay = 80;
byte current_effect = 0;
const int eeprom_addr = 4;

int pos = 0;
int pos1 = 0;
bool part_flag = false;
int color_x = 0;

FASTLED_USING_NAMESPACE
#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN_1  12  // Определяем пин для ленты #1
#define DATA_PIN_2  13  // Определяем пин для ленты #2
#define DATA_PIN_3  14  // Определяем пин для ленты #3
//#define DATA_PIN_4  8  // Определяем пин для ленты #4
//#define DATA_PIN_5  9  // Определяем пин для ленты #5
//#define DATA_PIN_6  10 // Определяем пин для ленты #6
//#define DATA_PIN_7  11 // Определяем пин для ленты #7
//#define DATA_PIN_8  12 // Определяем пин для ленты #8

#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    14
#define NUM_STRIPS  3
CRGB leds[NUM_STRIPS][NUM_LEDS];

#define BRIGHTNESS         150  // Стартовое значение яркости
#define FRAMES_PER_SECOND  1   // Стартовое значение скорости эффектов

void setup() {
  Serial.begin(115200); // Для отладки
  
//  pinMode(bright_rezistor_pin, INPUT);
//  pinMode(rainbowspeed_rezistor_pin, INPUT);
//  pinMode(fps_rezistor_pin, INPUT);
  
  pinMode(btn_changeeffect_pin, INPUT);
  digitalWrite(btn_changeeffect_pin, HIGH); // Используем встроенную верхнюю подтяжку
//  pinMode(btn_2_pin, INPUT);
//  digitalWrite(btn_2_pin, HIGH); // Используем встроенную верхнюю подтяжку
//  pinMode(btn_3_pin, INPUT);
//  digitalWrite(btn_3_pin, HIGH); // Используем встроенную верхнюю подтяжку
  
  delay(1000); // 3 second delay for recovery
  
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN_1,COLOR_ORDER>(leds[0], NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE,DATA_PIN_2,COLOR_ORDER>(leds[1], NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE,DATA_PIN_3,COLOR_ORDER>(leds[2], NUM_LEDS).setCorrection(TypicalLEDStrip);
//  FastLED.addLeds<LED_TYPE,DATA_PIN_4,COLOR_ORDER>(leds[3], NUM_LEDS).setCorrection(TypicalLEDStrip);
//  FastLED.addLeds<LED_TYPE,DATA_PIN_5,COLOR_ORDER>(leds[4], NUM_LEDS).setCorrection(TypicalLEDStrip);
//  FastLED.addLeds<LED_TYPE,DATA_PIN_6,COLOR_ORDER>(leds[5], NUM_LEDS).setCorrection(TypicalLEDStrip);
//  FastLED.addLeds<LED_TYPE,DATA_PIN_7,COLOR_ORDER>(leds[6], NUM_LEDS).setCorrection(TypicalLEDStrip);
//  FastLED.addLeds<LED_TYPE,DATA_PIN_8,COLOR_ORDER>(leds[7], NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
  current_effect = EEPROM.read(eeprom_addr);
}


// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, horizont_2, snow_2 };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
  
void loop() {
//  bright_rezistor = map(analogRead(bright_rezistor_pin), 0, 985 ,10 ,255);
//  fps_rezistor = map(analogRead(fps_rezistor_pin), 0, 985 ,5 ,255);
  
  // Городим жуткую защиту от дребезга для кнопки переключения эффектов...
  int btn_changeeffect_reading = digitalRead(btn_changeeffect_pin);
  if(btn_changeeffect_reading != last_btn_changeeffect_state){
    last_btn_changeeffect_debounce_time = millis();
  }
  if((millis() - last_btn_changeeffect_debounce_time) > debounceDelay) {
    if(btn_changeeffect_reading != btn_changeeffect_state) {
      btn_changeeffect_state = btn_changeeffect_reading;
      if(btn_changeeffect_state == LOW && btn_changeeffect_flag == 0){ // Если кнопка нажата...
        current_effect ++; // Увиличиваем номер эффекта
        EEPROM.write(eeprom_addr, current_effect); // Записываем номер эффекта в ЭСППЗУ
        btn_changeeffect_flag = 1;
        if(current_effect > 10){      // Если номер эффекта превышает существующее
          current_effect = 0;        // то отсчет начинается с нуля
        }
      }
      if(btn_changeeffect_state == HIGH && btn_changeeffect_flag == 1){
        btn_changeeffect_flag = 0;
      }
    }
  }
  last_btn_changeeffect_state = btn_changeeffect_reading;
  
  FastLED.setBrightness(bright_rezistor);
  //Serial.println(current_effect);
  //delay(1);
  if(current_effect == 0){
    EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
    gPatterns[gCurrentPatternNumber]();
  }
  if(current_effect == 1){
    rainbow();
  }
  if(current_effect == 2){
    rainbowWithGlitter();
  }
  if(current_effect == 3){
    confetti();
  }
  if(current_effect == 4){
    sinelon();
  }
  if(current_effect == 5){
    juggle();
  }
  if(current_effect == 6){
    bpm();
  }
  if(current_effect == 7){
    horizont_2();
  }
  if(current_effect == 8){
    snow_1();
  }
  if(current_effect == 9){
    snow_2();
  }
  if(current_effect == 10){
    up_to_down_circle();
  }

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/fps_rezistor); 

  // do some periodic updates
  EVERY_N_MILLISECONDS( 1 ) { gHue++; } // slowly cycle the "base color" through the rainbow
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow(){
  // FastLED's built-in rainbow generator
  for(int i=0; i < NUM_STRIPS; i++){
    fill_rainbow( leds[i], NUM_LEDS, gHue, 7);
  }
}

void rainbowWithGlitter(){
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter){
  if( random8() < chanceOfGlitter) {
    for(int i=0; i < NUM_STRIPS; i++){
      leds[i][ random16(NUM_LEDS) ] += CRGB::White;
    }
  }
}

void confetti(){
  // random colored speckles that blink in and fade smoothly
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 10);
  }
  int pos = random16(NUM_LEDS);
  for(int i=0; i < NUM_STRIPS; i++){
    leds[i][pos] += CHSV( gHue + random8(64), 200, 255);
  }
}

void sinelon(){
  // a colored dot sweeping back and forth, with fading trails
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 20);
  }
  int pos = beatsin16(13,0,NUM_LEDS);
  for(int i=0; i < NUM_STRIPS; i++){
    leds[i][pos] += CHSV( gHue, 255, 192);
  }
}

void bpm(){
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int ii = 0; ii < NUM_LEDS; ii++) { //9948
    for(int i=0; i < NUM_STRIPS; i++){
      leds[i][ii] = ColorFromPalette(palette, gHue+(ii*2), beat-gHue+(ii*10));
    }
  }
}

void juggle(){
  // eight colored dots, weaving in and out of sync with each other
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 20);
  }
  byte dothue = 0;
  for( int ii = 0; ii < 8; ii++) {
    for(int i=0; i < NUM_STRIPS; i++){
      leds[i][beatsin16(ii+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
    }
    dothue += 32;
  }
}

void horizont_2(){
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 100);
  }
  if(pos1 > NUM_STRIPS-1) {pos1 = 0; color_x = color_x+1;}
  if(color_x > 3) color_x = 0;
  CRGB color[] = {CRGB(255, 0, 0), CRGB(0, 255, 0), CRGB(0, 0, 255), CRGB(255, 255, 255),
                  CRGB(255, 0, 255), CRGB(0, 255, 255), CRGB(255, 255, 0), CRGB(255, 150, 150)};
  for (int i=0; i <= NUM_LEDS-1; i++){
    leds[pos1][i] = color[color_x];
  }
  pos1 = pos1+1;
}

void horizont_3(){
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 100);
  }
  if(pos1 > NUM_STRIPS-1) pos1 = 0;
  for (int i=0; i <= NUM_LEDS-1; i++){
    leds[pos1][i] = CHSV( gHue, 255, 192);
  }
  pos1 = pos1+1;
}
void snow_1(){
  if(pos1 > NUM_LEDS*2-1) pos1 = 0;
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 50);
  }
  for(int i=0; i < NUM_STRIPS; i++){
    leds[i][NUM_LEDS-pos1/2-1] = CRGB(255, 255, 255);
  }
  pos1 = pos1+1;
}

struct snow_line{   // объявляем структуру для ленты снега
    byte pos;
    long end_time;
    int  start_delay;
} type;
snow_line snow_2_vars[NUM_STRIPS];
void snow_2(){  
  for(int i=0; i < NUM_STRIPS; i++){
    fadeToBlackBy( leds[i], NUM_LEDS, 40);
  }
  
  for(byte i=0; i < NUM_STRIPS; i++){
    if(snow_2_vars[i].pos > NUM_LEDS*2-1){   // Если дошли до конца ленты то...
      snow_2_vars[i].pos = 0;              // Сбрасываем позицию на ноль
      snow_2_vars[i].end_time = millis();  // Записываем время окончания эффекта
      
    }
    if(snow_2_vars[i].pos == 0){           //  Если задана нулевая позиция - значит начало, то...
      snow_2_vars[i].start_delay = random(10, 3000);    // Генерируем врменную задержку запуска эффекта (до 3х секунд)
    }
    if(millis() > snow_2_vars[i].end_time+snow_2_vars[i].start_delay){  // Если вышла задержка перед запуском эффекта, запускаем...
      leds[i][NUM_LEDS-snow_2_vars[i].pos/2-1] = CRGB(255, 255, 200);
      if(NUM_LEDS-snow_2_vars[i].pos/2-1 > 0 && NUM_LEDS-snow_2_vars[i].pos/2-1 < NUM_LEDS){
        leds[i][NUM_LEDS-snow_2_vars[i].pos/2-2] = CRGB(20, 20, 20);
      }
      snow_2_vars[i].pos++; 
    }
  }
}

void up_to_down_circle(){
//  Serial.print("pos=");
//  Serial.print(pos);
//  Serial.print(" pos1=");
//  Serial.println(pos1);
  if(!part_flag){
    if(pos < pos1){ pos = NUM_LEDS-1; pos1++; }
    if(pos1 >  NUM_LEDS-1){ /*pos1 = 0*/; part_flag = !part_flag; }
    
    for(int i=0; i < NUM_STRIPS; i++){
      for(int n=NUM_LEDS-1; n >= pos1; n--){
        leds[i][n] = CRGB( 0, 0, 0); // гасим всё кроме собранных внизу
      }
      //fadeToBlackBy( leds[i], NUM_LEDS, 30);
    }
    
    for (int strip=0; strip < NUM_STRIPS; strip++){
//      leds[strip][pos] = CHSV( gHue, 255, 255);
      leds[strip][pos] = CHSV(random8(), random8(), random8());
    }
    pos = pos-1;
  } else {
    if(pos == 23 && pos1 == 25){pos = 0; pos1 = 24;} // Если старт этой части эффекта, то перезадаём позиции
    for(int i=0; i < NUM_STRIPS; i++){
      for(int n = 0; n < NUM_LEDS-1-pos1; n++){
        leds[i][n] = CRGB( 0, 0, 0); // гасим всё кроме собранных ВВЕРХУ
        //Serial.println(n);
        //delay(100);
      }
    }
    for (int strip=0; strip < NUM_STRIPS; strip++){
      leds[strip][pos] = CHSV( gHue, 255, 255);
    }
    pos--;
    if(pos < 0){ pos = NUM_LEDS-1-pos1; pos1--; }
    if(pos1 <= 0) {part_flag = !part_flag; pos1 = 1; pos = -1;}
  }
}

это последний код. но как в последнем видео не работает! 

Вот мое видео https://yadi.sk/i/DIi0ySqskVmQvA

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Дак нормально работает, как по мне. Всё параллельно выводится. 

romster
Offline
Зарегистрирован: 15.04.2013

Ох, ну и толсты у вас там провода))) в ролике

pasha413
Offline
Зарегистрирован: 27.11.2016

romster пишет:
Ох, ну и толсты у вас там провода))) в ролике

То что было, это остатки от ленты, чтоб всю не тягать, проверяю на кусках.
В коде не работает заполнение снизу вверх и наоборот

romster
Offline
Зарегистрирован: 15.04.2013

pasha413 пишет:

... как запустить 3 ленты паралельно?

Целый час мы репетируем, ради этого я позволил изуродовать свой собственный сарай... (с)

А если серьезно, ленты без особых проблем параллелятся и все работает.

https://youtu.be/d4zjO4964ds вот так.

pasha413
Offline
Зарегистрирован: 27.11.2016

А можно взглянуть на код? Интересует реализация эффектов.

romster
Offline
Зарегистрирован: 15.04.2013

pasha413 пишет:
А можно взглянуть на код? Интересует реализация эффектов.

Пример из Adafruit_NeoPixel-> strandtest


//вот кусок кода от туда 

void loop() {
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue

}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

 

pasha413
Offline
Зарегистрирован: 27.11.2016

Да, простые эффекты я пробовал, но как-то не понравилось.

romster
Offline
Зарегистрирован: 15.04.2013

Я полностью с Вами согласен, нужно придумывать или искать готовые, а то эти эффекты похожи на бестолковые гирлянды, которые продают повсюду перед новым годам, не для того ведь мы с Вами паяли WS2812, чтоб бегущие огни демонстрировать.

я вот хотел бы такой эффект:

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

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

З.Ы. в Glediator можно эффектов понаделать, но нужен комп или малинка какая нить.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Подскажете может - есть ли на алиэкспрессах варианты облегченных страйпов на адресных диодах? Чтобы не лентой, а косичкой и светики мелкие были, а не с палец толщмной? Хотя, наверное, там провода толстые будут энивэй...

pasha413
Offline
Зарегистрирован: 27.11.2016
romster
Offline
Зарегистрирован: 15.04.2013

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

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Они все какие-то... для монтирования в панель. На окне такие конструкции ужасно смотрятся развешенными, если шторкой не прикрывать, конечно.

romster
Offline
Зарегистрирован: 15.04.2013

sadman41 пишет:

Они все какие-то... для монтирования в панель. На окне такие конструкции ужасно смотрятся развешенными, если шторкой не прикрывать, конечно.

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