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);
}
}