//Perlin noise fire procedure 
//16x16 rgb led matrix demo
//Yaroslaw Turbin, 22.06.2020 

#include "FastLED.h"
 
// Matrix size
#define NUM_ROWS 7
#define NUM_COLS 3
#define NUM_LEDS NUM_ROWS * NUM_COLS
 
// LEDs pin
#define DATA_PIN 5   
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
 
// LED brightness
#define BRIGHTNESS 255
#define MAX_POWER_MILLIAMPS 700 
 
// Define the array of leds
CRGB leds[NUM_LEDS];

// DEFINE_GRADIENT_PALETTE(firepal) { // белая, желтая, красная палитра
//   0,  0,  0,  0, //black
//   32,  255,  0,  0, // red
//   190,  255,  255,  0, //yellow
//   255,  255,  255,  255 // white
// };

DEFINE_GRADIENT_PALETTE(firepal) { // красная палитра
  0,  0,  0,  0,     //black
  128,  255,  0,  0, // red
  255,  255,  0,  0  // red
};

CRGBPalette16 myPal = firepal;


void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_POWER_MILLIAMPS);
  FastLED.setBrightness(BRIGHTNESS);
}
 
void loop() {
  int scalexy = 80;  // масштаб
  float speed = 1.2; //скорость 

  float a = millis()*speed;
  for (int i = 0; i < NUM_COLS; i++) {
    for (int j = 0; j < NUM_ROWS; j++) {
      leds[XY(i, j)] = 
      ColorFromPalette(myPal, qsub8(inoise8(i * scalexy, j * scalexy + (int)a, (int)a / 2), abs8(j - (NUM_ROWS - 1)) * 255 / (NUM_ROWS + 2)), 255);
    }
  }
  FastLED.show();
}

uint8_t XY (uint8_t x, uint8_t y) {  //матрица идет от нижнего левого угла вверх и дальше зигзагом 

  const uint8_t XYTable[] = {
     6,   7,  20,
     5,   8,  19,
     4,   9,  18,
     3,  10,  17,
     2,  11,  16,
     1,  12,  15,
     0,  13,  14
  };

  uint8_t i = (y * NUM_COLS) + x;
  uint8_t j = XYTable[i];
  return j;
}

// uint16_t XY (uint8_t x, uint8_t y) { return (y * NUM_COLS + x);}  // для эмулятора