2.8'' TFT Touch Shield - TFT BMP demo problem!

Hi!
Has anyone got the TFT BMP demo working with Seeedstudio’s 2.8’’ TFT Touch Shield screen? I have version 1.0 of the screen.
Demo code can be found in the 2.8" TFT Touch Shield’s wiki site. http://seeedstudio.com/wiki/2.8%27%27_TFT_Touch_Shield#Demo_Code_shown
Here is direct link to the example: http://www.seeedstudio.com/wiki/images/1/11/Tftbmp_demo.zip
I’m using Seeeduino Stalker v2.1 with 2Gb microSD-card and arduino v1.0 IDE. I got all other example codes working except this one.
You need to slightly modify the TFT library to get it compiling in the v1.0 arduino IDE.
You need to replace this code in the library:

#include "WProgram.h"
[/code]With this:
[code]#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif[/code]To get it compiling without errors.

The BMP demo pictures is showing on the screen all sorts of scrambled pixels and colored vertical lines. Basically there is no picture. 
[img]http://img254.imageshack.us/img254/786/07022012528.jpg[/img]

Although picture data printed in the serial port is showing all the file details with no problems so I guess the file is oppened correctly. 
I assume that the problem has something to do with the way the example code converts pixel colors from 8r-8g-8b-mode to 5r-6g-5b-mode.
Can someone help me with this problem? Is anyone else experiencing this same problem?

Here is the demo code that I have used:
[code]//  This sketch is adapted to Seeed's TFT library from 
//  https://github.com/adafruit/TFTLCD-Library/blob/master/examples/tftbmp/tftbmp.pde
//  by ladyada/adafruit under MIT license

#include <SD.h>
#include <TFT.h>

// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// the file itself
File bmpFile;

// information we extract about the bitmap file
int bmpWidth, bmpHeight;
uint8_t bmpDepth, bmpImageoffset;

void setup()
{
  Serial.begin(57600);
 
  Tft.init();
 
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT); //10 is used as chip select pin

  if (!SD.begin(10)) { //10 is used as chip select pin
    Serial.println("failed!");
    return;
  }
  Serial.println("SD OK!");
    
}

void loop()
{
  Tft.setOrientation(0);
  
  //Image 1
  bmpFile = SD.open("flower.bmp");
  if (! bmpFile) {
    Serial.println("didnt find image");
    while (1);
  }
  
  if (! bmpReadHeader(bmpFile)) { 
     Serial.println("bad bmp");
     return;
  }
  
  Serial.print("image size "); 
  Serial.print(bmpWidth, DEC);
  Serial.print(", ");
  Serial.println(bmpHeight, DEC);
  bmpdraw(bmpFile, 0, 0);
  delay(3000);
  bmpFile.close();
  
  //Image 2
  bmpFile = SD.open("hibiscus.bmp");
  if (! bmpFile) {
    Serial.println("didnt find image");
    while (1);
  }
  
  if (! bmpReadHeader(bmpFile)) { 
     Serial.println("bad bmp");
     return;
  }
  
  Serial.print("image size "); 
  Serial.print(bmpWidth, DEC);
  Serial.print(", ");
  Serial.println(bmpHeight, DEC);
  bmpdraw(bmpFile, 0, 0);
  delay(3000);
}


/*********************************************/
// This procedure reads a bitmap and draws it to the screen
// its sped up by reading many pixels worth of data at a time
// instead of just one pixel at a time. increading the buffer takes
// more RAM but makes the drawing a little faster. 20 pixels' worth
// is probably a good place

#define BUFFPIXEL 20

void bmpdraw(File f, int x, int y) {
  bmpFile.seek(bmpImageoffset);
  
  uint32_t time = millis();
  uint16_t p;
  uint8_t g, b;
  int i, j;
  
  uint8_t sdbuffer[3 * BUFFPIXEL];  // 3 * pixels to buffer
  uint8_t buffidx = 3*BUFFPIXEL;
  

  for (i=0; i< bmpHeight; i++) {
    
      Tft.setXY(x, y+bmpHeight-i); 
    
    
    for (j=0; j<bmpWidth; j++) {
      // read more pixels
      if (buffidx >= 3*BUFFPIXEL) {
        bmpFile.read(sdbuffer, 3*BUFFPIXEL);
        buffidx = 0;
      }
      
      // convert pixel from 888 to 565
      b = sdbuffer[buffidx++];     // blue
      g = sdbuffer[buffidx++];     // green
      p = sdbuffer[buffidx++];     // red
      
      p >>= 3;
      p <<= 6;
      
      g >>= 2;
      p |= g;
      p <<= 5;
      
      b >>= 3;
      p |= b;
     
       // write out the 16 bits of color
      Tft.sendData(p);
    }
  }
  Serial.print(millis() - time, DEC);
  Serial.println(" ms");
}

boolean bmpReadHeader(File f) {
   // read header
  uint32_t tmp;
  
  if (read16(f) != 0x4D42) {
    // magic bytes missing
    return false;
  }
 
  // read file size
  tmp = read32(f);  
  Serial.print("size 0x"); Serial.println(tmp, HEX);
  
  // read and ignore creator bytes
  read32(f);
  
  bmpImageoffset = read32(f);  
  Serial.print("offset "); Serial.println(bmpImageoffset, DEC);
  
  // read DIB header
  tmp = read32(f);
  Serial.print("header size "); Serial.println(tmp, DEC);
  bmpWidth = read32(f);
  bmpHeight = read32(f);

  
  if (read16(f) != 1)
    return false;
    
  bmpDepth = read16(f);
  Serial.print("bitdepth "); Serial.println(bmpDepth, DEC);

  if (read32(f) != 0) {
    // compression not supported!
    return false;
  }
  
  Serial.print("compression "); Serial.println(tmp, DEC);

  return true;
}

/*********************************************/
// These read data from the SD card file and convert them to big endian 
// (the data is stored in little endian format!)

// LITTLE ENDIAN!
uint16_t read16(File f) {
  uint16_t d;
  uint8_t b;
  b = f.read();
  d = f.read();
  d <<= 8;
  d |= b;
  return d;
}

// LITTLE ENDIAN!
uint32_t read32(File f) {
  uint32_t d;
  uint16_t b;
 
  b = read16(f);
  d = read16(f);
  d <<= 16;
  d |= b;
  return d;
}

We are sorry, TFT Touch Shield BMP demo is not compatible with Seeeduino Stalker, as SD card use many I/Os.
Please use Arduino/Seeeduino Mega, and follow the wiki steps.

Thanks
Albert

Hi,
I’ve been trying to compile the touchscreendemo from the TFT library examples but it gives me many errors like this one:

TouchScreen\TouchScreen.cpp.o: In function Point': C:\Program Files (x86)\arduino-1.0\libraries\TouchScreen/TouchScreen.cpp:19: multiple definition of Point::Point()’

All the other examples work fine. I’m new to Arduino. Any help is highly appreciated.

Does that also translate to “It doesn’t work with the Arduino Uno” as well?

I am using the Arduino Uno (latest version - 3?) and the Arduino Ethernet card with the SD port.

When I try the tftbmp using the Uno, certain interesting things happen:

  • The code compiles and uploads properly
  • It successfully reads and (apparently) successfully sends the code to the display
  • The display remains absolutely blank, (as in dark with the backlight lit)
  • The second .BMP image (I used both of the ones provided) will not load.

Does anyone have a solution for this?

Thanks!

Jim (JR)

Update:

I have now tried this with the Arduino Mega, and (as specified in the Wiki) made sure that line 33 in the TFT.h file was changed to “MEGA”

Loading and running the sketch now produces some output - but it is a scrambled black-and-white image (similar to the one above) that looks like the 2D Bar-Code from Hell.

It should also be noted that the 2nd BMP on my SD card is still not being read.
Note on the SD card: It is a 2 gig micro-SD card (the smallest I could find) and according to all the Arduino literature, 2 gigs should be fine - it’s the max size, but should still work.

(Oooh! I just noticed - colors!)

Two questions:
(1) Why am I not getting the pictures displayed as I should?
(2) Why does it seem to take upwards of fifteen minutes to load?

Thanks!

Jim (JR)

Hello there. I also have issues with the 2.8’’ TFT Touch Shield. I am using it with SD card shield and Arduino uno. I copied the two 24-bit bmp pictures in a SD card and getting the exact picture like seppala_timo. I tried to uploaded but I got a message from this forum: “Your post looks too spamy for a new user, please remove off-site URLs.”

Here the code I am using. I only changed the default pin (53) to 10.

// This sketch is adapted to Seeed’s TFT library by ladyada/adafruit under MIT license

#include <SD.h>
#include <TFT.h>

// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// the file itself
File bmpFile;

// information we extract about the bitmap file
int bmpWidth, bmpHeight;
uint8_t bmpDepth, bmpImageoffset;

void setup()
{
Serial.begin(9600);

Tft.init();

Serial.print(“Initializing SD card…”);
pinMode(10, OUTPUT); //53 is used as chip select pin

if (!SD.begin(10)) { //53 is used as chip select pin
Serial.println(“failed!”);
return;
}
Serial.println(“SD OK!”);

}

void loop()
{
Tft.setOrientation(0);

//Image 1
bmpFile = SD.open(“flower.bmp”);
if (! bmpFile) {
Serial.println(“didnt find image”);
while (1);
}

if (! bmpReadHeader(bmpFile)) {
Serial.println(“bad bmp”);
return;
}

Serial.print("image size “);
Serial.print(bmpWidth, DEC);
Serial.print(”, ");
Serial.println(bmpHeight, DEC);
bmpdraw(bmpFile, 0, 0);
delay(3000);
bmpFile.close();

//Image 2
bmpFile = SD.open(“hibiscus.bmp”);
if (! bmpFile) {
Serial.println(“didnt find image”);
while (1);
}

if (! bmpReadHeader(bmpFile)) {
Serial.println(“bad bmp”);
return;
}

Serial.print("image size “);
Serial.print(bmpWidth, DEC);
Serial.print(”, ");
Serial.println(bmpHeight, DEC);
bmpdraw(bmpFile, 0, 0);
delay(3000);
}

/*********************************************/
// This procedure reads a bitmap and draws it to the screen
// its sped up by reading many pixels worth of data at a time
// instead of just one pixel at a time. increading the buffer takes
// more RAM but makes the drawing a little faster. 20 pixels’ worth
// is probably a good place

#define BUFFPIXEL 20

void bmpdraw(File f, int x, int y) {
bmpFile.seek(bmpImageoffset);

uint32_t time = millis();
uint16_t p;
uint8_t g, b;
int i, j;

uint8_t sdbuffer[3 * BUFFPIXEL]; // 3 * pixels to buffer
uint8_t buffidx = 3*BUFFPIXEL;

for (i=0; i< bmpHeight; i++) {

  Tft.setXY(x, y+bmpHeight-i); 


for (j=0; j<bmpWidth; j++) {
  // read more pixels
  if (buffidx >= 3*BUFFPIXEL) {
    bmpFile.read(sdbuffer, 3*BUFFPIXEL);
    buffidx = 0;
  }
  
  // convert pixel from 888 to 565
  b = sdbuffer[buffidx++];     // blue
  g = sdbuffer[buffidx++];     // green
  p = sdbuffer[buffidx++];     // red
  
  p >>= 3;
  p <<= 6;
  
  g >>= 2;
  p |= g;
  p <<= 5;
  
  b >>= 3;
  p |= b;
 
   // write out the 16 bits of color
  Tft.sendData(p);
}

}
Serial.print(millis() - time, DEC);
Serial.println(" ms");
}

boolean bmpReadHeader(File f) {
// read header
uint32_t tmp;

if (read16(f) != 0x4D42) {
// magic bytes missing
return false;
}

// read file size
tmp = read32(f);
Serial.print(“size 0x”); Serial.println(tmp, HEX);

// read and ignore creator bytes
read32(f);

bmpImageoffset = read32(f);
Serial.print("offset "); Serial.println(bmpImageoffset, DEC);

// read DIB header
tmp = read32(f);
Serial.print("header size "); Serial.println(tmp, DEC);
bmpWidth = read32(f);
bmpHeight = read32(f);

if (read16(f) != 1)
return false;

bmpDepth = read16(f);
Serial.print("bitdepth "); Serial.println(bmpDepth, DEC);

if (read32(f) != 0) {
// compression not supported!
return false;
}

Serial.print("compression "); Serial.println(tmp, DEC);

return true;
}

/*********************************************/
// These read data from the SD card file and convert them to big endian
// (the data is stored in little endian format!)

// LITTLE ENDIAN!
uint16_t read16(File f) {
uint16_t d;
uint8_t b;
b = f.read();
d = f.read();
d <<= 8;
d |= b;
return d;
}

// LITTLE ENDIAN!
uint32_t read32(File f) {
uint32_t d;
uint16_t b;

b = read16(f);
d = read16(f);
d <<= 16;
d |= b;
return d;
}

And here the serial output log:

[quote]
Initializing SD card…SD OK!
size 0x38436
offset 54
header size 40
bitdepth 24
compression 40
image size 240, 320
2169 ms
size 0x38436
offset 54
header size 40
bitdepth 24
compression 40
image size 240, 320
2171 ms
size 0x38436
offset 54
header size 40
bitdepth 24
compression 40
image size 240, 320
2170 ms
size 0x38436
offset 54
header size 40
bitdepth 24
compression 40
image size 240, 320
2171 ms
size 0x38436
offset 54
header size 40
bitdepth 24
compression 40
image size 240, 320
2170 ms

Any help with this matter it would be highly appreciate. Thanks in advance.

I am having OP’s issue as well, with an Uno, Seeed’s SD shield, and Seeed’s TFT shield. When running the provided tftbmp sketch the serial output shows the correct info, but the screen shows garbled lines of color. I, too, believe it’s an issue with [strike]converting 888 to 565[/strike], or in feeding the resulting uint_16 to the tft screen.

Has anyone been able to figure out a solution?

Edit:

I edited tftbmp as shown:

[code] boolean firstrow = true;
for (i=0; i< bmpHeight; i++) {

  Tft.setXY(x, y+bmpHeight-i); 


for (j=0; j<bmpWidth; j++) {
  // read more pixels
  if (buffidx >= 3*BUFFPIXEL) {
    bmpFile.read(sdbuffer, 3*BUFFPIXEL);
    buffidx = 0;
  }
  
  // convert pixel from 888 to 565
  b = sdbuffer[buffidx++];     // blue
  g = sdbuffer[buffidx++];     // green
  p = sdbuffer[buffidx++];     // red
  
  p >>= 3;
  p <<= 6;
  
  g >>= 2;
  p |= g;
  p <<= 5;
  
  b >>= 3;
  p |= b;
 
   // write out the 16 bits of color
  Tft.sendData(p);
  if(firstrow){
    Serial.print("Tft.sendData(");
    Serial.print(p);
    Serial.println(");");
  }
}
firstrow = false;

}[/code]

Take the output from the serial window and create a new file:

[code]#include <stdint.h>
#include <TFT.h>

void setup()
{
Tft.init();
Tft.setOrientation(0);
//Paste the serial window code here
}

void loop()
{

}[/code]

When run it is clear that converting the bitmap from 8-8-8 to 5-6-5 works fine. Unfortunately, I’m not sure where to go from here.

Hello
When you use SD card,some pins will be occupied,such as 10,11,12,13;and when you use TFT Shield,almost all pins will be occupied,such as 2-13.So,it’ll occur a clash while using them together,then the image drawn is just garbled lines of colors.

If you want to show picture through SD Card & TFT Shield,might you can use TFT Shield v2.0.

Best Regards
Jacket

OK, so the TFT Shield I purchased from RadioShack is a 1.0 version, and will not work in concert with the SD shield? A version 2.0 shield will fixe the problem? Please verify.

yes, actully , there is already a SD card socket on the SD card shield 2.0, you do not a socket anymore :unamused:

I too got the v1 TFT Shield at RadioShack, along with the SD shield (and camera). I’ve returned all of it.

The version 2 TFT shield should run the BMP demo, as it has it’s own sd slot.

hey all , we’ll fine down it step by step.