Using an SD card to read multiple large matrices of integers

Hi,

I’m working on a project where I use an Arduino Uno together with a Gameduino touchscreen to control an individually addressable LED strip (300 leds). I want to convert an image of 300 pixels width to be displayed on the ledstrip (so it will loop over the height amount of pixels). As an example, I took an image of Van Gogh’s Starry night, and converted it such that I have a matrix of 300 by 169 rgb values (so 900 by 169). As this was too much memory allocation for my Uno, I only took a 900 by 16 array, and managed to makes this work by storing the values in PROGMEM, and reading them out in my function. This works, and looks pretty cool as well!

However, I wanted to try to store the full 900 by 169 array, and preferably multiple ‘images’.
The way I store these values now is as follows:

const uint8_t StarryNight[16][900] PROGMEM = {
{251, 242, 63, …, 0, 56, 126},
{245, 235, 60, …, 239, 233, 0}
etc.
}

I was wondering if there is a way to similarly store this information on an SD card and read it as soon as I press the ‘starry night’ button on my touchscreen.

I tried the example of the SD library:

while (myFile.available()) {
Serial.write(myFile.read());
}

However, this seems a very inefficient method to read out every character, and it will take a long time before it is loaded completely. So my first question is, is it possible to just store a bunch of arrays on the SD card as a sort of extended flash memory as with PROGMEM. Alternatively, is there an efficient way to create a similar array by reading a txt (or different) file. If so, how would I do that (efficiently). I use a Python script to read out the RGB values and create the array basically, so that is something that only has to be done once so it would be cool if you guys have some tips on creating an easy to read file.

For those interested in how I use the array to set the ledstrip (for now it loops over the first 16 rows of pixels of the starry night image and than back up and down again, until I press a button on my touchscreen:

void starrynight() {

      int y = 16;
      uint8_t R_val;
      uint8_t G_val;
      uint8_t B_val;

      while(true){
      for(int i=0; i<y; i++) { 
        GD.get_inputs();
        if (GD.inputs.tag == 0 || GD.inputs.tag == 207){
          for(int k = 0; k < LED_COUNT; k++) {                                             // this forloop sets all LEDs
              int R_val = pgm_read_byte(&(StarryNight[i][0 + 3*k]));
              delayMicroseconds(0);
              int G_val = pgm_read_byte(&(StarryNight[i][1 + 3*k]));
              delayMicroseconds(0);
              int B_val = pgm_read_byte(&(StarryNight[i][2 + 3*k]));
              delayMicroseconds(0);
            strip.setPixelColor(k, strip.Color(R_val, G_val, B_val));   
          }
         strip.show();
         delay(100);
      }
      else{
        return;
      }
    } 
    for(int i=15; i>-1; i--) { 
        GD.get_inputs();
        if (GD.inputs.tag == 0 || GD.inputs.tag == 207){
          for(int k = 0; k < LED_COUNT; k++) {                                             // this forloop sets all LEDs
              int R_val = pgm_read_byte(&(StarryNight[i][0 + 3*k]));
              delayMicroseconds(0);
              int G_val = pgm_read_byte(&(StarryNight[i][1 + 3*k]));
              delayMicroseconds(0);
              int B_val = pgm_read_byte(&(StarryNight[i][2 + 3*k]));
              delayMicroseconds(0);
            strip.setPixelColor(k, strip.Color(R_val, G_val, B_val));   
          }
         strip.show();
         delay(100);
      }
      else{
        return;
      }
    }
  } 
}

It would be really cool to expand this to the full image or even multiple images. I looked into the flash memory of the Mega, which should be large enough to fit 1 full image, so I ordered one of those. but then the question still remains if I can store multiple images. I hope someone can help me out :slight_smile:

(deleted)

Hi Peter,

I'm doing okay, thanks! I hope you are too :slight_smile:

I tried looking into the definitions, but I'm not sure if I got the right idea here.
I read a post that explained the union definition to be 'as a hotel', where you can store different information that will use the same memory location, but only use that bit of information when it's called.

Do I understand it correctly, that I could just create such a union of different images, lets say a StarryNight and a Mona Lisa array of RGB values in that union, and than at the time of pressing the corresponding button select which part of the union to use. Or create the union once with a standard notation of the array, and than at button press time, allocate the correct values to the union. And would this than dismiss the need for the SD card at all. Or would I still need to find a way to read in the values from the SD card into the union.