Problemas de SRAM en Arduino Nano por librerías [SOLUCIONADO]

Saludos,

Vengo con una inquietud en cuanto al uso de SRAM del programa que actualmente estoy realizando. Actualmente estoy haciendo uso de tres dispositivos: un sensor TCS3200, un modulo microSD y una pantalla OLED 0.96". El problema viene al tratar de usar la pantalla y el modulo microSD juntos, ya que al incluir sus librerias al inicio del programa, una vez compilado el programa, el IDE de arduino me arroja el mensaje:
"Poca memoria disponible, se pueden producir problemas de estabilidad"
Ya que efectivamente se está usando el 97% de la SRAM disponible, algo que me parece muy raro teniendo en cuenta que el codigo no es necesariamente extenso. Sin embargo, subí el programa para ver si funcionaba correctamente pese al mensaje, pero lastimosamente no, el modulo MicroSD no se inicializa correctamente. Decidí entonces probar diferentes cosas, y llegué a la conclusión de que las librerias eran el problema, ya que ambas ocupan por si solas casi la mitad de SRAM con la que cuenta el ATMega328p, y que al juntarse provocan el mensaje mostrado en el IDE. Mi pregunta entnces es:

¿Hay alguna forma de reducir este consumo de SRAM? ¿Alguna forma quizá de reducir el tamaño de estas librerías?

Algo que intenté y no logró frutos, fue poner en comentarios algunas de las fuciones de la librería OLED que no estaba usando en mi programa, pero no se vio cambio alguno en cuanto al consumo de SRAM.

Agradecería la ayuda que me puedan brindar.

Tendría que ver de cuáles estamos hablando.

Si no habría que buscar alternativas más ligeras o aumentar la RAM con un Arduino Mega.

Hola Lucario, las que estoy usando especificamente son las siguientes:

#include <SD.h>
#include <OLED_I2C.h>

Con respecto a la segunda opción, no es viable en mi caso ya que estoy realizando un dispositivo y requiero de un microcontrolador pequeño, para poder realizar mi propio PCB.

Saludos y quedo atento a cualquier comentario.

ArduMyth, eso es lo raro puesto que carga las variables que se declaran en la libreria en su totalidad, sin yo siquiera usarlas en mi codigo. Con respecto a lo de usar 2 ATmega328p podría considerarse la opción, pero como se haría la comunicación que dices.

De acuerdo a tu capacidad hay 3 modos de comunicar dos arduinos

  1. comunicación serie.
  2. Comunicaicón I2C
  3. comunicación SPI.

No has puesto el código, ni los enlaces de las librerias como para que alguien intente observar lo que tu comentas.
Y ver si se puede sugerir algo o no.

Lo mas lógico es que no se pueda asi que podrias simplemente destinar un arduino para la lectura de un sensor y la SD y otro para la pantalla OLED
Supongo que la pantalla es la que te restringe en memoria.

Considera que tienes alternativas chicas como los ATtinyXX que tmb pueden ayudarte.
O por el contrario, puedes usar otros dispositivos que tienen mas SRAM pero esta claro que no es tu idea.
Ejemplo los SMT32 que lucen como un NANO pero tiene mucha RAM y FLASH.
Son baratos y potentes.
Hay muchas opciones.

Saludos surbyte, erro mio no subir codigo, a continuación lo muestro:

#include <SD.h>
#include <OLED_I2C.h>

#define S0 3
#define S1 4
#define S2 6
#define S3 7
#define sensorOut 5

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
const int inputPin = 2;
int value = 0;
int fR = 0;
int frequencyG = 0;
int frequencyB = 0;
int i=0;
int sumaR = 0;
int sumaG = 0;
int sumaB = 0;
int prR=0;
int prG=0;
int prB=0;
OLED myOLED(SDA, SCL, 8);
File archivo;
void setup() {
  myOLED.begin();
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  pinMode(inputPin, INPUT);
  
  // Setting frequency-scaling to 20%
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);

  
  Serial.begin(9600);
    Serial.print(F("Configurando SD ..."));
  if (!SD.begin(10)) {
    Serial.println(F("No se pudo configurar correctamente"));
    return;
}
Serial.println(F("Configuración exitosa"));
}

void loop() {
  value = digitalRead(inputPin);
  if (value == HIGH) {
          myOLED.setFont(SmallFont);
          myOLED.print("Universidad El Bosque", CENTER, 0);
        Serial.println(F("Guardando en SD: "));
      for(i=0;i<10;i++){
    archivo = SD.open("datos.txt", FILE_WRITE);
    if(archivo){
  digitalWrite(S2,LOW);
  digitalWrite(S3,LOW);
  fR = pulseIn(sensorOut, LOW);
  sumaR = sumaR+fR;
  archivo.print("R= ");
  archivo.print(fR);
  archivo.print("  ");
  delay(500);
  digitalWrite(S2,HIGH);
  digitalWrite(S3,HIGH);
  frequencyG = pulseIn(sensorOut, LOW);
  sumaG=sumaG+frequencyG;
  archivo.print("G= ");
  archivo.print(fR);
  archivo.print("  ");
  delay(500);
  digitalWrite(S2,LOW);
  digitalWrite(S3,HIGH);
  frequencyB = pulseIn(sensorOut, LOW);
  sumaB=sumaB+frequencyB;
  archivo.print("B= ");
  archivo.print(frequencyB);
  archivo.println("  ");
  delay(500);
  
  prR = sumaR/10;
  prG= sumaG/10;
  prB= sumaB/10;
     
  Serial.print(F("R= "));
  Serial.print(fR);
  Serial.print(F("  "));
  Serial.print(F("G= "));
  Serial.print(frequencyG);
  Serial.print(F("  "));
  Serial.print(F("B= "));
  Serial.print(frequencyB);
  Serial.println(F("  "));
  delay(500);

  archivo.print("RT= ");
  archivo.print(prR);
  archivo.print(" ");
  archivo.print("RG= ");
  archivo.print(prG);
  archivo.print(" ");
  archivo.print("RB= ");
  archivo.print(prB);
  archivo.println(" ");

  archivo.close();
      }
    }
  Serial.print(F("R= "));
  Serial.print(prR);
  Serial.println(F("  "));
  Serial.print(F("G= "));
  Serial.print(prG);
  Serial.println(F("  "));
  Serial.print(F("B= "));
  Serial.print(prB);
  Serial.println(F("  "));

  myOLED.setFont(SmallFont);
  myOLED.print("pH: ", 40, 30);
  myOLED.setFont(MediumNumbers);
  myOLED.printNumI(prR, 60, 20);
  myOLED.setFont(SmallFont);
  myOLED.print("Estado: ", 30, 45);
  myOLED.setFont(MediumNumbers);
  myOLED.printNumI(prG, 70, 40);
  delay(1000);
  myOLED.update();
  myOLED.clrScr();
      }
  }

OLED_I2C.zip (451 KB)

Yo compile esto con un ATmega328p correspondiente a un NANO y mira lo que me dice

DATA: [===== ] 48.5% (used 994 bytes from 2048 bytes)
PROGRAM: [===== ] 53.0% (used 16288 bytes from 30720 bytes)
[SUCCESS] Took 10.50 seconds

Como es posible?

Igualmente ahora veo esto

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];

y podrías poner las dos librerias en flash y ahorrarte mucho espacio.

para ello debes usar PROGMEM

Pero revisemos la disparidad entre tus datos y los mios. Algo debo haber elegido mal yo.

Use un NANO que es identico al UNO.

Vaya pues me dejaste sorprendido con lo que te sucedio, a mi me sale el siguiente mensaje:

El Sketch usa 15968 bytes (51%) del espacio de almacenamiento de programa. El máximo es 30720 bytes.
Las variables Globales usan 2009 bytes (98%) de la memoria dinámica, dejando 39 bytes para las variables locales. El máximo es 2048 bytes.
Poca memoria disponible, se pueden producir problemas de estabilidad.

Intenté lo que me comentas de PROGMEM, sin embargo no hubo efecto alguno de disminución del consumo SRAM. Que crees que pueda ser, será depronto por la versión del IDE o que puede ser. No habia intentado compilar el programa en otro Arduino y me dejaste sorprendido.

Vaya, pues tenías toda la razón.

Acabo de probar en otro computador y compile el mismo programa, y efectivamente sólo usa el 48% de la SRAM como lo indicas. Ahora funciona todo correctamente. Pero ahora si quedé aún mas confundido, que crees que pueda pasar, alguna forma de solucionar esto? Definitivamente es la primera vez que me sucede esto.

Por lo visto Defautlfont.c ya tiene las fuentes cargadas en flash usando PROGMEM de modo que me quedé sin explicaciones de porque en una PC te consume 98% y en otra menos de 50%.

Surbyte muchas gracias por tu ayuda, acabé de realizar una instalación en limpio del IDE de Arduino en el computador que presentaba ese error, y ya funciona normal. Que loco eso que me estaba pasando, de verdad no encuentro una explicación lógica, pero bueno, afortunadamente este post tiene un final feliz. Muchas gracias nuevamente por tu ayuda, y a todos los que intervinieron.

Hasta una proxima oportunidad. Saludos.