Огонь на Neopixel

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

Здравствуйте, есть у кого-то код эффекта огня на библиотеке NeoPixel

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

Поищите поиском. Где-то обсуждалось. Там всё очень непросто.

GENDOS13
Offline
Зарегистрирован: 11.08.2022

olegnezhelskiy007 пишет:
Здравствуйте, есть у кого-то код эффекта огня на библиотеке NeoPixel

Удалось ли вам найти пример с эффектом огня на NeoPixel?
Уже 3 года прошло с момента вашего поста, а в Интернете до сих пор не нахожу таких примеров.

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

Вроде, я где-то видел. А, ну да - посмотрите у Гивера. А также, вот здесь.

GENDOS13
Offline
Зарегистрирован: 11.08.2022

Спасибо

lilik
Offline
Зарегистрирован: 19.10.2017

GENDOS13 пишет:

Спасибо

Вот это - огонь!

https://labdata.ru/article/algoritm-ognja-dlja-adresnyh-svetodiodnyh-matric

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

// Алгоритм огня для светодиодной адресной матрицы
// 
// Автор: Роман Исаков, 2020
// (с) LabData.ru

// Параметры подключения 
#define PIN 6
#define x_size 32
#define y_size 8

// Параметры алгоритма
#define fire_dT 75 // задержка обрабобтки модели огня в мс
//#define fire_loss 0.7 // коэффициент потери энергии //удобно менять 0.4-0.9 
   float fire_loss = 0.7;
#define fire_smooth 0.9 // Коэффициент сглаженности распределения энергии частиц
#define sig 0.8 // ширина пламени
  byte razmer = 16;// ширина пламени в пикселях от середины матрицы в обе стороны
#define dlt 80 // общая мощность пламени 
#define mlt 150 // усиление возгорания
//#define Hue 10 // Цвет пламени (0- красный)//удобно менять 0-30
   byte Hue=10;//
#define H0 0
#define H255 60
#define S0 200
#define S255 255
#define V0 0
#define V255 255

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>


Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix( x_size,y_size , PIN,
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_RGB + NEO_KHZ800);


//Картина возгорания
byte fire_frame[y_size][x_size];
//Распределение вероятностей возгорания
byte fire_prob[x_size];
int bienie=1; // биение пламени

void setup (){
SetupMatrix();
}
void loop(){
LDfire();  
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Функция настройки матрицы. Поместить в setup
void SetupMatrix(){
    matrix.begin();
    matrix.clear();
    matrix.show();
    Generate_Prob(sig, mlt); // Создать распределение вероятностей (форма огня)
}

// Сгенерировать распределение вероятностей
void Generate_Prob(float sigma, int mult) {
  for(int i=0; i<x_size; i++){
    fire_prob[i] = round(mult*(1/(sigma*2.5))*exp(-sq(i-(x_size/2))/(2*sq(sigma))));
  }
}

// Функция реализации алгоритма огня. Поместить в loop
void LDfire() {
  bienie=bienie*(-1);
  static uint32_t old_T = 0;
  if (millis() - old_T > fire_dT) { // отслеживание срабатывания
      old_T = millis();
      // Цикл огня
      // 1. Сдвиг матрицы
      for (uint8_t y = y_size - 1; y >0; y--) {
          for (uint8_t x = 0; x < x_size; x++) {
          if(x!=0&&x!=x_size-1){fire_frame[y][x] = fire_frame[y - 1][x+bienie]*fire_loss;}
           else {fire_frame[y][x] = fire_frame[y - 1][x]*fire_loss;}
          }
      }
      // 2. Заполнение нижней строки псевдослучайными числами
      for (uint8_t x = 0; x < x_size; x++) {  
          byte fire_old = fire_frame[0][x];
          fire_frame[0][x] = round(fire_old + (random(fire_prob[x], fire_prob[x]+dlt)-fire_old)*fire_smooth);   
          
      } 
      // 3. Визуализация матрицы
      for (uint8_t y = 0 ; y <= y_size-1 ; y++) {// тут замену < сделал на <=
        for (uint8_t x = 0; x < x_size; x++) {
           if(x<x_size/2+razmer&&x>=x_size/2-razmer){ matrix.drawPixel(x, y, E2Color(fire_frame[y_size-1-y][x]));}
           else{ matrix.drawPixel(x, y, 0 );}
        }
      }
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //регулировка силы пламени
    fire_loss=0.1*map(analogRead(A0),0,1023,5,9);//
    Hue = map(analogRead(A0),0,1023,0,20);//
    razmer=map(analogRead(A0),0,1023,5,16);//
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
      matrix.show();
  }
}
// Функция расчета цвета из энергии частицы
uint16_t E2Color(byte E) {
  byte H = Hue + map(E, 0, 255, H0, H255);
  byte S = constrain(map(E, 0, 255, S255, S0), 0, 255);
  byte V = constrain(map(E, 0, 255, V0, V255), 0, 255);
  return HSV2Color(H,S,V);
}
// Функция перевода из модели HSV в код цвета.
uint16_t HSV2Color(uint8_t hue, uint8_t sat, uint8_t val) {
  uint8_t red, green, blue;
  byte h = ((24 * hue / 17) / 60) % 6;
  byte vmin = (long)val - val * sat / 255;
  byte a = (long)val * sat / 255 * (hue * 24 / 17 % 60) / 60;
  byte vinc = vmin + a;
  byte vdec = val - a;
  switch (h) {
  case 0:  red = val; green = vinc; blue = vmin; break;
  case 1: red = vdec; green = val; blue = vmin; break;
  case 2: red = vmin; green = val; blue = vinc; break;
  case 3: red = vmin; green = vdec; blue = val; break;
  case 4: red = vinc; green = vmin; blue = val; break;
  case 5: red = val; green = vmin; blue = vdec; break;
  } 
  return matrix.Color(green,red,blue);
}