Reading bitmaps from an SD card and displaying on a TFT

I am trying to put together a project which reads a number of bitmap files from an SD card in sequence, and displays them on a TFT.

I’m using the SD.h and TFT.h libraries. < PImage > to load the file from the card and
< screen.image(filename) > to load it to the TFT. It’s pretty much the demo code for doing this (except I’ve now got it full of serial monitor diagnostic messages trying to get to the bottom of what’s going wrong).

So this is what happens. I have six images on the card named 0.bmp through 5.bmp . First time through, all six images are correctly loaded from the card and painted by the TFT. Second time through, again all good. So that’s 12 images been displayed so far. Third time through, still all good. 18 images now. Fourth time through is where it then goes wrong. 0.bmp loads and displays. so does 1.bmp then, at 2.bmp or 3.bmp, instead of the file information being displayed in the serial monitor, it says that the file is not found - even though it has been three times so far. And that’s it then unless I physically reset. It will go on for ever - “4.bmp file not found” “5.bmp file not found” “0.bmp file not found” etc etc

Originally, I was using an incrementing variable to generate the file names to be be loaded, and that worked fine except the same behaviour so I changed to 6 individual calls with the actual file names just in case and still the same. The original hardware was a TFT screen with built in SD card holder. Again, just in case, I today changed to a basic TFT screen with separate SD card board, but results exactly the same.

Processor is an Arduino Nano. That hasn’t been changed.

So has anyone got any ideas what I am doing wrong or what is going wrong ? Or how to get around it even ?

Please bear in mind that I am a total novice at programming and need detailed help that I can learn from. Having been a hardware engineer my entire working life and now retired, I understand that at least …

Thanks

You’re leaking memory somewhere would be my guess. Make SURE you put all your toys away when you finish playing with them.

-jim lee

Thank you Jim, but what exactly does that mean ? Remember, I'm a novice at this trying to learn ...

You better post your code (In code tags or they will beat you up) and everyone here will have a look.

-jim lee

Thanks. I don't actually understand what 'code tags' are. I can post a copy of the code here with all the unnecessary diagnostic stuff removed and it won't amount to much. Are you saying it needs to be put up here in some special way ?

I don't actually understand what 'code tags' are.

Well, there's something you can work on.

-jim lee

arfa_daily:
I don’t actually understand what ‘code tags’ are… Are you saying it needs to be put up here in some special way ?

Use the code tag </> icon top left, or roll your own:

[code] sketch goes here [/code]

Then you get this:

digitalRead(8);

… not digitalRead(8);

So is this right ? I’ve looked for that icon and can find no sign of it. The ‘how to post’ pages in the help show a posting page that doesn’t seem to look anything like what I’ve got here ??

// include the necessary libraries
#include <SPI.h>
#include <SD.h>
#include <TFT.h>  // Arduino LCD library
#include <string.h>

// pin definition for the Nano
#define sd_cs  4
#define lcd_cs 10
#define dc     9
#define rst    8

TFT screen = TFT(lcd_cs, dc, rst);

PImage nextpic;
char filename[20] ;
int imagecount = 0;
int passcount = 1;

void setup() {
   Serial.begin(115200);
   while (!Serial) {
    }

  if (!SD.begin(sd_cs)) {
    Serial.println(F("failed!"));
    return;
  }
  
  Serial.println(F("OK!"));

  screen.begin();
  screen.background(0, 0, 0);  //  Black

  // now that the SD card can be access, try to load the
  // image file.
  
  if (!nextpic.isValid()) {
  Serial.println(F("error while loading xxx.bmp"));
}
}

  void loop() {
    
  screen.background(0, 0, 0);  //  Black
  SD.begin(sd_cs);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("0.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("1.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("2.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("3.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("4.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 screen.background(0, 0, 0);  //  Black
 nextpic = screen.loadImage("5.bmp");
 screen.image(nextpic, 0, 0);
 delay(2000);

//++++++++++++++++++++++++++++++++++++++++++

 passcount=passcount+1; 
}

Yeah that’s right.

Code tags.jpg

arfa_daily, as in Minder?

@arfa_daily,

if you used Quick Reply, then you don't get the command symbols. Just click Preview, and you get them.

I recommend to use Preview in any case, to check for typos and rendering.

jubukraa:
arfa_daily, as in Minder?

Yeah. It was one of my favourite shows ever, and that online name was my jokey salute to Arthur. I've been using it for many years ...

I used to drink in the same pub as Denis Waterman and Rula :wink:

Sweet ...

OK. Back to the problem. I've done some more testing and it definitely seems to be related to the actual reading of the files from the card. If I read in one file once at the start of the sketch, I can then write it to the screen endlessly without issue in the looped code. It has been doing it all night. However, if I read in the same file on each pass through the loop, it fails after 21 or 22 times. So something filling up and overflowing somewhere ?

Sorry if I sound a bit dumb on all this, but I really am a novice at it and am learning by doing stuff and correcting problems that arise as a result, so any (much greater than mine) detailed expertise and insight that anyone can offer would be greatly appreciated. I'm sure that my sketch is probably not very tidy, which may be something to do with the problem, but I have tried to adapt from sample code and tried to preserve the original structure as best I know how. Thanks

For starters you put SD.begin(sd_cs); in your loop so it gets initialized a few million times a second.

-jim lee

Yes, but it doesn't actually make a jot of difference to the problem. It wasn't originally in the loop, the initialisation taking place in the "if" test statement outside the loop that checks if the card initialises. I only copied it into the loop to see if it made any difference to the problem by re-initialising on each pass through the loop. It doesn't. I just commented it back out anyway and reloaded and ran the code. It fell over during the fourth pass exactly as before …

Am I right in thinking that the data read from the SD card is cached somewhere before being passed to the screen driver ? Is it that wherever that area of memory is, it’s getting filled up to the point where it just starts overflowing ?

In the absence of anyone working out what's going wrong, I've come up with a work-around. It's not particularly elegant, but in this particular application, it's not a problem. I have assigned pin 5 to be an output, and set it high at the start of the sketch. I have then hung a 470R resistor between pin 5 and the reset switch. At the end of the pass through all six images, I set the pin low and then after a brief delay, set it high again. This effectively just resets the Nano and the sketch which takes a very short time and barely results in any interruption to the display of the images. I realise that the code to read the images and display them no longer needs to be in a loop as the whole shebang is resetting every time, but it doesn't really make any difference, so I may as well leave it there in case I ever manage to come up with a 'proper' soft fix.

Final follow up. In the absence of anyone on here being able to come up with a proper solution, I mentioned the problem to a friend who was a sometime PIC coder in a past life, but knows almost nothing of Arduinos and programming them. He asked me if I was closing the file after I had opened it. I told him not specifically but assumed that the SD card control library was doing that. He said he wouldn’t be so sure of that and I should look for a close argument to go with the SD library call. I was fairly convinced that I had never seen any such controls, but Googled it anyway. I came up with "after all the contents of the file are read, close the file with
< SD.close() >

So I added in < nextpic.close() > after the < nextpic = screen.loadimage(file) > line and BOOM ! Problem fixed.

It has now been running for some hours and is at pass number 725 and still running perfectly, so that is the answer. Make sure that the file is specifically closed after it has been read from the card …