Help with performance and memory limits on Uno + TFT + SD

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
kipbot
 
Posts: 31
Joined: Sat May 04, 2013 3:43 pm

Help with performance and memory limits on Uno + TFT + SD

Post by kipbot »

I'm trying to manage the display of items on 2.8 TFT LCD Breakout Board driven by Uno and the SD breakout Breakout Board (all from Adafruit). Ideally I'm hoping to be able to read a card and grab files randomly and display them or put 100 files on a card and access them directly for display. I have two chunks of code that seem to be hitting the limits of what the system will do:

Code: Select all

void loop()
{
        bmpDraw("mdcLogo.bmp", 0, 0); pauseAndClear(); 
        bmpDraw("d2d001.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d002.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d003.bmp", 0, 0);  pauseAndClear(); bmpDraw("msn01.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d004.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d005.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d006.bmp", 0, 0);  pauseAndClear(); 
        bmpDraw("d2d007.bmp", 0, 0);  pauseAndClear();bmpDraw("msn05.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d008.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d009.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d010.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d011.bmp", 0, 0);  pauseAndClear();bmpDraw("MSN06.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d012.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d013.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d014.bmp", 0, 0);  pauseAndClear();;bmpDraw("MSN08.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d016.bmp", 0, 0);  pauseAndClear();  
        bmpDraw("d2d017.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d018.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d040.bmp", 0, 0);  pauseAndClear();bmpDraw("mdcLogo.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d045.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d042.bmp", 0, 0);  pauseAndClear();
        //bmpDraw("d2d022.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d023.bmp", 0, 0);  pauseAndClear();bmpDraw("MSN02.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d024.bmp", 0, 0);  pauseAndClear();
        //bmpDraw("d2d025.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d026.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d049.bmp", 0, 0);  pauseAndClear();bmpDraw("mdcLogo.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d028.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d029.bmp", 0, 0);  pauseAndClear();
        //bmpDraw("d2d030.bmp", 0, 0);  pauseAndClear();
        //bmpDraw("d2d031.bmp", 0, 0);  pauseAndClear();bmpDraw("MSN08.bmp", 0, 0); pauseAndClear();
       // bmpDraw("d2d051.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d033.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d034.bmp", 0, 0);  pauseAndClear();bmpDraw("mdcLogo.bmp", 0, 0); pauseAndClear();
        bmpDraw("d2d037.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d038.bmp", 0, 0);  pauseAndClear();
        bmpDraw("d2d041.bmp", 0, 0);  pauseAndClear();

}
And struggling with PROGMEM for arrays (and how to pass file names to bmpDraw) in this code:

Code: Select all

void loop()
{
  
  PROGMEM char* files[] = {
      "d2d001.bmp", "d2d002.bmp", "d2d003.bmp", "d2d004.bmp", "MSN01.BMP",
      "d2d005.bmp", "d2d006.bmp", "d2d007.bmp", "d2d009.bmp", "d2d010.bmp", 
      "d2d011.bmp", "d2d012.bmp", "d2d013.bmp","d2d014.bmp",  "MSN02.BMP",   
      "d2d016.bmp", "d2d017.bmp", "d2d018.bmp","d2d019.bmp", "MSN03.BMP" 
  };
  
  
  PROGMEM char* files2[] = {
      "d2d020.bmp", "d2d021.bmp", "d2d022.bmp", "d2d023.bmp", "MSN08.BMP", 
      "d2d025.bmp", "d2d027.bmp", "d2d028.bmp","d2d029.bmp", "MSN05.BMP",
      "d2d030.bmp", "d2d032.bmp", "d2d033.bmp","d2d034.bmp", "MSN06.BMP",     
      "d2d035.bmp", "d2d037.bmp", "d2d038.bmp","d2d039.bmp","MSN07.BMP"
  };
  
  bmpDraw("mdcLogo.bmp", 0, 0); pauseAndClear();
  for( int i = 0 ; i < 20 ; i++){
    bmpDraw( files2[i], 0 , 0);
    pauseAndClear();
  }

  for( int i = 0 ; i < 11 ; i++){
    bmpDraw( files[i], 0 , 0);
    pauseAndClear();
  }  
}
In both cases, I seem to be able to use a certain number of items (either commands in the first loop() or items in the array in the second). The system responds with succesive white wipes of the screen. I'm fairly certain it's a memory problem, but I'm not sure what the limits are of an Uno, or how much farther I could push it.

I'm in new territory, so I hope I'm writing this up properly!

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: Help with performance and memory limits on Uno + TFT + S

Post by adafruit_support_bill »

Not sure what the compiler does with a local variable that is declared PROGMEM. It can't really be both. Try moving all your PROGMEM arrays out to global scope.

You can use freeRam() to monitor your actual SRAM usage: http://learn.adafruit.com/memories-of-a ... ree-memory

User avatar
kipbot
 
Posts: 31
Joined: Sat May 04, 2013 3:43 pm

Re: Help with performance and memory limits on Uno + TFT + S

Post by kipbot »

Any tips on where I can learn how to reference those arrays when they're outside of loop() and when I'm calling bmpDraw?

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: Help with performance and memory limits on Uno + TFT + S

Post by adafruit_support_bill »

If they are declared at file scope they are global. You can access them from anywhere in your code.

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: Help with performance and memory limits on Uno + TFT + S

Post by pburgess »

PROGMEM string arrays are a tricky thing. You have to declare both the individual strings AND the array as PROGMEM. Will also need to modify the bmpDraw function to copy the PROGMEM string to a temporary buffer for passing to the SD library (which requires filenames as normal RAM-based strings).

See the 'Arrays of Strings' section on this page:
http://arduino.cc/en/Reference/PROGMEM

Another idea, since most of your filenames follow a common format (prefix + number + .BMP), is to store an array of numbers instead of strings, then format these into a temporary string buffer before calling bmpDraw(), e.g. something like:

Code: Select all

int files1[] = {
   1,  2,  3,  4, -1, // Positive numbers indicate a d2dXXX file
   5,  6,  7,  9, 10, // Negative numbers are a MSNXX file
  11, 12, 13, 14, -2,
  16, 17, 18, 19, -3};

char filename[13];
// Assuming 'i' is the file number of interest...
if(files1[i] >= 0) {
  sprintf(filename,"d2d%03d.BMP", files1[i]);
} else {
  sprintf(filename, "MSN%02d.BMP", -files1[i]);
}
The integer array could be PROGMEM'd for further savings (using pgm_read_word() to decode).

User avatar
kipbot
 
Posts: 31
Joined: Sat May 04, 2013 3:43 pm

Re: Help with performance and memory limits on Uno + TFT + S

Post by kipbot »

pburgess - thanks so much for this. I'm not grokking it all immediately, but it's a huge help to understanding what's going on. The challenge and the fun of this stuff is that there's always deeper to go. Much appreciated.

User avatar
kipbot
 
Posts: 31
Joined: Sat May 04, 2013 3:43 pm

Re: Help with performance and memory limits on Uno + TFT + S

Post by kipbot »

pburgess - thanks again. I've not fully grokked it yet, but I've got it working and I mostly know why! Simple tight loop and it's running loads of images.

Code: Select all

void loop()
{

  for( int i = 1 ; i < 61 ; i++){ 
    char filename[13];
    sprintf(filename,"d2d%03d.BMP", i);
    bmpDraw( filename, 0, 0); 
    pauseAndClear();    
  }
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”