Not enough space on SRAM

Hello. I have code with:

a) OLED display (i2c)
b) 2x MCP23017 (i2c)
c) RTC DS1307 (i2c)
d) IR control
e) 2x DS18B20 (one wire)

and I would like to add encoder and eeprom (i2c), but the problem is that I have 10% free space on SRAM and now arduino (328p)hangs after 10-20sec after power up.

Its possible to optimize code? Or I need change microcontroller with bigger SRAM space?

Now on OLED i have only time, but I will add 2 DS18B20 and something more, so SRAM memory now I have 1849bits used....

#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <IRremote.h>
#include "RTClib.h"
#include <OneWire.h>
#include <DS18B20.h>
#include <Adafruit_SH1106.h>
#define OLED_RESET 4


#define irPin 3  
#define ONEWIRE_PIN 2
#define SENSORS_NUM 2


IRrecv irrecv(irPin);
decode_results results;

//DS18B20 address
const byte address[SENSORS_NUM][8] PROGMEM = 
{
  0x28, 0xFF, 0x0, 0xE9, 0xC4, 0x16, 0x4, 0x78,
  0x28, 0xFF, 0x1F, 0x2F, 0xC3, 0x16, 0x3, 0xA2
};

OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);
RTC_DS1307 RTC;


Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;

Adafruit_SH1106 display(OLED_RESET);

void setup() {
  while (!Serial);

  irrecv.enableIRIn();  // Start the receiver
  
  Serial.begin(9600);

  sensors.begin();
  sensors.request();

  Wire.begin();
  RTC.begin();

  mcp0.begin(0); //0x20
  mcp1.begin(1); //0x21

  mcp0.pinMode(0, OUTPUT);
  mcp0.pinMode(1, OUTPUT);
  mcp0.pinMode(2, OUTPUT);
  mcp0.pinMode(7, OUTPUT);
  mcp0.pinMode(8, INPUT);
  mcp0.pullUp(8, HIGH);


  mcp1.pinMode(4, OUTPUT);
  mcp1.pinMode(7, OUTPUT);
  mcp1.pinMode(8, INPUT);
  mcp1.pullUp(8, HIGH);


  Serial.begin(9600);
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(1500);
  display.clearDisplay();


  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

}

void loop() {

  if (sensors.available())
  {
    for (byte i = 0; i < SENSORS_NUM; i++)
    {
      float temperature = sensors.readTemperature(FA(address[i]));
      Serial.print(F("#"));
      Serial.print(i);
      Serial.print(F(": "));
      Serial.print(temperature);
      Serial.println(F(" 'C"));
    }

    sensors.request();
  }


  DateTime now = RTC.now();
  display.setTextSize(2);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(20, 4);
  display.print(now.hour(), DEC);
  display.print(':');
  display.print(now.minute(), DEC);
  display.print(':');
  display.print(now.second(), DEC);

  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(35, 22);
  display.print(now.year(), DEC);
  display.print('/');
  display.print(now.month(), DEC);
  display.print('/');
  display.print(now.day(), DEC);
  display.display();
  display.clearDisplay();


  mcp0.digitalWrite(0, HIGH);
  mcp0.digitalWrite(1, HIGH);
  mcp0.digitalWrite(2, HIGH);
  mcp1.digitalWrite(7, mcp1.digitalRead(8));
  mcp0.digitalWrite(7, mcp0.digitalRead(8));
   
if (irrecv.decode(&results))
   {
       switch (results.value)
       {
         case 0x805:  // kod klawisza 5
            mcp1.digitalWrite(4, HIGH);
            break;
            
         case 0x5:  // kod klawisza 5
            mcp1.digitalWrite(4, LOW);
            break;
         }
   irrecv.resume();
   }
}

Regards

Although you can still save a few bytes in this sketch you should consider to change to an MCU with more RAM.

Put F macro around "RTC is NOT running!"

I don't see any other obvious wastes of ram - the problem is the frame buffer for that OLED display. Those are huge memory hogs, they're not a good fit for microcontrollers with as little ram as the 328p. I use character LCDs for those - they're cheap, and don't need a frame buffer, and are available with an I2C backpack so you can control with just I2C (without the backpack, they need a lot of pins)

Ok, thanks.

After some researched maybe ATmega1284P ? Its compatible with arduino and have bootloader

First I will try with Atmega 32u4

Maybe 0,5kb more will be ok