/* //CS MOSI SCLK MISO CS RES DC SDA SCL GND VCC off -> +5V / on -> GND // | | | | | | | | | | | | // | | | | | | | | | | | | // V V V V V V V V V V V V // 4 11 13 12 10 8 9 11 13 GND +5V 2 // (Arduino) (Arduino) #include <ST7735.h> #include <SD.h> #include <SPI.h> // If we are using the hardware SPI interface, these are the pins (for future ref) #define sclk 13 // SCL #define mosi 11 // MOSI // You can also just connect the reset pin to +5V (we do a software reset) #define rst 8 // RES // these pins are required #define cs 10 #define dc 9 // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF // to draw images from the SD card, we will share the hardware SPI interface ST7735 tft = ST7735(cs, dc, rst); // For Arduino Uno/Duemilanove, etc // connect the SD card with MOSI going to pin 11, MISO going to pin 12 and SCK going to pin 13 (standard) // Then pin 4 goes to CS (or whatever you have set up) #define SD_CS 4 // Set the chip select line to whatever you use (4 doesnt conflict with the library) // the file itself File bmpFile; const int buttonPin = 2; int buttonState = 0; // Status von Knoepfchen // information we extract about the bitmap file int bmpWidth, bmpHeight; uint8_t bmpDepth, bmpImageoffset; void setup(void) { Serial.begin(9600); pinMode(cs, OUTPUT); pinMode(buttonPin, INPUT); digitalWrite(cs, HIGH); // initialize a ST7735R TFT tft.initR(); // change this to initB() for ST7735B TFT's Serial.print("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("failed!"); return; } Serial.println("SD OK!"); bmpFile = SD.open("bendx.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); tft.fillScreen(BLACK); bmpdraw(bmpFile, 0, 0); pinMode(buttonPin, INPUT); } void loop() { buttonState = digitalRead(buttonPin); if(buttonState == LOW){ Serial.println("Knoepfche gedrueckt !"); zeigeText(); bmpdraw(bmpFile, 0, 0); } } void zeigeText(){ tft.fillScreen(BLACK); tft.drawString(0, 0, "Hallo lieber Luca,", YELLOW); delay(2000); for (int i = 0; i < 5; i++){ tft.drawString(0, 20, "* *", BLACK); delay(200); tft.drawString(0, 20, "* Glueckwunsch !! *", RED); delay(200); } tft.drawString(0, 50, "nachtraeglich", WHITE); tft.drawString(0, 60, " zum ", WHITE); tft.drawString(0, 70, " Geburtstag! ", BLUE); delay(3000); tft.drawString(0, 120, "Viele Gruesse, ", RED); tft.drawString(0, 130, "Henning", GREEN); delay(10000); } /*********************************************/ // 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[2 * BUFFPIXEL]; // 3 * pixels to buffer uint8_t buffidx = 2*BUFFPIXEL; Serial.print("rotation = "); Serial.println(tft.getRotation(), DEC); //set up the 'display window' tft.setAddrWindow(x, y, x+bmpWidth-1, y+bmpHeight-1); uint8_t rotback = tft.getRotation(); //tft.setRotation(180); for (i=0; i< bmpHeight; i++) { //for (i=bmpHeight; i> 0; i--) { // bitmaps are stored with the BOTTOM line first so we have to move 'up' for (j=0; j<bmpWidth; j++) { // read more pixels //if (buffidx >= 2*BUFFPIXEL) { //bmpFile.read(sdbuffer, 3*BUFFPIXEL); //buffidx = 0; sdbuffer[0] = bmpFile.read(); sdbuffer[1] = bmpFile.read(); sdbuffer[2] = bmpFile.read(); //Serial.print(sdbuffer[0], HEX); //Serial.print(sdbuffer[1], HEX); //Serial.print(sdbuffer[2], HEX); //} //p = (sdbuffer[1] << 8) | sdbuffer[0]; //buffidx++; //buffidx++; // convert pixel from 565 to 888 //b = sdbuffer[0] & 0x1f; //g = (sdbuffer[0] >> 5) | (sdbuffer[1] << 5); //r = sdbuffer[1] >> 3; // convert pixel from 888 to 565 b = sdbuffer[0]; // blue g = sdbuffer[1]; // green p = sdbuffer[2]; // red p >>= 3; p <<= 6; g >>= 2; p |= g; p <<= 5; b >>= 3; p |= b; //Serial.print(p, HEX); // write out the 16 bits of color //tft.drawPixel(i, j, p); tft.pushColor(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; }