Program taking up too much RAM and flash memory

Hi! I have recently been programming a bunch of components to the Arduino Uno, and I have come across a problem. I seem to have reached 100% of program storage space and 101% of dynamic memory. I have been using suggestions like F() macros and it helps, but it doesn't seem to be enough. I use a BMP280 sensor, an Adafruit SD card reader, and a Ultimate Breakout GPS.
I am not sure if libraries are relevant(I think they are), but I have the following libraries installed:

  • SD(by Arduino)
  • Adafruit BMP280 Library
  • Adafruit BusIO
  • Adafruit GPS Library
  • Adafruit Unified Sensor
  • GPS(By Helder Rodrigues)

My full sketch is here:

//GPS
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>




 //BMP280 Code
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>


//SD Card Reader
#include <SPI.h>
#include <SD.h>


//GPS
SoftwareSerial mySerial(8,7);
Adafruit_GPS GPS(&mySerial);


#define GPSECHO  true


//BMP 280
Adafruit_BMP280 bmp;
//SD card readed
 //Pin num connected to CS
File dataFile;




//Buzzer
//const int buzzerPin = 9;
//SD Card Reader
#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)




void setup() {
  Serial.begin(115200);
  Serial.begin(9600);
  while (!Serial);
  GPSStartup();
  pinMode(9, OUTPUT); //Buzzer
  BMPInit();
  SDInit();
  delay(2000); // Delay start
 
}
const uint16_t line = 1;
uint32_t timer = millis();


void loop() {
  //GPS
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false


    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }
 
  //BMP280 start
 // Serial.println(F("BMP280 Sensor Readings:"));
  //Finds all measurements and sets them
  Serial.print(line);
  Serial.print(FormatBMP());
 




 
  //BMP280 END
  //SD Card Reader
  dataFile = SD.open(F("PMData.txt"), FILE_WRITE); // Opens the file
  //Checks if file has opened
  if (dataFile)
  {
    //Serial.println(F("File has been opened sucessfully :D. Writing..."));
    //Write to file:
    dataFile.print(line);
    dataFile.print(FormatBMP());


    //GPS
     if (millis() - timer > 2000)
  {
    timer = millis();
    if (GPS.fix)
    {
      //Location
      Serial.print(FormatGPS());
      dataFile.print(FormatGPS());
    }
  }




   
    //Close File
    dataFile.close();
   
    //Serial.println("File closed successfully, data has been written(LETS GOOO).");
   
  }
  else
  {
    Serial.println(F("File failed to open :/"));
  }
 
  //Buzzer sounds every 5 seconds
  tone(9, 1000);
  delay(1000);
  noTone(9);
  delay(1000);
 
} 

void GPSStartup()
{
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_ANTENNA);
  
  // Ask for firmware version
  mySerial.println(F(PMTK_Q_RELEASE));
}

void BMPInit()
{
  if (!bmp.begin(0x76)) {
   
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    while (1);
  }
  Serial.println(F("BMP280 Sensor Initiallized!:D"));
}
void SDInit()
{
  if (!SD.begin(10))
  {
    Serial.println(F("SD Card Init Failed. Womp Womp D:."));


   
    while(1);
  }
  Serial.println(F("SD card initialized:D"));
}

String FormatBMP()
{
  String format = F("Temperature = ");
  format.concat(String(bmp.readTemperature(), 2));
  format.concat(F(" °C,  Pressure = "));
  format.concat(String((bmp.readPressure()/100.0), 2));
  format.concat(F(" hPa, Altitude = "));
  format.concat(F(" hPa, Altitude = "));
  format.concat(String(bmp.readAltitude(1013.25), 2));
  format.concat(F("m"));

  return format;
}
String FormatGPS()
{
  String format = F("Location(Lat.Lon.): ");
  //Location
  format.concat(String(GPS.latitude,4));
  format.concat(String(GPS.lat));
  format.concat(F(", "));
  format.concat(String(GPS.longitude, 4));
  format.concat(String(GPS.lon));
  //Speed
  format.concat(F("\nSpeed: "));
  format.concat(String(GPS.speed, 1));
  //Angle
  format.concat(F(" | Angle: "));
  format.concat(String(GPS.angle, 1));

  return format;
}

The SD card library in particular takes a lot of memory. And there may be alternatives to the Adafruit libraries that might reduce memory a bit.

Why not just use an Arduino with more memory ?

The issue is that all of this will have to be transferred to an Arduino Nano to fit into a small space along with the sensors. I am using an Arduino Uno for prototyping and figuring everything out. I will look into finding better SD card libraries sure!

Dont think there is one. Even a basic sketch using the SD card will consume circa 55% of memory on a UNO\Nano.

Using an SD card with an Arduino with such low amounts of memory as the UNO or Nano has always been an issue.

1 Like

@shadycrisp
Please show the IDE compiling message, your code doesn't looks too big.

In addition, the code is clearly not optimal, it looks like you have a poor understanding of which lines do what.

Why these definitions of SPI pins, duplicate to the standard ones?

Why two Serial.begin ?

What purpose this reading of the single char to unused variable?

and more and more

1 Like

All in all, the whole thing looks like a generated code.

Yes, I am quite new and do not fully understand some of the code. My SD card wouldn't work for a while, and I was trying to find solutions. I mostly use Arduino examples to help me out, and I tweak them as needed. I didn't know the definitions were not useful. Also, in multiple examples with GPS, a different serial is used to output GPS data, thus, I thought it might be necessary. The GPS.read(); was also part of an example, and I don't quite understand how it works.

Sketch uses 32320 bytes (100%) of program storage space. Maximum is 32256 bytes.
Global variables use 2072 bytes (101%) of dynamic memory, leaving -24 bytes for local variables. Maximum is 2048 bytes.
Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
text section exceeds available space in board

Compilation error: text section exceeds available space in board

That comment doesn't really help? The code is not generated, and I have been working on it, trying to understand it for a while now.

Unfortunately, by simply combining ready-made pieces of code you will never be able to write something more complex than blinking an LED. To write a program that does more than one thing, you need at least a basic understanding of how each part works and what the commands used are for.
Your current code gives the impression of randomly written lines. Even without taking into account the lack of memory, it would hardly work in this form

The code(before the GPS was implemented), worked quite well. I am trying to learn, and I know how to code(in a different language). I just don't get the individual components.

Yes, the GPS in the examples uses a different serial. But in your code you initialized a same serial twice.

So I only require 1 serial port for everything?

Sorry, that is your design target.

I really doubt. For example, you have defined SPI pins for BMP280 sensor, but in reality you are using an i2c interface for it.

The whole code is a mess, sorry.

As about you title question, it seems that the SD card and GPS libraries both are very big and can't be used in the Uno/Nano together. Choose an another Arduino board. There are many board with NANO-like dimensions with a way more memory.

1 Like

Wrong.
You still require a two ports and you MUST initialize the both and not a single port twice.

Okay, is there anywhere I can learn more about all of this?

If you know how to code in different language, the first thing you need to learn is a C/C++ on which the Arduino is programmed

I am quite familiar with C#, and am trying to lean C++.

Keep it simple and stupid firstly.

Follow the example code that comes with the library or
run some tutorials for the hardware selected.
If you are happy with the results of the tutorials you can merge these to your project.

Have a nice day and enjoy coding in C++.

p.s.

https://www.learncpp.com/

1 Like