Need to reduce the size of code. Any Tips

I am looking into using switch case for the menu, but hoping there are some other tips that can reduce the size. I need to upload the code in 2 parts due to size.

#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <SD.h>
#define SD_CS 5
#define LCD_RESET A4
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
//#define CYAN    0x07FF
//#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft;
int8_t saved_spimode;

void disableSPI(void) {
  saved_spimode = SPCR;
  SPCR = 0;
}

void enableSPI(void) {
  SPCR = saved_spimode; 
}

const int buttonPin = 2;
const int Index = A4;
const int Select = A5;
float rim = 2.110;
int cycles = 0;
int speedcycles = 0;
unsigned long revtimer;
unsigned long revtimer2;
unsigned long serialTimer;
float Speed = 0;
unsigned long AvgTime2 = 0;
unsigned long AvgTime = 0;
unsigned long TempTime = 0;
unsigned long MenuTime = 0;
unsigned long MenuBegin = 0;
unsigned long StartTime = 0;
unsigned long Timerec = 0;
int Avgspeed =0;
float timedif = 0;
byte A = 10;
byte newride = 0;
byte Race = 0;
int Debounce = 0;
int B = 0;
int C = 0;
File myFile1;
//File myFile2;
//File myFile3;
//File myFile4;
int digit;
float totalavg = 0;
float timeavg = 0;

void setup()
{
  Serial.begin (9600);
  pinMode (buttonPin, INPUT);
  pinMode (Index, INPUT);
  pinMode (Select, INPUT);
  tft.reset();
  uint16_t identifier = tft.readID();
  tft.begin(identifier); 
  if (!SD.begin(SD_CS)) {
    return;
  }
  disableSPI(); 
  Background(); 
}

void loop ()
{ 
  while ((digitalRead(Index) == LOW)&& (digitalRead(buttonPin) == LOW));
  if (digitalRead(Index) == HIGH){
    if (Race == 1) {
    MenuBegin = millis();
    }
    menu ();
    if ((Race == 1) && (MenuBegin > 0)) {
    serialTimer =millis();
    MenuBegin = (serialTimer)-(MenuBegin);
    MenuTime = (MenuTime) + (MenuBegin);
    }
  }
  if (digitalRead(buttonPin) == HIGH){  
    if ((cycles == 0) && (Race == 1)) {
      StartTime = millis();
    }
    if (Race == 1) {
    cycles++;
    }
    
  while (digitalRead(buttonPin) == HIGH);
  speedcycles++;
  if (speedcycles % 4 == 0) {
  Serial.println (speedcycles);
  Currentspeed ();
  Speedtext();  
  }
  Debounce = 0;
  for (B=1; B<26000; B+=40){
  if (cycles == B+39) {
  AvgspeedW();
  }
  if (cycles == B+19) {
  TimecompareW();
  }
  if ((cycles == B) && (newride==0)) {
  AvgspeedR();
  Debounce = 1;
  }
  if ((cycles == B+20) && (newride==0)) {
  TimeR();
  Debounce = 1;
  }
  if ((cycles == B+21) && (newride==0)) {
  TimeCompareText();
  }
  }
   if (Debounce == 0) {
    if (Speed < 40) {
    Debounce = (map (Speed, 1, 40, 240, 1));
    } 
  delay (Debounce);
  delay (60);
  }
  }  
}

unsigned long Background() {
  tft.fillScreen(WHITE);
}

void Currentspeed () {
   revtimer = millis();
   Speed = ((rim * 14400)/(revtimer - revtimer2));
   revtimer2 = (revtimer);
}

void AvgspeedR() {
  enableSPI();
  char AvgSR[19];
  sprintf(AvgSR, "/Read/S%05d.txt", B+39);
  totalavg = 0;
  File myFile1 = SD.open(AvgSR);
    while (true)
        {
        if (myFile1.available() == 0)
            break;
        digit = myFile1.read();
        if (digit == '\n' || digit == '\r')
            break;
        totalavg = totalavg * 10 + (digit - '0');
        }
  myFile1.close();
  disableSPI();
 } 
 
void TimeR() {
  enableSPI();
  char TimeSR[19];
  sprintf(TimeSR, "/Read/T%05d.txt", B+19);
  timeavg = 0;
  File myFile1 = SD.open(TimeSR);
    while (true)
        {
        if (myFile1.available() == 0)
            break;
        digit = myFile1.read();
        if (digit == '\n' || digit == '\r')
            break;
        timeavg = timeavg * 10 + (digit - '0');
        }
  myFile1.close();
  disableSPI(); 
 } 

void AvgspeedW() {
  enableSPI();
  char fileName[20];
  sprintf(fileName, "/Write/S%05d.txt", B+39);
  myFile1 = SD.open(fileName, FILE_WRITE);
  if (myFile1) {
  serialTimer = millis();
  AvgTime2 = (serialTimer)-(MenuTime + StartTime);
  Avgspeed = (1440000*rim/(AvgTime2-TempTime));
  TempTime = (AvgTime2);
  myFile1.println(Avgspeed);
  myFile1.close();
  }
  disableSPI(); 
 }
void TimecompareW() {
  enableSPI();
  char Times[20];
  sprintf(Times, "/Write/T%05d.txt", B+19);
  myFile1 = SD.open(Times, FILE_WRITE); 
  if (myFile1) {
   serialTimer =millis();
   Timerec = ((serialTimer -(MenuTime + StartTime)) /100);
   myFile1.println(Timerec);
  
  myFile1.close();
  }
  disableSPI(); 
} 
 
 unsigned long Speedtext() {
  if (Speed < 10 || cycles == 1)
  {A = (77);
  }
  else { A=(47);
  }
  tft.setTextColor(BLACK);
  if (Speed < ((totalavg/10)-2) && (Race == 1) && (newride == 0))
  { tft.setTextColor(RED);
  tft.fillTriangle (120, 240, 50, 200, 190, 200, (RED));
  tft.fillRect (95, 180, 50, 20, (RED)); 
  tft.fillRect (50, 80, 140, 60, WHITE);
   }
  else if (Speed > ((totalavg/10)+2) && (Race == 1) && (newride == 0))
  { tft.setTextColor(BLUE);
  tft.fillTriangle (120, 80, 50, 120, 190, 120, (BLUE));
  tft.fillRect (95, 120, 50, 20, (BLUE)); 
  tft.fillRect (50, 180, 140, 60, WHITE);
  }
  else {
    tft.fillRect (50, 180, 140, 60, WHITE);
    tft.fillRect (50, 80, 140, 60, WHITE);
  }
  tft.setCursor(A, 142);
  tft.setTextSize(5);
  tft.fillRect (47, 142, 146, 40, WHITE);
  tft.println(Speed, 1);
}

 unsigned long TimeCompareText() {
  serialTimer = millis();
  timedif = (((timeavg*100)-((serialTimer)-(MenuTime + StartTime)))/1000); //Time compare start fix
  if (timedif < 10 && timedif > 0)
  {A = (151);
  }
  else if ((timedif <= (0-10) && timedif > -100) || (timedif > 100))
  { A=(115);
  }
  else if (timedif < (0-100))
  { A=(97);
  }
  else {
    A=(133);
  }
  tft.setTextSize(2);
  tft.setCursor(10, 25);
  tft.fillRect (10, 25, 100, 30, WHITE);
  if (timedif > 0) {
  tft.setTextColor(BLUE);
  tft.println("AHEAD");
  }
  else {
  tft.setTextColor(RED);
  tft.println("BEHIND");
  }
  tft.setCursor(A, 20);
  tft.setTextSize(3);
  tft.fillRect (105, 18, 120, 30, WHITE);
  tft.println(timedif); 
}

void menu1 () {
   tft.fillCircle(25, 25, 10, RED);
   tft.fillCircle(25, 75, 10, 0x57E0);
   tft.fillCircle(25, 125, 10, 0x57E0);
   tft.fillCircle(25, 175, 10, 0x57E0);
   tft.setTextColor(BLACK);
   tft.setTextSize(2);
   tft.setCursor(50, 18);
   tft.println("Course Select");
   tft.setCursor(50, 68);
   tft.println("Purge Temp Data");
   tft.setCursor(50, 118);
   tft.println("New Course");
   tft.setCursor(50, 168);
   tft.println("Exit");
   
   while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
   if (digitalRead(Index) == HIGH) { 
       tft.fillCircle(25, 25, 10, 0x57E0);
       tft.fillCircle(25, 75, 10, RED);
       delay (250);
       
        while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
        if (digitalRead(Index) == HIGH) {
        tft.fillCircle(25, 75, 10, 0x57E0);  
        tft.fillCircle(25, 125, 10, RED);
        delay (250);
        
          while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
          if (digitalRead(Index) == HIGH) {
          tft.fillCircle(25, 125, 10, 0x57E0);  
          tft.fillCircle(25, 175, 10, RED); 
          delay (250);
          
             while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
             if (digitalRead(Index) == HIGH) {
             delay (250);
             menu1 ();
             }
             if (digitalRead(Select) == HIGH) {
             tft.fillCircle(25, 175, 10, BLUE);
             Race =(0);
             delay (250);
             }
          }
          
          if (digitalRead(Select) == HIGH) {
          tft.fillCircle(25, 125, 10, BLUE);
          Race =(1);
          newride = (1);
          delay (250);
          }        
        }
      if (digitalRead(Select) == HIGH) {
      tft.fillCircle(25, 75, 10, BLUE);
      Race =(0);
      cycles = (0);
      delay (250);
      }      
   }
   if (digitalRead(Select) == HIGH) {
   tft.fillCircle(25, 25, 10, BLUE);
   delay (250);
   tft.fillScreen(0x62EC);
   menu2 ();
   }
} 
 
void menu2 () {   
   tft.fillCircle(25, 25, 10, RED);
   tft.fillCircle(25, 75, 10, 0x57E0);
   tft.fillCircle(25, 125, 10, 0x57E0);
   tft.fillCircle(25, 175, 10, 0x57E0);
   tft.setTextColor(BLACK);
   tft.setTextSize(2);
   tft.setCursor(50, 18);
   tft.println("Fanshawe CW");
   tft.setCursor(50, 68);
   tft.println("Fanshawe CCW");
   tft.setCursor(50, 118);
   tft.println("Other");
   tft.setCursor(50, 168);
   tft.println("Exit");
   
   while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
   if (digitalRead(Index) == HIGH) { 
       tft.fillCircle(25, 25, 10, 0x57E0);
       tft.fillCircle(25, 75, 10, RED);
       delay (250);
       
        while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
        if (digitalRead(Index) == HIGH) {
        tft.fillCircle(25, 75, 10, 0x57E0);  
        tft.fillCircle(25, 125, 10, RED);
        delay (250);
        
          while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
          if (digitalRead(Index) == HIGH) {
          tft.fillCircle(25, 125, 10, 0x57E0);  
          tft.fillCircle(25, 175, 10, RED); 
          delay (250);
          
             while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
             if (digitalRead(Index) == HIGH) {
             delay (250);
             menu2 ();
             }
             if (digitalRead(Select) == HIGH) {
             tft.fillCircle(25, 175, 10, BLUE);
             delay (250);
             }
          }
          
          if (digitalRead(Select) == HIGH) {
          tft.fillCircle(25, 125, 10, BLUE);
          delay (250);
          }        
        }
      if (digitalRead(Select) == HIGH) {
      tft.fillCircle(25, 75, 10, BLUE);
      delay (250);
      }      
   }
   if (digitalRead(Select) == HIGH) {
   tft.fillCircle(25, 25, 10, BLUE);
   Race =(1);
   cycles = (0);
   speedcycles = (0);
   delay (250);
   }
} 

void menu3 () {  
   tft.fillCircle(25, 25, 10, RED);
   tft.fillCircle(25, 75, 10, 0x57E0);
   tft.setTextColor(BLACK);
   tft.setTextSize(2);
   tft.setCursor(50, 18);
   tft.println("Resume");
   tft.setCursor(50, 68);
   tft.println("Cancel Ride");
   
   while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
   if (digitalRead(Index) == HIGH) { 
       tft.fillCircle(25, 25, 10, 0x57E0);
       tft.fillCircle(25, 75, 10, RED);
       delay (250);
       
        while ((digitalRead(Index) == LOW)&& (digitalRead(Select) == LOW));
        if (digitalRead(Index) == HIGH) {
        delay (250);
        menu3 ();
        }
        if (digitalRead(Select) == HIGH) {
        tft.fillCircle(25, 75, 10, BLUE);
        cycles = (0);
        Race = (0);
        StartTime = (0);
        MenuTime = (0);
        MenuBegin = (0);
        delay (250);
        }
   }
   if (digitalRead(Select) == HIGH) {
   tft.fillCircle(25, 25, 10, BLUE);
   
   delay (250);
   }
}


void menu (){
  delay (250);
  tft.fillScreen(0x62EC);
  if (Race == 0) {
  menu1 ();
  }
  else {
  menu3 ();
  } 
  delay (250);
  Background(); 
}

There are repetitive code sequences that could be put into their own functions to save space. Especially the many places where four arguments have to be passed to draw a circle.

See how much code elimination you can do by condensing common code like that into a few functions that get called from several places. At least that's where I'd start.

Good luck with your project,

-br

Thanks Bill, I think that will squeeze a bit more space.

you can check the type of your vars if they need to be long or int or byte. especially for arrays this adds up.