2.4" MCUFRIEND TFT Shield for Arduino Displays Colors Incorrectly
July 24, 2018A while ago I bought this 2.4"" Inch TFT LCD Touch Display Shield for Arduino UNO, but only recently I came up with a project where I could make use of this piece of hardware.
For the price tag of 5$ the specs of this display are quite neat:
- 2.4 inch LCD TFT
- 320 x 240 resolution
- 18 bit (262.000 colors)
- 4-wire resistive touchscreen
- Micro SD card reader
For reading images from an SD card and showing them on the display, I used the Adafruit/TFTLCD-Library, which I found on GitHub.
Displaying these images stored on the SD card would be an integral part of this project, so I did a quick proof of concept ... which happened to be very disappointing!
The colors were completely off when rendering images using the bmpDraw
function from the sample sketch tftbmp_shield
.
My first step was to check the Serial Monitor for possible debug or log output, that could suggest a possible error. But everything appeared to be OK there.
Found ILI9325 LCD driver
Initializing SD card...OK!
Loading image 'me.bmp'
File size:
230454
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 320x240
Loaded in 3005 ms
My next hunch was that maybe the RGB pixel values were out of order (a commong issue in computer graphics - ask me how I know). So I looked into the bmpDraw
function where the pixels were read and swapped the order of the RGB values there - but again to no avail.
void bmpDraw(char *filename, int x, int y) {
. . .
// Convert pixel from BMP to TFT format
r = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
b = sdbuffer[buffidx++];
lcdbuffer[lcdidx++] = tft.color565(r,g,b);
. . .
}
Next, I created a much simpler test image which just displayed some basic colors and interestingly, those were mainly Ok for the "primary" RGB colors, but already off for composite colors like cyan, yellow or purple.
This most probably meant that the method color565
which creates a 16 bit (unit16_t
) packed color from the RGB components, had an issue. With that information, Googling for a fix was rather easy and in the offciial Arduino forums I found someone having the exact same problem and also the fix for it.
It turned out that indeed the RGB packing function from the Adafruit library did not play well with that display, but shifting and OR'ing the bits only slightly different would do the trick.
uint16_t fixed_color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xF8) << 2) | (b >> 3);
}
Then, instead of calling the method tft.clor565
, a call to the newly created function fixed_color565
made sure that images got displayed correctly from now on..
void bmpDraw(char *filename, int x, int y) {
. . .
// lcdbuffer[lcdidx++] = tft.color565(r,g,b);
lcdbuffer[lcdidx++] = fixed_color565(r,g,b);
. . .
}
Problem solved!