Problema con el espacio de las variables y el Sketch

Hola a todos, al final he conseguido adaptar el codigo a mi Arduino, pero me da el siguiente error.

El Sketch usa 18124 bytes (58%) del espacio de almacenamiento de programa. El máximo es 30720 bytes.
Las variables Globales usan 5344 bytes (260%) de la memoria dinámica, dejando -3296 bytes para las variables locales. El máximo es 2048 bytes.
No hay suficiente memoria, ver http://www.arduino.cc/en/Guide/Troubleshooting#size para obtener consejos sobre cómo reducir su huella.
Error compilando para la tarjeta Arduino Nano.

original.ino (21 KB)

Independientemente de las variables que utilizen las librerias de la pantalla TFT, que de por si seguro ocupa mucha memoria, tienes MUUUUCHAS variables en tu programa. Casi todas del tipo float (4 bytes) o unsigned long (4 bytes también), incluso he visto algún que otro array de 90 float... Eso es mucho para el arduino. Ten en cuenta que el atmega tiene solo 2k de RAM, no es un procesador con 4GB de RAM.

Debes de repasar todo el programa, e intentar reducir el número de variables:

  • Si utilizas constantes, definelas como macros no como variable, usando #define
  • Intenta trabajar con int en vez de float, siempre y cuando se pueda hacer la conversión. Además será más rápido.
  • Reutiliza variables. Por ejemplo para recorrer un array no hace falta definir 200 variables indice. Con una sola variable int deberias poder recorrerlas todas, o casi todas.
  • Intenta utilizar la macro F() para cadenas de texto, en los sitios que puedas

Hay te dejo unos consejos. Ahora tu trabajo es empezar a practicarlos.

Muchas gracias por la respuesta. he estado mirando y hasta donde llega mi conocimiento, he conseguido bajar a un 216%... de un 260%... pero aun asi ocupa mucho.

He estado mirando, y con un arduino mega que tiene mas RAM se solucionaria el problema?
Es que el codigo no puedo borrar ya nada mas... es vital todo.

ivan0909:
He estado mirando, y con un arduino mega que tiene mas RAM se solucionaria el problema?

Un Arduino Mega tiene 8192 bytes (8 KB) de RAM.

Respecto a las optimizaciones: hay tantas variables que no sé cuales pueden cambiar en el transcurso de la ejecución del programa.
Las que nunca llegan a cambiar su valor, conviértelos en una sentencia #define (const no sirve porque de todos modos lo sigue cargando en memoria). Otra ventaja del #define es que si en ningún momento se utilizara dicha definición, no se incluye en el compilado.

Cadenas de caracteres u otro grupo de datos que no se vaya a alterar en transcurso de la ejecución, deben ser ingresados con la macrofunción F() o declarados const pero junto con PROGMEM. Por ejemplo:

Serial.println("SET BT NAME OpenBarbell");

Ahorra memoria si lo haces así:

Serial.println(F("SET BT NAME OpenBarbell"));

Mira:

const int repArrayCount=90;
//---
float repArray[repArrayCount] = {0.0};
//---
float testVelocity[repArrayCount] = {0.0};
float peakVelocity[repArrayCount] = {0.0};
float peakAcceleration[repArrayCount] = {0.0};
uint16_t dispArray[repArrayCount] = {0};
float timeArray[repArrayCount] = {0.0};

He quitado lo demás y dejo solo eso. Defines 4 arrays de 90 elementos de float, 4x4x90=1440 bytes. Luego un deo uint16_t de igual tamaño, 2x90=180. Usas 1620 bytes solo en eso. Y no me he leido el resto del código con lo que no se que hace, pero usas muchas mas variables.

Comprueba que esos array son necesarios, si los usas y, si puedes, sustituirlo por algo mejor.

Hola buenas me encuentro en la misma situación de falta de memoria.

Uso un Arduino Uno que he probado con la shield ethernet y con otros componentes (sensor ultrasonico, dht11, leds, servo...) por separado, y el problema vino al intentar unir las piezas del puzzle (y aún tengo mucho código que añadir):

El Sketch usa 18326 bytes (56%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 1621 bytes (79%) de la memoria dinámica, dejando 427 bytes para las variables locales. El máximo es 2048 bytes.

Las globales antes ocupaban el 86%, he conseguido reducirlo con el uso de F al usar println cuando no varia nada en lo que voy a imprimir. No he conseguido reducir el uso de memoria con #define, aunque antes usaba const, no parece variar nada a simple vista.

Os dejo las variables globales y librerías (Ethernet y SPI ocupan mucho??) que tengo definidas, por si podéis aportarme algo...estoy viendo que todo con un placa mega sería mas sencillo pero estoy bastante pobre y son mas bien carillas

#include <SPI.h>
#include <Ethernet.h>
#include <DHT.h>

#define iluminacion 3
#define leds 4
#define zumbador 5
#define sensorE 6
#define sensorT 7
#define pinDHT 8
#define pinLDR 0

/*
const int iluminacion = 3;
const int leds = 4;
const int zumbador = 5;
const int sensorE = 6; //Pin del Echo del sensor (IN)
const int sensorT = 7; //Pin del trigger del sensor (OUT)
const int pinDHT = 8;
const int pinLDR = 0;
*/

boolean controlParkingActivado;
boolean alarmaActivada;
boolean LDRactivado;


//Sensor DHT11 Temp/humedad
DHT dht (pinDHT, DHT11);
//Variables para realizar mediciones
boolean medicionActiva;
long tiempoMedicion, tiempoTotalMedicion, inicioMedicion, medicionAnterior;
//Variables de conexion ethernet
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);

const int nComandos = 7;
String comandos [] = {"alarma", "parking", "led", "ledauto", "medicion", "estado", "comandos"};

Gracias de antemano!!

Hay cosas que sí no tiene remedio (instancia DHT, dirección MAC e instancia EthernetServer), pero algunas otras sí.

Las variables de tipo long debes tomar en cuenta lo siguiente: ¿realmente puede acabar en un número muy grande?, ¿realmente necesito la capacidad de representar valores negativos?. A la ligera decides que sea de ese tipo, pero podría ser que dicha variable nunca sobrepase los 65535, máximo del unsigned int.

Luego está esto:

String comandos [] = {"alarma", "parking", "led", "ledauto", "medicion", "estado", "comandos"};

Aunque dichos objetos no se usen para concatenar, si no para sólo lectura; aún así tienden a ocupar más espacio que al haberlos declarado de formas alternativas. Mayor ahorro de memoria de la siguiente forma:

const char comandos[][] PROGMEM = {"alarma", "parking", "led", "ledauto", "medicion", "estado", "comandos"}; // 0 bytes de RAM ocupa
char comandoBuffer[9]; // 9 bytes de RAM ocupa. Se usa cuando cierta función que lo necesita, no admite strings en memoria flash

Un string en memoria flash se recupera a RAM de la siguiente manera:

strcpy_P(comandoBuffer, comandos[indice]);

Los print y println no necesitan de este último paso, solo has un "casting de tipo" y pones la referencia directamente:

Serial.println((__FlashStringHelper)comandos[indice]);

__FlashStringHelper es el tipo de dato resultante de la macrofunción F().