Прошу помощи (управление несколькими лентами WS2812)

sheff
Offline
Зарегистрирован: 14.11.2017

Поздравляю всех с новым годом!
Пытаюсь добавить эффект пламени в гирлянду на окно, фрагмент нужного кода взял в скетче у alexgyvera.
Вот скетч после моего вмешательства
 

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

#define NUM_LEDS 60          // число светодиодов в кольце/ленте
#define PIN1 6             // пин, куда подключен DIN ленты
#define PIN2 7
 CRGB leds1[NUM_LEDS];                // первая лента
 CRGB leds2[NUM_LEDS];                // вторая лента

int max_bright = 55;         // максимальная яркость (0 - 255)
int thisdelay = 25;
// ---------------СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ-----------------

void one_color_all(int cred, int cgrn, int cblu) {       //-SET ALL LEDS TO ONE COLOR
  for (int i = 0 ; i < NUM_LEDS; i++ ) {
    leds1[i].setRGB( cred, cgrn, cblu);
    leds2[i].setRGB( cred, cgrn, cblu);
  }
}

void setup() {
  LEDS.setBrightness(max_bright);  // ограничить максимальную яркость

  LEDS.addLeds<WS2811, PIN1, GRB>(leds1, NUM_LEDS);  // настрйоки для нашей ленты (ленты на WS2811, WS2812, WS2812B)
  LEDS.addLeds<WS2811, PIN2, GRB>(leds2, NUM_LEDS);  // настрйоки для нашей ленты (ленты на WS2811, WS2812, WS2812B)
  one_color_all(0, 0, 0);          // погасить все светодиоды
  LEDS.show();                     // отослать команду

}
//---------------------------------линейный огонь-------------------------------------
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;

  // Step 1.  Cool down every cell a little
  for ( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);

    if (cooldown > heat[i]) {
      heat[i] = 0;
    } else {
      heat[i] = heat[i] - cooldown;
    }
  }

  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for ( int k = NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }

  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if ( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160, 255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for ( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[NUM_LEDS-j] );
  }

  FastLED.show();
  delay(SpeedDelay);
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature / 255.0) * 191);

  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252

  // figure out which third of the spectrum we're in:
  if ( t192 > 0x80) {                    // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if ( t192 > 0x40 ) {            // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
  leds1[Pixel].r = red;
  leds1[Pixel].g = green;
  leds1[Pixel].b = blue;
  leds2[Pixel].r = red;
  leds2[Pixel].g = green;
  leds2[Pixel].b = blue;
}

void loop() {
Fire(55, 120, thisdelay);
  one_color_all(0, 0, 0);

}
[/code]

Помогите пожалуйста с выводом эффекта на несколько лент, у меня получается выводить одинаково на все ленты (16 штук по 60 светодиодов, подключенных к разным пинам), не знаю как выводить с разной последовательностью и высотой "пламени".

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже на просьбу установить в этом помещении биде.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, раз 

sheff пишет:

взял в скетче у alexgyvera

то обращайтесь на профильный форум - https://community.alexgyver.ru/  Там Вам и помогут. Сюда-то чего?

sadman41
Offline
Зарегистрирован: 19.10.2016

Гиверовского кода не вижу тут. Фастледовские экзамплы похоже нарублены в салат.

Jaeger
Jaeger аватар
Offline
Зарегистрирован: 23.03.2018

Fire - функцию нужно выполнять  для каждого канала.

ku-ku
Offline
Зарегистрирован: 14.11.2018

можно пользовать CRGBSet (по 60 штук).

NUM_LEDS у нас 16*60=960.

В основную процедуру нужно добавить перебор этих CRGBSet и в каждом генерить кадр.
Я не настоящий сварщик, всегда думал, что 900 диодов  на одной линии это перебор, но меня тут уже переубедили. Я до сих пор считаю, что это гонево, но коли камраду нужно, то идею я дал. А кодить - то или сам, или рублей 5 вынь, да полож в ветку "ищу исполнителя". Уверен, что р е а л и з у е м о :D
Если чо - это для последовательного вывода, то есть для одного пина. На ESP32 вроде пытаются пилить FastLed для многоножного параллельного вывода, но я хз какие там успехи

ku-ku
Offline
Зарегистрирован: 14.11.2018

а вообще - коли есть 16 каналов по 60 диодов, то это уже по сути матрица. Так зачем изобретать коня, коли оно уже есть готовое!? Для матрицы "фаерок" не один фраерок сочинял. Было бы желание найти.

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

Jaeger пишет:

Fire - функцию нужно выполнять  для каждого канала.

Не факт. Он в setPixel "запаралелил". Но 16 "линейных огней" расположеных рядом и один огонь на 16 лентах - разные вещи. Тут думать надо, что для ТС недопустимо похоже.

Jaeger
Jaeger аватар
Offline
Зарегистрирован: 23.03.2018
В одной из мигалок, которые работают сейчас у меня на окне, есть функция Fire для 2х каналов (лент по 60 лед). Огонек мерцает поразному в лентах благодаря random. (Код не мой):
 
/*
 * Looks like fire! Both channels are seperate and random
 */

void fire() {
  const uint8_t COOLING = 55;
  const uint8_t SPARKING = 50;
  
  // Array of temperature readings at each simulation cell
  static byte heatLeft[N_PIXELS];
  static byte heatRight[N_PIXELS];

  // Step 1.  Cool down every cell a little
  for (int i = 0; i < N_PIXELS; i++) {
    heatLeft[i] = qsub8(heatLeft[i], random8(0, ((COOLING * 10) / N_PIXELS) + 2));
  }

  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for (int k = N_PIXELS - 1; k >= 2; k--) {
    heatLeft[k] = (heatLeft[k - 1] + heatLeft[k - 2] + heatLeft[k - 2]) / 3;
  }

  // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  if (random8() < SPARKING) {
    int y = random8(7);
    heatLeft[y] = qadd8(heatLeft[y], random8(160, 255));
  }

  // Step 4.  Map from heat cells to LED colors
  for (int j = 0; j < N_PIXELS; j++) {
    // Scale the heat value from 0-255 down to 0-240
    // for best results with color palettes.
    byte colorindex = scale8(heatLeft[j], 240);
    CRGB color = ColorFromPalette(CRGBPalette16(CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White), colorindex);
    int pixelnumber = j;
    ledsLeft[pixelnumber] = color;
  }

  // Now do it all again for the right channel
  // Step 1.  Cool down every cell a little
  for (int i = 0; i < N_PIXELS; i++) {
    heatRight[i] = qsub8(heatRight[i], random8(0, ((COOLING * 10) / N_PIXELS) + 2));
  }

  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for (int k = N_PIXELS - 1; k >= 2; k--) {
    heatRight[k] = (heatRight[k - 1] + heatRight[k - 2] + heatRight[k - 2]) / 3;
  }

  // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  if (random8() < SPARKING) {
    int y = random8(7);
    heatRight[y] = qadd8(heatRight[y], random8(160, 255));
  }

  // Step 4.  Map from heat cells to LED colors
  for (int j = 0; j < N_PIXELS; j++) {
    // Scale the heat value from 0-255 down to 0-240
    // for best results with color palettes.
    byte colorindex = scale8(heatRight[j], 240);
    CRGB color = ColorFromPalette(CRGBPalette16(CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White), colorindex);
    int pixelnumber = j;
    ledsRight[pixelnumber] = color;
  }
  FastLED.show();
}

Вероятно по аналогии возможно сделать и для нескольких каналов.

 

ata3d
Offline
Зарегистрирован: 24.05.2017

Вроде и в библиотеке Fastled есть примеры работы с матрицей 16x16 XYMatrix.ino и поиск по "fastled matrix fire" дает кучу ссылок.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Только дело в том, что в примерах фастледа матрица всё равно является длинным страйпом, а не их набором.

ata3d
Offline
Зарегистрирован: 24.05.2017

Куски лент, соединеные последовательно. На 1 пине сделать половину, на 2 другую. продублировав код с заменой переменных.

 

sheff
Offline
Зарегистрирован: 14.11.2017

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

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

Теория по теме огня https://habr.com/post/435122/

sheff
Offline
Зарегистрирован: 14.11.2017

Спасибо, почитал....интересно, но для меня как китайская грамота.