Reducing File Upload Size

Hello,
I am working on a flight computer for an upcoming weather balloon project. I have run out of space on the Arduino nano that is on my PCB. Is there anyway to change some of my code to reduce the size or change my libraries and reduce the size that way.
-Liam

//Kermputer Code written by Liam and Frank . Flight computer designed by Liam 
//Written for use on a Kermputer Board (Can be easily modified for a kermini) and the arduino NANO platform
//I really hope this works
//Notes/Progress: right now the bmp280 and gps are working together but gps does not happen everytime so sometimes get more temperature recrodings then gps log
//now not working woht the adding lines of priting the speed to the oled
//VERSION: 1.0


//Libraries
#include <SPI.h> //SPI Library
#include <Wire.h> //Wire Library 
#include <Adafruit_GFX.h> //Graphics Library         
#include <Adafruit_SSD1306.h> //OLED Library 
#include <Adafruit_BMP280.h>
#include <TinyGPS++.h> //Library for GPS
#include <SoftwareSerial.h> //Library to communicate with sensors
#include <MPU6050_light.h> //Gyro Library



//Other Stuff (Before Void Setup)

          // For OLED:
      #define OLED_RESET 5 //Oled reset pin is 5 
      Adafruit_SSD1306 display(OLED_RESET); //Reset the display 

         // For GPS:
      TinyGPSPlus gps; //create an object called gps that can be called on
      int RXPin = 4; //Set the rx pin to be pin 4 (WORKS ON THIS ONE DO NOT CHANGE)
      int TXPin = 3; //Set the tx pin to be pin 3 (WORKS ON THIS ONE DO NOT CHNAGE)
      int GPSBaud = 9600;
      SoftwareSerial ss(RXPin, TXPin); //Start listening on the TX (Transmitting) and RX (Reciving pins)
      double newMaxHeight = 0;
      double newMaxSpeed = 0;
      

         // For MPU-6050 Gyro
      MPU6050 mpu(Wire);
      int timer = 0;

         //For BMP280
      Adafruit_BMP280 bmp; // use I2C interface
      Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
      Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();
      double temperatureC;


void setup() {
Serial.begin(9600); // RUNS 9600 SO SEE IF IT OKAY. HAS TO BE ONE OR THE OTHER. SHOULD BE OKAY KEEP TESTING 
Serial.println("Kermputer Start");

        //Void Setup for OLED 
       display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C, telling program where to find it 
       delay(100); //wait .1 seconds
       display.clearDisplay(); //clear the oled screen
       display.display(); 
       delay(100); //wait .1 seconds 

        //Void Setup for GPS 
       ss.begin(GPSBaud); //Software serial at 9600. gps using that baud rate that we set earlier (9600 baud rate)
       
        //Void Setup for MPU-6050
        Wire.begin();
        byte status = mpu.begin();
        Serial.print(F("MPU6050 status: "));
        Serial.println(status);
        while (status != 0) { } // stop everything if could not connect to MPU6050
        Serial.println(F("Calculating offsets, do not move MPU6050"));
        delay(1000);
        mpu.calcOffsets(); // gyro and accelero
        Serial.println("Done!\n");

        //Void Setup for BMP280
        Serial.println(F("BMP280 Sensor event test"));
        if (!bmp.begin()) {
            Serial.println(F("Could not find a valid BMP280 sensor, check wiring or try a different address!"));
            while (1) delay(10);
            }
                  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
                  bmp_temp->printSensorDetails();
}



void loop()  {
mpu6050Routine();
gpsRoutine();
bmp280Routine();
oledDisplay(); //this should really be last since it is being called on after the others. needs their data to print 

}




void oledDisplay(){


  
  display.clearDisplay();  
  display.setTextSize(1);    
  display.setCursor(0,0);
  display.setTextColor(WHITE); 
  display.print("ALT =");
  display.print(gps.altitude.feet());
  display.println();
  display.print("Satellites Lock=");
  display.println(gps.satellites.value());
  display.print("Temp=");
  display.println(temperatureC);
  display.display();//Finally display the created image   
}


void gpsRoutine(){ //gps takes about 2 minutes of waiting before it gets a lock and will then flash red when ready
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){ //while the gps location is updated 
      Serial.println(" ");
      Serial.println(" ");
      Serial.print("Date= ");
      Serial.println(gps.date.value()); // Raw date in DDMMYY format (u32)
      Serial.println(gps.time.value()); // Raw time in HHMMSSCC format (u32)
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 3);
      Serial.print(" Longitude= "); 
      Serial.println(gps.location.lng(), 3);
      Serial.print("Speed (MPH)= ");
      Serial.println(gps.course.deg()); // Course in degrees (double)
      Serial.print("Heading (Degrees)= ");
      Serial.println(gps.speed.mph()); // Speed in miles per hour (double)
      Serial.print("Altitude= ");
      Serial.println(gps.altitude.feet()); // Altitude in feet (double)
      Serial.print("Satellites= ");
      Serial.println(gps.satellites.value()); // Number of satellites in use (u32)
      Serial.println("");

      if(gps.altitude.feet() > newMaxHeight){
      newMaxHeight = gps.altitude.feet();
      Serial.print("New Max Height: ");
      Serial.println(newMaxHeight);
    }
    
    if(gps.speed.mph() > newMaxSpeed){
      newMaxSpeed = gps.speed.mph();
      Serial.print("New Max Speed: ");
      Serial.println(newMaxSpeed);
    }
   } 
  }
}

void bmp280Routine(){
  Serial.print("Temperature: ");
  Serial.println(bmp.readTemperature()); 
  Serial.print("Pressure: ");
  Serial.println(bmp.readPressure()/100000);
  Serial.println("");
  temperatureC = bmp.readTemperature();
}

void mpu6050Routine(){
  mpu.update();
    if ((millis() - timer) > 10) { // print data every 10ms
     Serial.print("Pitch: ");
     Serial.print(mpu.getAngleX());
     Serial.print("\tTilt: ");
     Serial.print(mpu.getAngleY());
     Serial.print("\tRoll: ");
     Serial.println(mpu.getAngleZ());
     timer = millis();
   }
 }

Is it flash memory or SRAM or both that are running short?

Serial.println("Kermputer Start");

If it is SRAM I would suggest that you apply the F macro to all the string literals. So the above becomes:

Serial.println(F("Kermputer Start"));

Edit: The above advice will not help if the program is causing a "text section exceeds available space in board" error. Is that what is happening? Why didn't you say so in your first post?

Since the sketch size is very close to the Nano's upper limit, you can write it if you do trick.

Nano and Uno have almost exactly the same schematic, but for some special reason, selecting Nano in the IDE reduce limits the ROM size by 1536 bytes.
This is because Nano has different bootloader size than Uno, in the past.
Both are the same now, but we're wasting ROM at the team's decision to keep things consistent.

If you can burn the bootloader, tricking Nano into Uno will provide an additional secret 1536 bytes.


Try switching the board to Uno in the IDE and compile it.
Both has ATmega328P at microcontroller.
But, the maximum sketch size displayed be different.

Uno = 32256 bytes
Nano = 30720 bytes

Nano

text section exceeds available space in board
Sketch uses 31914 bytes (103%) of program storage space. Maximum is 30720 bytes.
Global variables use 1260 bytes (61%) of dynamic memory, leaving 788 bytes for local variables. Maximum is 2048 bytes.
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
Error compiling for board Arduino Nano.

Uno

Sketch uses 31914 bytes (98%) of program storage space. Maximum is 32256 bytes.
Global variables use 1260 bytes (61%) of dynamic memory, leaving 788 bytes for local variables. Maximum is 2048 bytes.


BTY, You can modify boards.txt to create a variant that makes full use of Nano, but considering the possibility of overwriting by an IDE update, I think it's better to pretend to be Uno.

If you are running out of RAM, then have a look for an alternative SSD1306 library like this one which uses a lot less RAM if your requirement is to only display text.

A quick google for "ssd1306 text only library" shows that there are other libraries too.

There's also one called SSD1306Ascii that I just found.

As far as I compiled copy'n-paste code, his sketch is out of ROM sizes.
In this case, the F() macro doesn't work.
However, changing the library has the potential to reduce the ROM size.

I did not know that when I wrote that post. If the OP had let us know of the error and the nature of the error, in his original post, I would not have wasted my time writing that post. It was only after I tried to compile the code for Nano that I knew of the error. The OP still has not acknowledged it.

First, I thought that many beginners might not even understand the difference between "out of ROM" and "out of RAM".
But if I take a quick look at the code, it doesn't look like it using so many arrays or string constants, and the F() macro was already used at long strings.
So I compiled it before write a post because he correctly provided code that could probably be compiled.
If the compilation didn't succeed without modifying the code, I wouldn't post... :hushed:

Do you need graphics for the OLED? Or can you get by with only text. I use the Bill Geiman text only library (on github).

Using MCUdude's MiniCore, you can easily remove the bootloader entirely, but will need to upload the code using an ISP programmer.

I prefer the u8g2 library for the display, but you can save some flash memory by modifying Adafruit's library to remove the splash images.

Also, timer needs to be an unsigned long.

While there might be some porting issues you might want to consider replacing the Nano with the Nano Every which uses an ATmega4809 microcontroller that has 48K of ROM and doesn't need to use any of that for a bootloader. It also can access ROM as data memory which simplifies the generated code for those character strings.

anyone facing scrolling issue inside the code block? Because on my side I can't see the whole code!