2

When i am uploading my code to arduino nano, i am getting message about high dynamic memory usage (87%):

Sketch uses 17,628 bytes (57%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,751 bytes (85%) of dynamic memory, leaving 297 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

But despite this, its uploading to my arduino nano and everything works fine without action method's code. How to use code (code to work with LCD) wich is located in action() method. If i use hidden code, im getting message error opening test.txt (not enough memory). But if code which is controls LCD screen is annotated then SD card works fine.

If i use this code, i'm getting problem with SD card. But i can still use LCD and SD on same arduino board separately without any problems, but if i try to combine it, im getting some problems with SD card reading.

void action() {
//  display.display();
//  display.clearDisplay();
//  display.setCursor(0, 0);
//  display.setTextSize(2);
//  display.setTextColor(WHITE);
//  display.println(sensorValue);
// if uncomment this code, i am getting error with sd card reading (possible memory issue)
}

All code:

#include <Wire.h>
#include <Adafruit_SSD1306.h>

#include <SPI.h>
#include <SD.h>


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

int count_iterations = 0;

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


File myFile;

void setup() {



  /// SD START
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

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

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
  //// SD END
}

void loop() {
  sensorValue = analogRead(analogInPin);
  if (sensorValue < 1000) {
    action();
  }
}

void action() {
//  display.display();
//  display.clearDisplay();
//  display.setCursor(0, 0);
//  display.setTextSize(2);
//  display.setTextColor(WHITE);
//  display.println(sensorValue);
// if uncomment this code, i am getting error with sd card reading (possible memory issue)
}

1 Answer 1

1

Your code is using in the neighborhood of 150 bytes for text-strings in RAM, much of which can be moved to PROGMEM quite easily. For example, replace

Serial.print("Initializing SD card...");

by

Serial.print(F("Initializing SD card..."));

Changes like that to Serial.print() arguments should free up about 140 bytes of RAM. To free up another 8 bytes, instead of SD.open("test.txt" ...), write SD.open(FileName ...) with FileName previously declared via char *FileName = "test.txt"; so that the text test.txt appears in RAM once instead of twice.

In short, if 150 bytes will make the difference, that much memory reduction is easy.


I briefly examined the source code behind the Adafruit_SSD1306.h and SD.h headers, to see if they use some large arrays in RAM, such as 512 bytes of sector data, or some hundreds of bytes for frame buffers.

Ordinarily, such arrays are difficult to get rid of without a rewrite from scratch or without major loss of functionality. For most one-off projects, the effort involved isn't worthwhile: one can instead use an Arduino Mega2560 system, which has 8 KB of RAM, vs the Arduino Nano's 2KB RAM; or can use an Arduino Due with 96KB RAM; or a Teensy, with 8, 16, or 64KB RAM.

However, if you plan a production run and are trying to hold down costs by using Nanos, consider the following approach: Carefully arrange the processing so that you are done with SD buffers before needing a display frame buffer; and revise the libraries so the SD buffer and frame buffer overlap. That is, place the smaller buffer within the same region of memory holding the larger buffer. If processing can't be neatly separated, blank the display while using the shared buffer area for accessing SD data.

[Note, I edited this answer and expanded discussion of buffers in the libraries.]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.