No title

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <SD.h>

// -------------------------
// Pin configuration
// -------------------------
#define TFT_CS   10
#define TFT_RST   8
#define TFT_DC    9
#define SD_CS     4

// -------------------------
// TFT object
// -------------------------
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// Buffer size
#define BUFFPIXEL 20


// ============================================================
// SETUP
// ============================================================
void setup() {

  Serial.begin(9600);

  Serial.println();
  Serial.println("Starting...");

  // Initialize TFT
  tft.initR(INITR_BLACKTAB);

  // Landscape mode
  tft.setRotation(1);

  // Clear screen
  tft.fillScreen(ST77XX_BLACK);

  Serial.println("TFT initialized.");

  // Initialize SD card
  Serial.print("Initializing SD card...");

  if (!SD.begin(SD_CS)) {
    Serial.println("FAILED!");

    tft.fillScreen(ST77XX_BLACK);
    tft.setTextColor(ST77XX_RED);
    tft.setTextSize(2);
    tft.setCursor(10, 30);
    tft.println("SD ERROR");

    while (1);
  }

  Serial.println("OK!");

  tft.fillScreen(ST77XX_BLACK);

  Serial.println("System ready.");
}


// ============================================================
// LOOP
// ============================================================
void loop() {

  bmpDraw("logo.bmp", 0, 0);
  delay(3000);

  bmpDraw("mezapos.bmp", 0, 0);
  delay(3000);

  bmpDraw("sparti.bmp", 0, 0);
  delay(3000);

  bmpDraw("mani.bmp", 0, 0);
  delay(3000);

  bmpDraw("lisbon.bmp", 0, 0);
  delay(3000);
}


// ============================================================
// DRAW BMP FILE
// ============================================================
void bmpDraw(const char *filename, uint8_t x, uint8_t y) {

  File bmpFile;

  int bmpWidth;
  int bmpHeight;

  uint8_t bmpDepth;

  uint32_t bmpImageoffset;
  uint32_t rowSize;

  uint8_t sdbuffer[3 * BUFFPIXEL];
  uint8_t buffidx = sizeof(sdbuffer);

  boolean goodBmp = false;
  boolean flip = true;

  int w, h;
  int row, col;

  uint8_t r, g, b;

  uint32_t pos = 0;

  uint32_t startTime = millis();


  // Check position
  if ((x >= tft.width()) || (y >= tft.height())) {
    return;
  }


  Serial.println();
  Serial.print("Loading image: ");
  Serial.println(filename);


  // ----------------------------------------------------------
  // Open BMP file
  // ----------------------------------------------------------

  bmpFile = SD.open(filename);

  if (!bmpFile) {

    Serial.print("File not found: ");
    Serial.println(filename);

    tft.fillScreen(ST77XX_BLACK);

    tft.setTextColor(ST77XX_RED);
    tft.setTextSize(2);
    tft.setCursor(5, 20);
    tft.println("FILE ERROR");

    return;
  }


  // ----------------------------------------------------------
  // BMP header
  // ----------------------------------------------------------

  if (read16(bmpFile) == 0x4D42) {

    Serial.print("File size: ");
    Serial.println(read32(bmpFile));

    // Creator bytes
    read32(bmpFile);

    // Image data offset
    bmpImageoffset = read32(bmpFile);

    Serial.print("Image offset: ");
    Serial.println(bmpImageoffset);


    // --------------------------------------------------------
    // DIB header
    // --------------------------------------------------------

    uint32_t headerSize = read32(bmpFile);

    Serial.print("Header size: ");
    Serial.println(headerSize);


    bmpWidth = (int)read32(bmpFile);
    bmpHeight = (int)read32(bmpFile);


    Serial.print("Width: ");
    Serial.println(bmpWidth);

    Serial.print("Height: ");
    Serial.println(bmpHeight);


    // Number of planes
    if (read16(bmpFile) == 1) {

      // Bits per pixel
      bmpDepth = read16(bmpFile);

      Serial.print("Bit depth: ");
      Serial.println(bmpDepth);


      // Compression
      uint32_t compression = read32(bmpFile);


      // ------------------------------------------------------
      // Only 24-bit uncompressed BMP supported
      // ------------------------------------------------------

      if ((bmpDepth == 24) && (compression == 0)) {

        goodBmp = true;


        Serial.print("Image size: ");
        Serial.print(bmpWidth);
        Serial.print(" x ");
        Serial.println(bmpHeight);


        // ----------------------------------------------------
        // BMP rows are padded to 4-byte boundary
        // ----------------------------------------------------

        rowSize = (bmpWidth * 3 + 3) & ~3;


        // ----------------------------------------------------
        // Negative height means top-to-bottom BMP
        // ----------------------------------------------------

        if (bmpHeight < 0) {

          bmpHeight = -bmpHeight;

          flip = false;
        }


        // ----------------------------------------------------
        // Image dimensions
        // ----------------------------------------------------

        w = bmpWidth;
        h = bmpHeight;


        // Clip image to display
        if ((x + w - 1) >= tft.width()) {
          w = tft.width() - x;
        }

        if ((y + h - 1) >= tft.height()) {
          h = tft.height() - y;
        }


        // ----------------------------------------------------
        // Set display window
        // ----------------------------------------------------

        tft.setAddrWindow(
          x,
          y,
          x + w - 1,
          y + h - 1
        );


        // ----------------------------------------------------
        // Read every row
        // ----------------------------------------------------

        for (row = 0; row < h; row++) {

          // Calculate position of row in BMP

          if (flip) {

            pos = bmpImageoffset +
                  (bmpHeight - 1 - row) *
                  rowSize;

          } else {

            pos = bmpImageoffset +
                  row * rowSize;
          }


          // Move file pointer

          if (bmpFile.position() != pos) {

            bmpFile.seek(pos);

            buffidx = sizeof(sdbuffer);
          }


          // --------------------------------------------------
          // Read every pixel
          // --------------------------------------------------

          for (col = 0; col < w; col++) {

            // Need more data?
            if (buffidx >= sizeof(sdbuffer)) {

              bmpFile.read(
                sdbuffer,
                sizeof(sdbuffer)
              );

              buffidx = 0;
            }


            // BMP stores BGR
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];


            // ------------------------------------------------
            // IMPORTANT:
            // color565() is the correct function name
            // ------------------------------------------------

            uint16_t color = tft.color565(r, g, b);

            tft.pushColor(color);
          }
        }


        Serial.print("Loaded in ");
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      }
    }
  }


  // ----------------------------------------------------------
  // Close file
  // ----------------------------------------------------------

  bmpFile.close();


  if (!goodBmp) {

    Serial.println("BMP format not recognized.");

    tft.fillScreen(ST77XX_BLACK);

    tft.setTextColor(ST77XX_RED);
    tft.setTextSize(2);
    tft.setCursor(5, 20);
    tft.println("BMP ERROR");
  }
}


// ============================================================
// READ 16-BIT VALUE
// ============================================================
uint16_t read16(File &f) {

  uint16_t result;

  result = f.read();

  result |= ((uint16_t)f.read()) << 8;

  return result;
}


// ============================================================
// READ 32-BIT VALUE
// ============================================================
uint32_t read32(File &f) {

  uint32_t result;

  result = f.read();

  result |= ((uint32_t)f.read()) << 8;
  result |= ((uint32_t)f.read()) << 16;
  result |= ((uint32_t)f.read()) << 24;

  return result; 

} 

Post a Comment

Previous Post Next Post

Contact Form