2.8" TFT Shield BMP Sketch
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- doogerk
- Posts: 5
- Joined: Tue Jul 15, 2014 1:09 pm
2.8" TFT Shield BMP Sketch
I have the 2.8" TFT shield on the arduino mega adk board. Other tft sketches work fine, but when I try to compile the tftbmp_shield sketch I get an error "SPI not declared in this scope". I made sure that in the TFTLCD header file #define USE_ADAFRUIT_SHIELD_PINOUT 1 was uncommented and in the sd2card file #define MEGA_SOFT_SPI 1 was uncommented as described in the tutorial. Is there something else I am missing?
- Franklin97355
- Posts: 23940
- Joined: Mon Apr 21, 2008 2:33 pm
Re: 2.8" TFT Shield BMP Sketch
Could you post your code and a description or drawing of your connections between it all?
Please use the code button as shown below.
Please use the code button as shown below.
- doogerk
- Posts: 5
- Joined: Tue Jul 15, 2014 1:09 pm
Re: 2.8" TFT Shield BMP Sketch
Code: Select all
// BMP-loading example specifically for the TFTLCD Arduino shield.
// If using the breakout board, use the tftbmp.pde sketch instead!
// If using an Arduino Mega, make sure the SD library is configured for
// 'soft' SPI in the file Sd2Card.h.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SD.h>
// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// There are examples in the sketch folder
#define SD_CS 5 // Card select for shield use
Adafruit_TFTLCD tft;
uint8_t spi_save;
void setup()
{
Serial.begin(9600);
tft.reset();
uint16_t identifier = tft.readID();
if(identifier == 0x9325) {
Serial.println(F("Found ILI9325 LCD driver"));
} else if(identifier == 0x9328) {
Serial.println(F("Found ILI9328 LCD driver"));
} else if(identifier == 0x7575) {
Serial.println(F("Found HX8347G LCD driver"));
} else if(identifier == 0x9341) {
Serial.println(F("Found ILI9341 LCD driver"));
} else {
Serial.print(F("Unknown LCD driver chip: "));
Serial.println(identifier, HEX);
Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
Serial.println(F("If using the breakout board, it should NOT be #defined!"));
Serial.println(F("Also if using the breakout, double-check that all wiring"));
Serial.println(F("matches the tutorial."));
return;
}
tft.begin(identifier);
Serial.print(F("Initializing SD card..."));
if (!SD.begin(SD_CS)) {
Serial.println(F("failed!"));
return;
}
Serial.println(F("OK!"));
spi_save = SPCR;
bmpDraw("woof.bmp", 0, 0);
delay(1000);
}
void loop()
{
for(int i = 0; i<4; i++) {
tft.setRotation(i);
tft.fillScreen(0);
for(int j=0; j <= 200; j += 50) {
bmpDraw("miniwoof.bmp", j, j);
}
delay(1000);
}
}
// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates. It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel). Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster. 20 pixels seems a
// good balance.
#define BUFFPIXEL 20
void bmpDraw(char *filename, int x, int y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
uint8_t lcdidx = 0;
boolean first = true;
if((x >= tft.width()) || (y >= tft.height())) return;
Serial.println();
Serial.print("Loading image '");
Serial.print(filename);
Serial.println('\'');
// Open requested file on SD card
SPCR = spi_save;
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print("File not found");
return;
}
// Parse BMP header
if(read16(bmpFile) == 0x4D42) { // BMP signature
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
// Read DIB header
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format -- proceed!
Serial.print(F("Image size: "));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h = tft.height() - y;
// Set TFT address window to clipped image bounds
SPCR = 0;
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row<h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize;
SPCR = spi_save;
if(bmpFile.position() != pos) { // Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
}
for (col=0; col<w; col++) { // For each column...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
// Push LCD buffer to the display first
if(lcdidx > 0) {
SPCR = 0;
tft.pushColors(lcdbuffer, lcdidx, first);
lcdidx = 0;
first = false;
}
SPCR = spi_save;
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
}
// Convert pixel from BMP to TFT format
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
lcdbuffer[lcdidx++] = tft.color565(r,g,b);
} // end pixel
} // end scanline
// Write any remaining data to LCD
if(lcdidx > 0) {
SPCR = 0;
tft.pushColors(lcdbuffer, lcdidx, first);
}
Serial.print(F("Loaded in "));
Serial.print(millis() - startTime);
Serial.println(" ms");
} // end goodBmp
}
}
bmpFile.close();
if(!goodBmp) Serial.println("BMP format not recognized.");
}
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
- doogerk
- Posts: 5
- Joined: Tue Jul 15, 2014 1:09 pm
Re: 2.8" TFT Shield BMP Sketch
Also if it helps. I traced the code error back to sd2card.cpp line 507. it calls SPI.setClockDivider(v);
- Franklin97355
- Posts: 23940
- Joined: Mon Apr 21, 2008 2:33 pm
Re: 2.8" TFT Shield BMP Sketch
I copied your code to the IDE and it compiled without errors. I'm not sure where the error is on your system. What version of the IDE are you using and have you downloaded the libraries recently?
- doogerk
- Posts: 5
- Joined: Tue Jul 15, 2014 1:09 pm
Re: 2.8" TFT Shield BMP Sketch
It seems like it is narrowed to the SD library. Any sketch using that library doesn't compile now. I must have a corrupt version. I will have to look for a download of it and replace it.
- Franklin97355
- Posts: 23940
- Joined: Mon Apr 21, 2008 2:33 pm
Re: 2.8" TFT Shield BMP Sketch
There are two SD libraries. One is Adafruit and should go in the sketchbook/libraries folder the other is built into the Arduino IDE and you can update that by downloading the latest version. For most things 1.0.5 is fine.
Please be positive and constructive with your questions and comments.