Bitmap Images with 3.5" TFT LCD 480x320

Hi All,

I am messing around with TFT displays now and have been interested in my TFT displays bitmap function, however, it is very slow. when doing any other kind of colour printing/messages it is about as instantaneous as I'd expect, but when doing bitmaps it takes almost 30seconds to fully update the 320x480px screen.

I'm wondering if this is normal for this type of display and setup and if not then, how can I speed it up! Ideally I'd like to display simple animations!

Screen: 320x480 3.5" TFT LCD Display, ILI9486 driver. 8-bit display.
Ardunio: Mega2560
Using SPI communications
Bitmap files are on a FAT32, 8GB SDcard

My working theory is because its only operating at 8 bit? I have ordered a 16bit just to continue playing. Code Below!

Thanks!

Diesel

// IMPORTANT: LCDWIKI_KBV LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.

//This program is a demo of how to show a bmp picture from SD card.

//Set the pins to the correct ones for your development shield or breakout board.
//when using the BREAKOUT BOARD only and using these 8 data lines to the LCD,
//pin usage as follow:
//             CS  CD  WR  RD  RST  D0  D1  D2  D3  D4  D5  D6  D7
//Arduino Uno  A3  A2  A1  A0  A4   8   9   2   3   4   5   6   7
/* AtMega Connections as follows:
 *  
 *  ATMEFA 2560      A0        A1     A2      A3      A4      D2  D3  D4  D5  D6  D7  D8  D9   D50    D51    D52     D53 
 *  TFT 3.5" SHLD:  LCD_RD  LCD_WR  LCD_RS  LCD_CS  LCD_RST   D2  D3  D4  D5  D6  D7  D0  D1  SD_DO  SD_DI  SD_SCK  SD_SS
 *  
 *  D50 - MOSI
 *  D51 - MISO
 *  D52 - SCK
 *  D53 - CS or SS
 */

//Remember to set the pins to suit your display module!

#include <SD.h>
#include <SPI.h>
#include <LCDWIKI_GUI.h> //Core graphics library
#include <LCDWIKI_KBV.h> //Hardware-specific library

//the definiens of 8bit mode as follow:
//if the IC model is known or the modules is unreadable,you can use this constructed function
//LCDWIKI_KBV my_lcd(ILI9341,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(ILI9325,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(ILI9328,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(HX8357D,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(HX8347G,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(HX8347I,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
LCDWIKI_KBV my_lcd(ILI9486,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//LCDWIKI_KBV my_lcd(ST7735S,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset

//if the IC model is not known and the modules is readable,you can use this constructed function
//LCDWIKI_KBV my_lcd(240,320,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset 
//LCDWIKI_KBV my_lcd(320,480,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define PIXEL_NUMBER  (my_lcd.Get_Display_Width()/4)
#define FILE_NUMBER 4
#define FILE_NAME_SIZE_MAX 20

uint32_t bmp_offset = 0;
uint16_t s_width = my_lcd.Get_Display_Width();  
uint16_t s_heigh = my_lcd.Get_Display_Height();
//int16_t PIXEL_NUMBER;

char file_name[FILE_NUMBER][FILE_NAME_SIZE_MAX];

uint16_t read_16(File fp)
{
    uint8_t low;
    uint16_t high;
    low = fp.read();
    high = fp.read();
    return (high<<8)|low;
}

uint32_t read_32(File fp)
{
    uint16_t low;
    uint32_t high;
    low = read_16(fp);
    high = read_16(fp);
    return (high<<8)|low;   
 }
 
bool analysis_bpm_header(File fp)
{
    if(read_16(fp) != 0x4D42)
    {
      return false;  
    }
    //get bpm size
    read_32(fp);
    //get creator information
    read_32(fp);
    //get offset information
    bmp_offset = read_32(fp);
    //get DIB infomation
    read_32(fp);
    //get width and heigh information
    uint32_t bpm_width = read_32(fp);
    uint32_t bpm_heigh = read_32(fp);
    if((bpm_width != s_width) || (bpm_heigh != s_heigh))
    {
      return false; 
    }
    if(read_16(fp) != 1)
    {
        return false;
    }
    read_16(fp);
    if(read_32(fp) != 0)
    {
      return false; 
     }
     return true;
}

void draw_bmp_picture(File fp)
{
  uint16_t i,j,k,l,m=0;
  uint8_t bpm_data[PIXEL_NUMBER*3] = {0};
  uint16_t bpm_color[PIXEL_NUMBER];
  fp.seek(bmp_offset);
  for(i = 0;i < s_heigh;i++)
  {
    for(j = 0;j<s_width/PIXEL_NUMBER;j++)
    {
      m = 0;
      fp.read(bpm_data,PIXEL_NUMBER*3);
      for(k = 0;k<PIXEL_NUMBER;k++)
      {
        bpm_color[k]= my_lcd.Color_To_565(bpm_data[m+2], bpm_data[m+1], bpm_data[m+0]);
        m +=3;
      }
      for(l = 0;l<PIXEL_NUMBER;l++)
      {
        my_lcd.Set_Draw_color(bpm_color[l]);
        my_lcd.Draw_Pixel(j*PIXEL_NUMBER+l,i);
      }    
     }
   }    
}

void setup() 
{
    Serial.begin(9600);
    while(!Serial){
    }
    Serial.print("Initializing..");
    //SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
   my_lcd.Init_LCD();
   my_lcd.Fill_Screen(BLUE);
   //s_width = my_lcd.Get_Display_Width();  
   //s_heigh = my_lcd.Get_Display_Height();
   //PIXEL_NUMBER = my_lcd.Get_Display_Width()/4;
   if(PIXEL_NUMBER == 60)
   {
       strcpy(file_name[0],"flower.bmp");
       strcpy(file_name[1],"tiger.bmp");
       strcpy(file_name[2],"tree.bmp");
       strcpy(file_name[3],"RedRose.bmp");
   }
   else
   {
       strcpy(file_name[0],"01.bmp");
       strcpy(file_name[1],"02.bmp");
       strcpy(file_name[2],"03.bmp");
       strcpy(file_name[3],"04.bmp");
   }
  //Init SD_Card
   pinMode(53, OUTPUT); //SPI CS or SS for LCD display
   
    if (!SD.begin(53)) //must be same as above.
    {
      my_lcd.Set_Text_Back_colour(BLUE);
      my_lcd.Set_Text_colour(WHITE);    
      my_lcd.Set_Text_Size(1);
      my_lcd.Print_String("SD Card Init fail!",0,0);
      Serial.println("SD Card Init Fail!");
    }
}

void loop() 
{
    int i = 0;
    File bmp_file;
    for(i = 0;i<FILE_NUMBER;i++)
    {
       bmp_file = SD.open(file_name[i]);
       if(!bmp_file)
       {
            Serial.println("didnt find BMPimage!");
            while(1);
        }
        if(!analysis_bpm_header(bmp_file))
        {  
            my_lcd.Set_Text_Back_colour(BLUE);
            my_lcd.Set_Text_colour(WHITE);    
            my_lcd.Set_Text_Size(1);
            my_lcd.Print_String("bad bmp picture!",0,0);
            return;
        }
          draw_bmp_picture(bmp_file);
         bmp_file.close();
         delay(5000); 
     }
}

Post a link to the actual display that you have bought. e.g. Ebay sale page.

Quote a genuine Arduino board by name.
Or post a link if it is a non-standard Arduino.

David.

It is a regular "Mcufriend Uno Shield".

You don't say whether you are using Uno, Mega2560, Due, ...
It will always be fairly slow on a Mega2560.

And if you choose to use the badly spelled library you can guarantee that most Arduino projects will be incompatible.

David.

the TFT display did say it was compatible with the UTFT library, I couldn't get it to do anything with that library sadly.

Sounds like I just need to find a more reliable brand of TFT display! :smiley:

Shops LIE.

You still have not said which Arduino board you want to use.

I thought I said above, I am using a Mega2560

My apologies. The screen is 8-bit parallel. The screen does not use SPI. But the SDcard does use SPI.

Yes, a 16-bit parallel Mega2560 display Shield will use PORTA, PORTC digital #22-37. This will work at a reasonable speed if you use a sensible library like Bodmer's TFT_HX8357.h library.

But your existing shield will work pretty well with an Arduino Due clone.
Most importantly, you can display JPEG images from PROGMEM.

David.

Yeah, gonna wait till I get an 16 bit display.

I thought that is what I ordered, but I just figured it wouldn't matter too much, the files I managed to get with it are...ironically for the 16bit variant, so going by their instructions, getting it to work as wired wasn't gonna do the trick! its working though, I spent most of this morning attempting to use another library, but I just can't seem to get another library to generate anything on the display, even simple things! I'll have a look into the HX8357!

Thanks for your help!

Diesel

MCUFRIEND_kbv can be installed via the IDE Library Manager.

All the library examples should work straight out of the box.

David.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.