Elegoo TFT - Showing personalized images without SD card

Hi, recently I purchased a TFT touchscreen from Elegoo, similar to Adafruit.

Since this library don't have a function to show bitmaps without SD card, I'm trying to have my own function, but I can't do it works. The code I have written is this:

#include <Elegoo_TFTLCD.h> // Libreria para visualización

#include "logo.h"

int const LCD_CS = A3; // Definimos los pines del LCD

int const LCD_RS = A2; // para poder visualizar elementos graficos

int const LCD_WR = A1;

int const LCD_RD = A0;

int const LCD_RESET = A4;

Elegoo_TFTLCD objetoTFT(LCD_CS, LCD_RS, LCD_WR, LCD_RD, LCD_RESET);

void bitmap(int pos_x, int pos_y, int c, int r, const unsigned char imagen[]){ //
int contador = 0;
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
objetoTFT.drawPixel(j, i, imagen[contador++]);
}
}
}

void setup() {
pinMode(13, OUTPUT);
objetoTFT.begin(0x9341);
objetoTFT.setRotation(1);
objetoTFT.fillScreen(0XFFFF);
Serial.begin(9600);
}

void loop() {
bitmap(0, 0, 200, 150, logo); // my logo is 200x150 pixels, origin x0,y0
delay(50000);

}

I've used an online web to convert the image, but I don't know if the format is right, or if my function must work as it do.

Any help please?

Attach your original logo BMP file and your logo.h result.
Put them in a ZIP. Then the Forum software will be happy.

Are you using a Uno or a Mega?

David.

Down is attached file.

Yes, of couse. I'm using an Arduino Mega 2560. The TFT is 320x240 pixels from Elegoo.

I've generated the bitmap array through this web:

http://www.rinkydinkelectronics.com/t_imageconverter565.php

It isn't designed for my library, but I'm trying to draw each pixel along columns and rows, putting each color pixel.

What's wrong in my code? Thanks!

logo.zip (45.5 KB)

Anyone can say me what's wrong? All the code? :stuck_out_tongue:

You have created a full-colour icon from a fairly nondescript JPG.
Yes, you need 30000 pixels. Your format requires 60000 byte array. The AVR compiler will not accept any array larger than 32768 bytes. (or it might be 32767)

You could split the large array into two. And use your function to display each half. Amend your function to read from Flash.

Think about it. You could have a monochrome image with sharp edges. Display with tft.drawBitmap()
Or use a 16-colour palette to produce anti-aliased curved edges. This needs a user function to display this BMP format.

I have used IrfanView to convert your JPG into BMP files of different resolution.
You can store the BMP file in Flash memory and display using the Colour Palette.

In an ideal world, Henning Karlsen's online ImageConverter (Mono) could produce the monochrome bitmap.
Unfortunately this program does not seem to work.

If you use IrfanView to create a monochrome BMP file, LCD Assistant from Bitmap converter for mono and color LCD displays can create a monochrome bitmap but only from a Black&White BMP.
Unfortunately this program will not create a monochrome bitmap from JPG, PNG, ...

I presume you are using a Mega2560. You would not have had the array size problem with a Zero or Due.
You might have noticed that the JPG is 7kB, a Monochrome BMP is 5kB, a 16-colour BMP is 15kB, a 256-colour BMP is 31kB. All these formats can fit in an array. Decoding the BMP or JPG is a lot more complicated than your function to draw RAW pixels.

David.

logo.zip (96.6 KB)

Thanks for your reply David. I've used LCD assistant for monocrome logo. I've tried differents outputs for the logo. Code shows image, but not I spected. ¿How many pixels/byte must I select for a true dimension output?

I only have a Mega for this project. My function reads an array in another tab with PROGMEM label in code. The images I need to load are smaller. With 80x50 pixels aprox I can do my TFT interface.

If I store in PROGMEM it shows one image, and if I store in dynamic memory, there's memory problems...
I attach pictures with 4 pixels/byte

I little plus of help since my goal is very near. Thanks!!

dynamic memory.jpg

PROGMEM.jpg

First off. Edit logo.h:

...
const unsigned short logo_top[15000] PROGMEM={
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0010 (16) pixels
...
0x2C72, 0x3451, 0x3431, 0x3431, 0x3C31, 0x3C31, 0x3C31, 0x3431, 0x3430, 0x3C50, 0x3C30, 0x440F, 0x5C30, 0xD77E, 0xF7FF, 0xF7DF,   // 0x3A90 (14992) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
};
const unsigned short logo_bot[15000] PROGMEM={
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x3AA0 (15008) pixels
0xFFFF, 0xF7DF, 0xEFFF, 0xE7DF, 0x8D96, 0x3B8E, 0x4430, 0x3C30, 0x3431, 0x3451, 0x3451, 0x3C31, 0x3C31, 0x3431, 0x3431, 0x3431,   // 0x3AB0 (15024) pixels
...

then edit lamartinada_logo.ino:

void bitmap(int pos_x, int pos_y, int c, int r, const unsigned short imagen[]){ //
  int contador = 0;
  for(int i=0; i<r; i++){
    for(int j=0; j<c; j++){
//      objetoTFT.drawPixel(j, i, imagen[contador++]);
      objetoTFT.drawPixel(j + pos_x, i + pos_y, pgm_read_word(&imagen[contador++]));
    }
  }
}
...

void loop() {
  bitmap(0, 0, 200, 75, logo_top); // my logo is 200x150 pixels, origin x0,y0
  bitmap(0, 75, 200, 75, logo_bot); //
  delay(1000);
}

Incidentally, the GFX library has a suitable method

    drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
      int16_t w, int16_t h),

David.

Thanks David, thanks for your help!!! My programming skills are not as good as I'd like. Thanks!!!

Your function works. The MEGA2560 has got enough flash memory.

It just seems wasteful when 60000 bytes of Flash memory are used. It requires a little trick if you want more than one logo.

David.