Need some way of limiting SRAM usage. Can I get some tips? (Beginner)

Here’s my script. I’m at 83% of dynamic memory, and now the script stops writing the SD half way through at random spots (Even though each chunk of code works on its own). How can I get my dynamic memory usage back down below 80%?

I’m flying this thing tomorrow morning, so any help would be very appreciated!!

/* SD SD SD SD SD */
#include <SPI.h>
#include <SD.h>
File myFile;
/* END SD END SD END SD END SD */



/* SERVO SERVO SERVO SERVO */
#include <Servo.h>  // servo library
Servo servo1;  // servo control object
/* END SERVO SERVO SERVO SERVO */

/*ALTIMETER */
#include <Wire.h> 
#include "IntersemaBaro.h"
Intersema::BaroPressure_MS5607B baro(true);
/* END ALTIMETER */

void setup() { 
  
  delay(3000);

  
  /*SD SD SD SD SD SD SD SD SD SD SD SD SD */

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }
  Serial.println(F("Initializing SD card..."));
  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println(F("initialization failed!"));
    return;
  }
  Serial.println(F("initialization done."));
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.println(F("Writing to test.txt..."));
    myFile.println("BEGIN NEW FLIGHT");
    // close the file:
    myFile.close();
    Serial.println(F("done."));
  } else {
    // if the file didn't open, print an error:
    Serial.println(F("error opening test.txt"));
  }
  /* END SD END SD END SD END SD END SD */
  
  

  
   /* SERVO SERVO SERVO */
 
   // initialize digital pin 13 as an output.
      pinMode(3, OUTPUT);
      servo1.attach(9);
      servo1.write(170); 

   /* END SERVO SERVO SERVO */

    Serial.begin(9600);
    baro.init();
 
 
 
 // BEGIN FLIGHT BEGIN FLIGHT
 
 
 
 
 
 
 
 
    float alt1 = baro.getHeightCentiMeters();
    delay(1000);
    float alt2 = baro.getHeightCentiMeters();
    delay(1000);
    float alt = (alt2)-(alt1);
  
 
    while (alt < 609600) {
       float alt3 = baro.getHeightCentiMeters();
       delay(1000);
       alt = alt3-alt1;
  
  /*
       Serial.print("Centimeters: ");
       Serial.print((float)(alt));
       Serial.print(", Feet: ");
       Serial.println((float)(alt) / 30.48);
       
   */
 
      myFile = SD.open("test.txt", FILE_WRITE);
      //  myFile.print("Centimeters: ");
      // myFile.print((float)(alt));
       myFile.print("Time Elapsed: ");
       myFile.print((float)millis()/1000);
       myFile.print(", Feet: ");
       myFile.println((float)(alt) / 30.48);
       myFile.close();
       delay(1000);
 
   }
  
// OPEN VENT!!  
  
  
    // Serial.println(F("OPEN VENT OPEN VENT OPEN VENT OPEN VENT OPEN VENT "));
    myFile = SD.open("test.txt", FILE_WRITE); 
    myFile.println("BEGIN VENTING");
    myFile.close();
    servo1.write(0); 
  
  
  
  
  
  
  /* Wait for ascent rate to become less than 100 cm/s */
  
  

  float ascent = 1;
  
  while (ascent > 0) {
   
    myFile = SD.open("test.txt", FILE_WRITE); 
    myFile.println("Open Vent to slow ascent rate");
    servo1.write(0);   
 
    
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000);
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000);
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000); 
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000); 
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000); 
    // CLOSE VENT TO CHECK ASCENT RATE
 
    myFile.println("Close Vent to check ascent rate");
    servo1.write(170);
    
    float asc1 = baro.getHeightCentiMeters();
    delay(2000);
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000);
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000);
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000); 
    myFile.print("Time Elapsed: ");
    myFile.print((float)millis()/1000);
    myFile.print(", Altitude: ");
    myFile.println((float)baro.getHeightCentiMeters()-(alt1));
    delay(2000); 
    float asc2 = baro.getHeightCentiMeters();
    ascent = ((asc2)-(asc1))/10;
 
    
    myFile.print("Ascent rate:");
    myFile.println((float)(asc2)-(asc1));   
  }

  
    myFile = SD.open("test.txt", FILE_WRITE);
    myFile.println("SEAL VENT AND BEGIN FLOAT");
    
    servo1.write(170); 
    delay(1000);
    servo1.write(50); 
    delay(1000);
    servo1.write(170); 
    delay(1000);
    servo1.write(50); 
    delay(1000);
    servo1.write(170); 
    delay(1000);
    servo1.write(50); 
    delay(1000);

    
    
    // TIMER UNTIL SOFT LANDING
    
    int i=0;
    myFile.println(i);
    
    while (1) {
      
      myFile = SD.open("test.txt", FILE_WRITE); 

      float time = millis();
      if (i > 10) {   
        myFile.println("time is greater than threshold - TERMINATE FLIGHT");
        servo1.write(0); 
        while(1){
          myFile.print("Time Elapsed: ");
          myFile.print((float)millis()/1000);
          myFile.print(", Altitude: ");
          myFile.println((float)baro.getHeightCentiMeters()-(alt1));
        }
      }
      else {
        myFile.println("time is not greater than thresh");
        myFile.print("Time Elapsed: ");
        myFile.print((float)millis()/1000);
        myFile.print(", Altitude: ");
        myFile.println((float)baro.getHeightCentiMeters()-(alt1));
        
        servo1.write(170); 
      }
      myFile.close();
      
      i++;
      
      delay(2000);
      }
 
}

void loop() {




}

There is no dynamic memory on an Arduino; it's all static.

myFile.print("Time Elapsed: ");

More RAM,

Use the F() macro on all your ("mmmm") string constants not just a few.

use a byte not and int with this line

    int i=0;

Mark

Several of your string literals are repeated a lot (e.g., Altitude and Time Elapsed). Create an array of pointers to those constants to save a little memory.

All of the text constants (labels) written to file can be put in PROGMEM and printed from there.

As said above, use F() for more string literals.

And for form, put the stuff from

// BEGIN FLIGHT BEGIN FLIGHT

down into the loop() function, rather than the setup() function.

My apologies, for some reason I thought that the F() macro was only for Serial, but it's not! It's part of the PRINT class that Serial, SD and other libraries use.

I am assuming that the compiler optimizes duplicate F() strings as one.

GoForSmoke: I am assuming that the compiler optimizes duplicate F() strings as one.

I vaguely recall that it does not. (confirmed by The Great and Wise Gorcle; apparently my memory still works)

If I remember correctly PROGMEM / Flash string constants have to have global scope to be pooled. (which makes pooling a bit pointless) (this is not correct)

I believe there was a discussion on this forum discussing the details. Found it... http://forum.arduino.cc/index.php?topic=194603.0

What I have been doing is putting prompt and message texts into PROGMEM and using my own print utility. But what I could do is make a function with my one copy of each print F() line in a switch-case and call them by number. Hey, the text will be in flash along with the code to print it.

Dear john09121,

You started a topic here : http://forum.arduino.cc/index.php?topic=308128.0 You were told to use the 'F()' macro to keep the strings in flash.

You started a new topic here : http://forum.arduino.cc/index.php?topic=311699.0 You were told to use the 'F()' more. Not only for the Serial.print() and Serial.printf(), but also for the myFile.print() and myFile.printf().

Then you started this topic, and you were told once again, to use the 'F()' macro more.

It is about all the "myFile.print("Time Elapsed: ");" that could use the 'F()' macro.