Go Down

Topic: don't get my display to display anything (Read 1 time) previous topic - next topic


Jul 29, 2020, 11:17 am Last Edit: Aug 02, 2020, 08:57 pm by step1 Reason: added wiring image, added video, corrected values
I had a similar idea. In one of the older threads you mentioned that the ST7735 could be sent to sleep mode. In a data sheet of a similar device I found out that in this mode the memory of the display stays preserved. But I couldn't find out how to put the ST7789 into sleep mode. So I tried something else. It came to me by accident more or less. Remember when I said that I forgot to change the SPI_MODE back from 0 to 2? Mode 0 prevents the display from receiving data. How - that I don't know. But that was the crucial idea: I set SPI_MODE0 for ignoring the SPI bus and then back to SPI_MODE3 to listen to it again. It seems that while in MODE0 the display is "fighting back" the data as it flickers just a tiny bit. But that may also be due to bad connections on the breadboard.

here is the code:

Code: [Select]
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SD.h>                // SD card & FAT filesystem library
#include <SPI.h>             // Arduino SPI library

#define TFT_CS    10  // define chip select pin
#define TFT_DC    9  // define data/command pin
#define TFT_RST   8  // define reset pin, or set to -1 and connect to Arduino RESET pin
#define SD_CS   4 // SD card select pin
// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(-1, TFT_DC, TFT_RST);

// defines variables

bool c=false;

int32_t width;
int32_t height;

int32_t readNbytesInt(File *p_file, int position, byte nBytes)
    if (nBytes > 4)
        return 0;


    int32_t weight = 1;
    int32_t result = 0;
    for (; nBytes; nBytes--)
        result += weight * p_file->read();
        weight <<= 8;
    return result;

void setup() {
    while (!Serial);

    Serial.print("Initializing SD card...");
    if (!SD.begin(4)) {
        Serial.println("initialization failed!");
        while (1); // <- this is how you should block execution, not with returns
    Serial.println("initialization done.");


void drawBMP(){
  // Open
    File bmpImage = SD.open("/1.bmp", FILE_READ);

    int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);

    // Change their types to int32_t (4byte)
    width = readNbytesInt(&bmpImage, 0x12, 4);
    height = readNbytesInt(&bmpImage, 0x16, 4);

    int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);

    if (pixelsize != 24)
        Serial.println("Image is not 24 bpp");
        while (1);

    bmpImage.seek(dataStartingOffset);//skip bitmap header

    // 24bpp means you have three bytes per pixel, usually B G R
int s;
    byte R[28800], G[28800], B[28800];
    int i,j;
    for(i = 0; i < 28800; i++) {
            B[i] = bmpImage.read();
            G[i] = bmpImage.read();
            R[i] = bmpImage.read();
Serial.println("done read.");

    tft.init(240, 240, SPI_MODE3); // <-- important to put this here. AFTER filling the array.
        tft.setAddrWindow(0, 120*s, width, height); // first load lower half of the image, then in second run of the loop load upper half
          for (i=0; i<120; i++) {
              tft.pushColor(tft.color565(R[(i+1)*240-j],G[(i+1)*240-j],B[(i+1)*240-j])); // image is mirrored left to right, hence the transformation

        tft.endWrite();if(s==0)tft.init(240, 240, SPI_MODE0);} // crucial step: SPI_MODE0 prevents the display from receiving data via the SPI that is meant for the SD card reader.

delay(10000); // showing the image for 10 seconds

void loop() {
if(c==false){drawBMP();c=true;} // shows image only once

// [...] any other code you want


for reading the BMP I used this source:

of course reading takes a couple of seconds this way but the goal was achieved :)


ps. maybe I'm going to make a video about this. Takes some work though.

edit: for wiring see attachment

edit II: video added: https://youtu.be/xU1gWKsm9oY

Go Up