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

#include "FastLED.h"
 
// Matrix size
#define NUM_ROWS 12
#define NUM_COLS 4
#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 = 60;  // масштаб
  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[] = {
    11,  12,  35,  36,
    10,  13,  34,  37,
     9,  14,  33,  38,
     8,  15,  32,  39,
     7,  16,  31,  40,
     6,  17,  30,  41,
     5,  18,  29,  42,
     4,  19,  28,  43,
     3,  20,  27,  44,
     2,  21,  26,  45,
     1,  22,  25,  46,
     0,  23,  24,  47
  };

  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);}  // для эмулятора