Hitting Dynamic Memory Error - ARDUINO Uno, VL53L0X & SD

I am somewhat new to using Arduinos and best practices for writing code. My current project requires using optical time of flight sensors (VL53L0X), real time clock data, and SD storage. I am using the Adafruit Datalogging Shield to handle RTC / SD concerns.

The issue: I seem to be hitting dynamic memory thresholds that prevent my code from functioning with both the VL53L0X setup and SD card libraries. The code below is simply the Adafruit 'vl53l0x' example code with some added commented lines which relate to SD card operation.

#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox = Adafruit_VL53L0X();

//// 1
//#include <SPI.h>
//#include <SD.h>
//#include <Wire.h>
//
//// 2
//File myFile;
//
////3
//String csv_delim = ", ";

void setup() {
  Serial.begin(115200);

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }
  
  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power 
  Serial.println(F("VL53L0X API Simple Ranging example\n\n")); 
}


void loop() {
  VL53L0X_RangingMeasurementData_t measure;
    
  Serial.print("Reading a measurement... ");
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }
    
  delay(100);
}
  • If I execute the code above (leaving sections 1, 2, and 3 commented) the sketch uses 1236 (60%) of dynamic memory and correctly utilizes the sensor and outputs distances.
  • If I execute with section 1 uncommented (the three includes), the sketch uses 1847 bytes (90%) of dynamic memory and correctly utilizes the sensor and outputs distances.
  • With 1 and 2 uncommented, the sketch uses 1892 bytes (92%) of dynamic memory and correctly utilizes the sensor and outputs distances.
  • Finally, with 1, 2, and 3 uncommented the sketch uses 1912 bytes (93) of dynamic memory and the console window now shows "Failed to boot VL53L0X" instead of producing distance measurements.

Am I correct in assuming that the error stems from the large dynamic memory use? If so, are there any ways to reduce the large amount of memory my code is using? I am surprised to be hitting the limits of the Uno with one simple distance sensor and an SD card library with only one variable declared. My eventual intention was to include RTC libraries, GPS libraries, and use a total of 4 sensors. Is this just not possible?

  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));

Why the inconsistencies? The F() macro should be use to wrap all string literals.

Using the String class is NOT a good idea on the Arduino.

Is this just not possible?

On a Uno, probably not. On a Mega, no problem.

Thanks for your response!

PaulS:
Why the inconsistencies? The F() macro should be use to wrap all string literals.

Using F() on strings helped me get the memory with the full code uncommented down to the usable level of 1854 bytes (90%) - thanks for the tip. Obviously I'll probably still run into my memory ceiling when incorporating more sensors but this is helpful for now. As for the reasoning behind the inconsistencies, that's how it loads from the tutorial! Perhaps our friends at Adafruit can answer to that.

PaulS:
Using the String class is NOT a good idea on the Arduino.
On a Uno, probably not. On a Mega, no problem.

I want to make sure I understand. It looks like using a Mega increases my dynamic memory from 2K to 8K. If I write a script that installs all of the packages I need, incorporates the number of sensors I am interested in, etc., I should be able to figure out how much dynamic memory it uses by attempting to upload it to the Uno. If that amount is <8K the Mega will be able to run the script? I am trying to avoid ordering a Mega without confirming it is the correct tool for the job.

You can compile for the Mega without actually having one.