Cutting down the size of code, stuck.

I'm a little stuck. I'm working on writing a graphic menu that will ultimately be used for Atmega8s. This menu is supposed to be pretty basic, and only needs to have just a few options. I.e., setting analog values for analogWrite, etc... The idea is to be able to graphically display the values so that if the analog value is 200, and I desired 180, I could visually inspect to ensure that is what I'm setting it to.

Now I'm not worried about that part of the code. What I am worried about is the Menu itself. After writing a VERY simple menu, I'm being squeezed by the inevitable limitations of program space for the Atmega8. 8k isn't very much room, and I really don't think that this should be taking up as much as it is.

Now I've written this prototyping with a Mega2560, but I will port it to the Atmega8, and have already test compiled it, but the only difference is the pin definitions for the SPI, so it's should be that much of an issue as far as code size.

The LCD is one of the 2.2" TFT LCDs from Adafruit, and I'm using the appropriate libraries. The rest is just simple graphics. Compiling for the Mega, the size is 7424 bytes. And for the Atmega8 it is 6416 bytes.

The code is here:

// Mega2560 Menu Sketch for use with the ILI9430/ILI9431 Adafruit Libraries.

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h"

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

#define _sclk 52
#define _miso 50
#define _mosi 51
#define _cs 53
#define _dc 9
#define _rst 8

const int button1 = A0;
const int button2 = A1;
const int button3 = A2;
const int button4 = A3;

Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _rst);


void setup() {
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9340_BLACK);
  tft.setTextSize(3);
  tft.setCursor(30, 0);
  pinMode(button1, INPUT);  // setting up buttons
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(10, OUTPUT); // Led on pin 10
  digitalWrite(button1, LOW); // setting the values of buttons to low
  digitalWrite(button2, LOW);
  digitalWrite(button3, LOW);
  digitalWrite(button4, LOW);
  digitalWrite(10, LOW); // Value of pin 10 to low
}

void loop() {
  tft.setCursor(0, 0);
  tft.setTextSize(3);
  tft.println("Gabbard's Menu:");
  menu1();

}

void menu1() {
  tft.setCursor(0, 30);
  tft.println("'1' - Option1");
  tft.println("'2' - Option2");
  tft.println("'3' - Option3");
  tft.println("'4' - Option4");

  if (digitalRead(button1) == HIGH) { //Calls function
    tft.fillScreen(ILI9340_BLACK);
    option1();
  }

  else { // Loops back to beginning of function
    menu1();
  }
}

void option1() {
  tft.setTextSize(3);
  tft.setCursor(30, 0);
  tft.println("Option1 Menu");
  tft.println();
  tft.println();
  tft.setTextSize(2);
  tft.println("Press '1' to turn on LED.");
  tft.println("Press '2' to turn off LED.");
  tft.println("Press '4' to go back.");

  if (digitalRead(button1) == HIGH) { // Turns on LED, but could be anything
    digitalWrite(10, HIGH);
    option1();
  }

  else if (digitalRead(button2) == HIGH) { // Turns off LED, but could be anything
    digitalWrite(10, LOW);
    option1();
  }

  else if (digitalRead(button3) == HIGH) { // Whatever funtion needed, etc...
    option1();
  }

  else if (digitalRead(button4) == HIGH) { // Prints screen black and returns to LOOP()
    tft.fillScreen(ILI9340_BLACK);
    loop();
  }

  else { // Loops back to beginning of function
    option1();
  }
}

Now, if I create function for the screen clear like so:

void fillblack() {
  tft.fillScreen(ILI9340_BLACK);
}

then I can get the size of the code to 6602 bytes for the M8, and 7410 bytes for the Mega.

Is there any way I can trim this code down??? Surely the Adafruit libraries and the SPI library cannot be taking up 6kb of space can they?

Any advice is welcome.

jdgabbard: Is there any way I can trim this code down??? Surely the Adafruit libraries and the SPI library cannot be taking up 6kb of space can they?

They certainly can. My introduction to Arduino was buying an Uno and several shields and then discovering that the free libraries all added up to 50% more code space and nearly twice the RAM space as the little Uno contained. I could have upgraded to a larger processor and bought different shields but instead I worked on the libraries, trimming some, rewriting others. It all eventually fit.

In the case of the display I used (128x64 OLED) the Adafruit code had more functionality than I needed as my sketch only displayed text of different sizes, nothing serious in the way of graphics. That library went from using about 10K in code just to say "Hello World" down to about 3K and RAM usage went from something like 1400 bytes down to 50 bytes. This is an extreme example but illustrates that it is almost always possible to reduce... it just depends on how hard you want to work at it.

I would first look around to see if another library already exists that is more efficient. Have you tried the u8glib library? I don't know what size it compiles to, but it is good code and worth looking at. If nothing else is available, I would start by taking scissors to the Adafruit code and cutting out anything you didn't use. Often the compiler optimizes well enough that this approach has little effect, but sometimes it still works. It depends on how the code is written. Beyond that you need to be more creative.

Do you know if the u8glib library supports the ILI9340/9341 display driver?

I'm not really sure. A quick google makes it look like ucglib (the color version of u8glib) supports 9341. The guy who wrote the code posts on the display forum here so you can ask him more directly.