Speed up or change the display direction

Hi all

I am building a audio control for my car. I modified the back end of my car’s stereo to accept aux in, and I am going to use the arduino to change the input between a bluetooth controller, the aux in or the cd changer.

All well and good so far but I would just like to speed the graphics up a bit. At the moment it is a bit slower than I’d like it to be. Is there anything I could do to improve this? or if not, is there any way I could change the direction the image gets built from? as if it was from top to bottom, the selected item would become visible straight away rather than having to wait for the image build to make it’s way to the item.

I am using a arduino uno and a Linksprite 2.8TFT LCD.

This is how fast the code runs on it at the moment:

Youtube Video

This is the code:

#include <SD.h>
#include <SPI.h>
#include "TFTv2.h"
#include <stdint.h>
#include <TouchScreen.h>
File bmpFile;

unsigned char saved_spimode;
int bmpWidth, bmpHeight;
uint8_t bmpDepth, bmpImageoffset;

#define chipSelect 4

//set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

TouchScreen ts = TouchScreen(XP, YP, XM, YM); //init TouchScreen port pins

void setup()
{
  pinMode(11,INPUT);
  pinMode(12,INPUT);
  pinMode(13,INPUT);
  TFT_CS_HIGH;
  pinMode(chipSelect,OUTPUT);
  digitalWrite(chipSelect,HIGH);

  Serial.begin(38400);
  SPI.begin(); 
  Tft.TFTinit();
  
   // a point object holds x y and z coordinates.
    Point p = ts.getPoint();
    
    //map the ADC value read to into pixel co-ordinates

    p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
  
  //SPI.setClockDivider(SPI_CLOCK_DIV4);
  //SDcard_info();
  /**/
  DDRB |= 0x04;
  card.init(SPI_FULL_SPEED,chipSelect);//SPI_QUARTER_SPEED   SPI_HALF_SPEED, SPI_FULL_SPEED,
  if(!SD.begin(chipSelect))//SPI_QUARTER_SPEED,
  { //53 is used as chip select pin
    Serial.println("failed!");
    while(1);
  }
  Serial.println("SD OK!");

  Tft.setCol(0,239);
  Tft.setPage(0,319);
  Tft.sendCMD(0x2c);//start to write to display ram
  TFT_BL_ON;
  
  
  
  
  char bmpfiles[][18]=
  {
    "bmp1.bmp","bmp2.bmp","bmp3.bmp","bmp4.bmp"
  };
  

  for(unsigned char i=0;i<2;i++)
  {
   //TFT_BL_OFF;
    bmpFile = SD.open(bmpfiles[i]);
    
    
    if (! bmpFile) 
    {
      Serial.println("didnt find image");
      while (1);
    }

    if (! bmpReadHeader(bmpFile)) { 
      Serial.println("bad bmp");
      return;
    }

Serial.print(i); 

    Serial.print("image size "); 
    Serial.print(bmpWidth, DEC);
    Serial.print(", ");
    Serial.println(bmpHeight, DEC);
    bmpdraw(bmpFile, 0, 0);


    bmpFile.close();
    //TFT_BL_ON;
    delay(5000);
  
  }
  
   
 
  
}

void loop()
{
  /*
   */
   // a point object holds x y and z coordinates.
    Point p = ts.getPoint();

    //map the ADC value read to into pixel co-ordinates

    p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);

    // we have some minimum pressure we consider 'valid'
    // pressure of 0 means no pressing!
  
  if (p.z > __PRESURE) 
  {
        // Detect  paint brush color change
        if(p.y > 108)
        {
              if(p.y < 221)
              {
                  bmpFile = SD.open("bmp0.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
            
                  bmpFile = SD.open("bmp3.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
               }
              else
              {
           
               }
        
          }
        
         else
         {
          }
          
          
          
          
          if(p.y > 1)
        {
              if(p.y < 104)
              {
                  bmpFile = SD.open("bmp0.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
            
                  bmpFile = SD.open("bmp4.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
               }
              else
              {
           
               }
        
          }
        
         else
         {
          }
       
  
  
        if(p.y > 215)
        {
              if(p.y < 318)
              {
                  bmpFile = SD.open("bmp0.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
            
                  bmpFile = SD.open("bmp2.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
               }
              else
              {
           
               }
        
          }
        
         else
         {
          }
  
  
  
  }
}

/*********************************************/
// This procedure reads a bitmap and draws it to the screen
// its sped up by reading many pixels worth of data at a time
// instead of just one pixel at a time. increading the buffer takes
// more RAM but makes the drawing a little faster. 20 pixels' worth
// is probably a good place


#define BUFFPIXEL 20

void bmpdraw(File f, int x, int y) 
{
  bmpFile.seek(bmpImageoffset);

  uint32_t time = millis();
  uint16_t p;
  uint8_t g, b;
  int i, j;

  uint8_t sdbuffer[3 * BUFFPIXEL];  // 3 * pixels to buffer
  uint8_t buffidx = 3*BUFFPIXEL;


  for (i=0; i< bmpHeight; i++) 
  {

    for (j=0; j<bmpWidth; j++) 
    {
      // read more pixels
      if (buffidx >= 3*BUFFPIXEL) 
      {
        bmpFile.read(sdbuffer, 3*BUFFPIXEL);
        buffidx = 0;
      }

      // convert pixel from 888 to 565
      b = sdbuffer[buffidx++];     // blue
      g = sdbuffer[buffidx++];     // green
      p = sdbuffer[buffidx++];     // red

      p >>= 3;
      p <<= 6;

      g >>= 2;
      p |= g;
      p <<= 5;

      b >>= 3;
      p |= b;

      // write out the 16 bits of color
      Tft.sendData(p);
    }
  }
  Serial.print(millis() - time, DEC);
  Serial.println(" ms");
}

boolean bmpReadHeader(File f) {
  // read header
  uint32_t tmp;

  if (read16(f) != 0x4D42) {
    // magic bytes missing
    return false;
  }

  // read file size
  tmp = read32(f);  
  Serial.print("size 0x"); 
  Serial.println(tmp, HEX);

  // read and ignore creator bytes
  read32(f);

  bmpImageoffset = read32(f);  
  Serial.print("offset "); 
  Serial.println(bmpImageoffset, DEC);

  // read DIB header
  tmp = read32(f);
  Serial.print("header size "); 
  Serial.println(tmp, DEC);
  bmpWidth = read32(f);
  bmpHeight = read32(f);


  if (read16(f) != 1)
    return false;

  bmpDepth = read16(f);
  Serial.print("bitdepth "); 
  Serial.println(bmpDepth, DEC);

  if (read32(f) != 0) {
    // compression not supported!
    return false;
  }

  Serial.print("compression "); 
  Serial.println(tmp, DEC);

  return true;
}

/*********************************************/
// These read data from the SD card file and convert them to big endian 
// (the data is stored in little endian format!)

// LITTLE ENDIAN!
uint16_t read16(File f) 
{
  uint16_t d;
  uint8_t b;
  b = f.read();
  d = f.read();
  d <<= 8;
  d |= b;
  return d;
}

// LITTLE ENDIAN!
uint32_t read32(File f) 
{
  uint32_t d;
  uint16_t b;

  b = read16(f);
  d = read16(f);
  d <<= 16;
  d |= b;
  return d;
}

I am using the linksprite library and 5 bmp images i made for the menu and used in the code (stored on a 2GB SD). I have added 2 to the post (converted to .jpg as the forum does not accept .bmp)

Any suggestions / help to improve the code and speed it up would be greatly appreciated.

Cal

bmp1.jpg

bmp3.jpg

   // a point object holds x y and z coordinates.
    Point p = ts.getPoint();
    
    //map the ADC value read to into pixel co-ordinates

    p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);

Why? You never use this data, so this is pointless.

#include "TFTv2.h"
#include <TouchScreen.h>

Links?

                  bmpFile = SD.open("bmp0.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
            
                  bmpFile = SD.open("bmp3.bmp");
           
                  bmpdraw(bmpFile, 0, 0);
               }
              else
              {
           
               }

You HAVE to know that this IS not fast. The useless else block just looks silly.

If you really want fast, use text.