UNO R3 reads the picture from the SD card and displays it on the 2.2-inch LCD screen (220x176)



After a tossing for a weekend, it was finally done. I have played for a while before, but failed to solve the problem of insufficient memory or array overrun after the picture is large enough.

So I decided to try SD card again. 220x176 has less information. After checking the website of Chinese and foreign languages ​​inside and outside the altar, I finally found some ideas.

The big idea is to read the RGB of each pixel of the specified picture file from the SD card and then display it at the corresponding position.

The LCD module I used has a resolution of 220x176, with an SD card slot, and supports UNO insertion, but the pins of the SD card must be soldered by themselves. In addition, there is a 320x240 which is also 2.2 inches. The information I read says it needs to be used after level conversion. Let me put this for the time being.

The wiring is very simple, it shows that the relevant plug directly into UNO R3, starting from 5V to A5 alignment. The original genuine one has a socket that is stuffy, so the corresponding pin of the LCD module should be broken. Compatible UNO is mostly a gap in this position so you can ignore it.

The wiring of the SD card is also very simple. Corresponding to the hardware SPI definition of PIN11-PIN13 (the official example also has detailed instructions). There is another SD_CS pin, which I connected to 10. This is not a matter of principle, because the parameter of SD.begin in the code is SD_CS.

Anyway, the SD part is not very complicated, basically look at the DumpFile of SD in the example below. To say more, it is said on the Internet that SD is best to use 2G or less, but the SD card I use is 4G. In addition, the pinMode is commented out in the example. I ca n’t do it here. I must explicitly specify it as OUTPUT, otherwise I wo n’t recognize the SD card.

I also took a detour to the picture file. So far, it is not a complete solution, but only a more cumbersome workaround. The ideal situation is to use Bitmap files (JPEG, PNG, etc. are all coded, considering the poor 16M clock frequency of the microcontroller to decode ... so the data must be fed directly. It takes almost 1 minute to load it ). Seek (0x12) gets the width, seek (0x16) gets the height, and seek (0x36) gets the data. This is feasible, but the biggest problem I encountered in testing here is lack of color. Let me put it this way, all faces are Avatar. . . . . . The structure of the Bitmap file has not been studied carefully. It is estimated that it has something to do with the saving options when making the Bitmap or the palette of the BMP file that you have. Let's try it later.

The current approach is to write a program in C # and directly convert it into a pixel RGB file without any file header. For example, if there is a picture with a width of 3 pixels and a height of 2 pixels, the first line is all red, and the second line is all green, so the file binary I output is:
0xFF 0x00 0x00 0xFF 0x00 0x00 0xFF 0x00 0x00
0x00 0xFF 0x00 0x00 0xFF 0x00 0x00 0xFF 0x00
(In order to take care of human reading habits, spaces and line breaks are added, in fact there is no. The shortcomings are obvious, you have to know the width and height.)
A total of 3 * 2 * 3 = 18 bytes.

I believe there is a ready-made format, but I don't know the keyword to look for. I guessed the RAW and MemoryBmp formats, but none of them succeeded in my hands.

Reading each byte in turn in Arduino, you can get the RGB information of one pixel every three readings, which can be displayed on the current coordinates. The actual effect is shown in the figure:

The main code is as follows, a lot of exception judgments are omitted. Please refer to the official example for the complete algorithm.

#include <UTFT.h>
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10;

UTFT lcd(QD220A, A2, A1, A5, A4, A3); 

void setup()
{
  int r, g, b;
  //Serial.begin(9600);

  pinMode(chipSelect, OUTPUT);

  lcd.InitLCD();
  lcd.clrScr();

  int width;
  int height;

  if (SD.begin(chipSelect)) {
    File bmpImage = SD.open("TEST.RAW", FILE_READ);
    
    /*

    bmpImage.seek(0x12);  // 宽度
    width = bmpImage.read();
    bmpImage.seek(0x16);  // 高度
    height = bmpImage.read();

    //Serial.println(width);
    //Serial.println(height);

    bmpImage.seek(0x36); //跳过Bitmap文件头
	
    */

    width = 220;
    height = 176;

    for (int y = 0; y < height; y ++) {
      for (int x = 0; x < width; x++) {

        r = bmpImage.read();
        g = bmpImage.read();
        b = bmpImage.read();

        lcd.setColor(r, g, b);
        lcd.drawPixel(x, y);
      }
    }

    bmpImage.close();
  }
}

void loop()
{
    // 啥都不用做
}


Published 122 original articles · Like 61 · Visits 530,000+

Guess you like

Origin blog.csdn.net/ki1381/article/details/66974924