Я сделал с потенциометром, добавил биения языков, а автор по учёному алгоритм сделал с кучей регулировок (что и позволило приделать потенциометр к месту).
// Алгоритм огня для светодиодной адресной матрицы
//
// Автор: Роман Исаков, 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);
}
Поищите поиском. Где-то обсуждалось. Там всё очень непросто.
Удалось ли вам найти пример с эффектом огня на NeoPixel?
Уже 3 года прошло с момента вашего поста, а в Интернете до сих пор не нахожу таких примеров.
Вроде, я где-то видел. А, ну да - посмотрите у Гивера. А также, вот здесь.
Спасибо
Спасибо
Вот это - огонь!
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); }