Reduce Space on Arduino Nano

I am new to Arduino and I am working towards making a HUD for an iron man helmet. I have an OLED and a temperature/pressure/humidity sensor set up to an Arduino Nano. I have a loading animation set up followed by the display of temperature, pressure, and humidity read from the sensor. Unfortunately, I am at 106% of of my program storage space and have no idea how to lower the space without shortening the loading animation, which I don't really want to do. Any ideas?

For space purposes, I can't upload the entire code. There are 21 bitmap images that look like this and represent the different images for the loading bar.

const unsigned char myBitmap1 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xf9, 0xc0, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf8, 0x60, 
  0x00, 0x01, 0xd2, 0xef, 0xb9, 0x90, 0xef, 0x74, 0x98, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf8, 0x20, 
  0x00, 0x00, 0x9a, 0x42, 0x12, 0x50, 0x42, 0x26, 0xa0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x30, 
  0x00, 0x00, 0x96, 0x42, 0x13, 0xd0, 0x44, 0x25, 0xac, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 
  0x00, 0x00, 0x92, 0x42, 0x12, 0x50, 0x48, 0x24, 0xa4, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 
  0x00, 0x01, 0xd2, 0xe2, 0x3a, 0x5e, 0xef, 0x74, 0x98, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 
  0x00, 0x00, 0x10, 0x30, 0x38, 0x11, 0x07, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 
  0x00, 0x00, 0x10, 0x48, 0x24, 0x11, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbf, 0xff, 0xd8, 
  0x00, 0x00, 0x10, 0x78, 0x38, 0x0a, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9f, 0x07, 0x98, 
  0x00, 0x00, 0x90, 0x48, 0x28, 0x0a, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 
  0x00, 0x00, 0x62, 0x49, 0x24, 0x84, 0x27, 0x27, 0x10, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x18, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 
  0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xe0, 0x00, 0x70, 
  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x32, 0x40, 0xe0, 0x00, 0x70, 
  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x48, 0x80, 0xf0, 0x00, 0xf0, 
  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x00, 0xf1, 0xf8, 0xf0, 
  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x00, 0x72, 0x04, 0xe0, 
  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x32, 0x40, 0x70, 0x00, 0xe0, 
  0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x30, 0xf0, 0xc0, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xf9, 0xc0, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x07, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

This is the remainder of the code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BME280.h>

/*Global Var*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;
#define SEALEVELPRESSURE_HPA2 (101500)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//All of the 21 bitmaps are here
const uint8_t *myBitmap[] = {
  myBitmap1, myBitmap2, myBitmap3, myBitmap4, myBitmap5, myBitmap6, myBitmap7, myBitmap8,
  myBitmap9, myBitmap10, myBitmap11, myBitmap12, myBitmap13, myBitmap14, myBitmap15, myBitmap16,
  myBitmap17, myBitmap18, myBitmap19, myBitmap20, myBitmap21
};


void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  bme.begin(0x76);

  for(int i = 0; i <= 20; i++) {
    display.clearDisplay();
    display.drawBitmap(0,0,myBitmap[i],128,32,WHITE);
    display.display();
    delay(500);  
  }
  
}

void loop() { 
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("T=");
  /*prints BME280 temperature in Celsius*/
  display.print((float)bme.readTemperature(),1);
  display.print("*C");
  display.println("H=");
  /*prints humidity in %*/
  display.print((float)bme.readHumidity(),1);
  display.print("%");
  display.println("P=");
  /*prints BME280 pressure in Hectopascal Pressure Unit*/
  display.print(bme.readPressure()/100.0F,1);
  display.print("hPa");
  display.println("A=");
  /*prints BME280 altitude in meeters*/
  display.print((float)bme.readAltitude(SEALEVELPRESSURE_HPA),1);
  display.print("m");
  delay(1000);
  /*display buffer*/
  display.display();
}

Thanks in advance!

Compress your bitmaps by using some sort of run-length encoding.
Ie a 0 byte followed by an second byte byte indicating the number of zeros.
single 0s in the images become two bytes (0, 1), but up to 255 0s are still 2 bytes...

Compress your bitmaps by using some sort of run-length encoding.
Ie a 0 byte followed by an second byte byte indicating the number of zeros.
single 0s in the images become two bytes (0, 1), but up to 255 0s are still 2 bytes...

My first though exactly. If you do this for just the '0x00' , that means any '0x00' will be followed by the amount of zeros. You will have to translate the image before you send it to the display using the library, that will take up RAM, or you could make a modified version of the library that accepts your format as it is reading the data from progmen (more efficient)

Also, you can win some flash memory by installing the Arduino Uno bootloader onto the Nano, replacing the original Nano bootloader. From then on, you treat the device just like a Uno for uploading code etc.

You appear to be at 106% of flash memory, so that may just help. If you have a Uno available, try loading he sketch there first to see if that helps.

You can also look at the Nano Every instead. It has more flash memory space, but a different architecture, and is relatively new, meaning some libraries may not work.

You can save a bit of memory by removing the Adafruit splash images from the SSD_1306 library, those images are used to pre-load the display buffer with the Adafruit logo.

Edit Adafruit_SSD1306.cpp and comment out the following lines:

<<line 54>>
#include "splash.h"   

<<lines 469 - 475>>
  if (HEIGHT > 32) {
    drawBitmap((WIDTH - splash1_width) / 2, (HEIGHT - splash1_height) / 2,
               splash1_data, splash1_width, splash1_height, 1);
  } else {
    drawBitmap((WIDTH - splash2_width) / 2, (HEIGHT - splash2_height) / 2,
               splash2_data, splash2_width, splash2_height, 1);
  }

Not quite enough to allow the sketch to fit on the nano, but will reduce the program memory usage by a bit over 1400 bytes.

I was debating whether to suggest replacing the bootloader, since you appear new to the forum, but since it has already been suggested, this modification to the library will allow the sketch to fit using the UNO bootloader, although the original sketch would also fit if you eliminated the bootloader entirely.

I managed to reduce your code by using u8glib.

Sketch uses 27866 bytes (86%) of program storage space. Maximum is 32256 bytes.
Global variables use 602 bytes (29%) of dynamic memory, leaving 1446 bytes for local variables. Maximum is 2048 bytes

#include "U8glib.h"
#include "bitmaps.h"
#include <Adafruit_BME280.h>

const byte OLED_MOSI_Pin =     9;  // SDA
const byte OLED_CLK_Pin =      10; // SCL
const byte OLED_DC_Pin =       11;
const byte OLED_CS_Pin =       12;
const byte OLED_RESET_Pin =    4;

Adafruit_BME280 bme;

U8GLIB_SSD1306_128X64 u8g(OLED_CLK_Pin, OLED_MOSI_Pin, OLED_CS_Pin, OLED_DC_Pin);

/*Global Var*/
const float SEALEVELPRESSURE_HPA = 1013.25;
const long SEALEVELPRESSURE_HPA2 = 101500;

const byte SCREEN_WIDTH = u8g.getWidth(); // OLED display width, in pixels
const byte SCREEN_HEIGHT = u8g.getHeight(); // OLED display height, in pixels


//All of the 21 bitmaps are here
const uint8_t* myBitmaps[] = {
  myBitmap1, myBitmap2, myBitmap3, myBitmap4, myBitmap5, myBitmap6, myBitmap7, myBitmap8,
  myBitmap9, myBitmap10, myBitmap11, myBitmap12, myBitmap13, myBitmap14, myBitmap15, myBitmap16,
  myBitmap17, myBitmap18, myBitmap19, myBitmap20, myBitmap21
};


void setup() {
  u8g.setColorIndex(1);
  u8g.setFontPosTop();
  u8g.setFont(u8g_font_profont12);
  bme.begin(0x76);
}

void loop() {
  loadPage();
}

void loadPage() {
  u8g.firstPage();
  do {
    drawPage();
  }
  while (u8g.nextPage());
}

void drawPage() {
  // draw bitmaps
  for (const uint8_t* bitmap : myBitmaps) {
    u8g.drawBitmapP(0, 0, 128, 32, bitmap); // u8g.drawBitmapP(x, y, bmpByteWidth, bmpPixelHight, bmp);
    delay(1000);
  }
  // draw text
  u8g.setColorIndex(1); // set pixel color - 1 is white, 0 is black.
  u8g.setPrintPos(0, 0);
  u8g.println("T=");
  /*prints BME280 temperature in Celsius*/
  u8g.print((float)bme.readTemperature(), 1);
  u8g.print("*C");
  u8g.println("H=");
  /*prints humidity in %*/
  u8g.print((float)bme.readHumidity(), 1);
  u8g.print("%");
  u8g.println("P=");
  /*prints BME280 pressure in Hectopascal Pressure Unit*/
  u8g.print(bme.readPressure() / 100.0F, 1);
  u8g.print("hPa");
  u8g.println("A=");
  /*prints BME280 altitude in meeters*/
  u8g.print((float)bme.readAltitude(SEALEVELPRESSURE_HPA), 1);
  u8g.print("m");
  delay(1000);
}

bitmaps.h is just a header file with the 21 bit maps inside the file