#include <Adafruit_NeoPixel.h>

// This program displays a scrolling image on a 16x16 LED array or string of arrays.

#define PIN      6  // change to whatever pin you are using to send data to the LED array.
#define N_LEDS 256  // must be (number of pixels per array)*(number of arrays being used)
#define imageRows 16  // the size of the image that is going to be displayed.  Height normally 16.
#define imageCols 285  // Change this number depending on the width of your scrolling image.
// number of rows and columns in each LED panel
#define numRows 16
#define numCols 16

Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);

int numPanels = N_LEDS/numRows/numCols;
int offset = numCols*numPanels;
int pixel = 0;
int imageStartCol = 0;
int imageRow = 0;
int imageCol = 0;
int r=0;
int g=0;
int b=0;

// the image data is stored in program memory (flash memory), because there is not enough RAM in an Arduino to store the whole image.
const uint8_t pc[imageRows][imageCols][3] PROGMEM = 
#include "bonneFeteDesMeres285x16.h"   // write the name of the text file where the image data is stored.
;

void setup() {
  strip.begin();
  
}

void loop() {
  
  offset--;
  if (offset < -imageCols) {
    offset = numCols*numPanels;
  }

  pixel = 0;
  
  for(int panel=0; panel<numPanels; panel++) {
    imageStartCol = panel*numCols-offset;
    imageRow = 0;
    for (int y=0; y<numRows/2; y++) {
      for (int x=numCols-1; x>=0; x--) {
        imageCol = imageStartCol + x;
        if ((imageCol < 0) || (imageCol >= imageCols)) {
          drawPixel(strip.Color(0, 0, 0)); // Draw black
        }
        else {
          r = int(pgm_read_byte_near(&pc[imageRow][imageCol][0]));
          g = int(pgm_read_byte_near(&pc[imageRow][imageCol][1]));
          b = int(pgm_read_byte_near(&pc[imageRow][imageCol][2]));
          drawPixel(strip.Color(r, g, b)); // Draw image pixel
        }
        pixel++;
      }
      imageRow++;
      for (int x=0; x<numCols; x++) {
        imageCol = imageStartCol + x;
        if ((imageCol < 0) || (imageCol >= imageCols)) {
          drawPixel(strip.Color(0, 0, 0)); // Draw black
        }
        else {
          r = int(pgm_read_byte_near(&pc[imageRow][imageCol][0]));
          g = int(pgm_read_byte_near(&pc[imageRow][imageCol][1]));
          b = int(pgm_read_byte_near(&pc[imageRow][imageCol][2]));
          drawPixel(strip.Color(r, g, b)); // Draw image pixel
        }
        pixel++;
      }
      imageRow++;
    }
  }
  strip.show();
  delay(25);  // you can change this number to change the scrolling speed.  Smaller number will be faster scrolling.

}


static void drawPixel(uint32_t c) {
  strip.setPixelColor(pixel , c); // Draw new pixel
}
