Ayuda. Curioso problema con Serial.print

Hola a todos, necesito ayuda para un curioso comportamiento que no soy capaz de resolver.

El proyecto que me traigo entre manos, se trata de sitema de control basado en un arduino uno, un LCD y un joystick.

Para reproducir el error no es necesario mas que una placa arduino uno.

Para codificar las pantallas que se mostraran en el LCD, guardo los datos en un estructura de C. El problema es que solo imprime en el Serial Monitor algunos Serial.print() y otro no.

El error se produce cuando añado la segunda pantalla en el array screens, que es un array cuyos elementos son estructuras del tipo Screen

El codigo para reproducir el problema os lo dejo a continuación

enum Type { empty=0, text, digits, chars, options } idText, idDigits, idChars, idOptions;

struct List {
  char list[7][8];
};

struct Limit {
  byte minimum;
  byte maximum;
};

struct Content {
  char text[16];
};

struct Segment {
  Type type;
  byte line;
  byte pos;
  byte length;
  char format[8];
  union {
    List l;
    Limit m;
    Content c;
  } data;
};

struct Screen {
   char title[16];
   struct Segment segments[16];
};

Screen screens[] = {
  {"Time", {
      {digits, 0, 0, 2, "%02d", 0, 24},
      {text, 0, 2, 1, "%s", ":"},
      {digits, 0, 3, 2, "%02d", 0, 59},
      {text, 0, 5, 1, "%s", ":"},
      {digits, 0, 6, 2, "%02d", 0, 59},
      {options, 1, 0, 3, "%s", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"}, 
      {text, 1, 3, 1, " "}, 
      {digits, 1, 4, 2, "%02d", 1, 31}, 
      {text, 1, 6, 1, "/"}, 
      {digits, 1, 7, 2, "%02d", 1, 12}, 
      {text, 1, 9, 1, "/"}, 
      {digits, 1, 10, 4, "20%02d", 14, 64}
    }
  },/**/ {"Temperature", {
      {text, 0, 0, 4, "%s", "Max:"},
      {digits, 0, 4, 2, "%02d", 10, 30},
      {text, 0, 9, 7, "%s", "Current"},
      {text, 1, 0, 4, "%s", ":"},
      {digits, 1, 4, 2, "%02d", 10, 30},
      {digits, 1, 12, 4, "%f", 10, 30}
    }
  }/**/
};


void setup()
{

   Serial.begin(9600);
   
   byte numOfScreens = sizeof(screens)/sizeof(Screen);
   
   Serial.print("numero de pantallas = ");
   Serial.println(numOfScreens);
   
   Screen* currentScreen;
   byte numOfSegments, numOptions;
   for(byte s = 0; s < numOfScreens; s++) {
     
     Serial.print("-----------------------\nScreen#");
     Serial.println(s);
     
     currentScreen = (Screen *) &screens[s];
     
     Serial.print("title = ");
     Serial.println(currentScreen->title);
     
     numOfSegments = sizeof(currentScreen->segments)/sizeof(Segment);
     
     Serial.print("num of segments => ");
     Serial.println(numOfSegments);
     
     for(byte i = 0; i < numOfSegments; i++) {
       
       if (currentScreen->segments[i].type == empty)
         continue;
       
       Serial.print("-----------------------\nSegment#");
       Serial.println(i);


     }
     
   }

}

void loop()
{
  
}

Al compilar y subirlo a un arduino uno; abrimos el Serial Monitor y nos encontramos:

2
0

16
5
6
7
8
9
10
11
1
Temperature
16
0
1
2
3
4
5
10
11

Si, en cambio, dejamos el array screens con un solo Screen

Screen screens[] = {
  {"Time", {
      {digits, 0, 0, 2, "%02d", 0, 24},
      {text, 0, 2, 1, "%s", ":"},
      {digits, 0, 3, 2, "%02d", 0, 59},
      {text, 0, 5, 1, "%s", ":"},
      {digits, 0, 6, 2, "%02d", 0, 59},
      {options, 1, 0, 3, "%s", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"}, 
      {text, 1, 3, 1, " "}, 
      {digits, 1, 4, 2, "%02d", 1, 31}, 
      {text, 1, 6, 1, "/"}, 
      {digits, 1, 7, 2, "%02d", 1, 12}, 
      {text, 1, 9, 1, "/"}, 
      {digits, 1, 10, 4, "20%02d", 14, 64}
    }
  }
};

y volvemos a ejecutarlo, en la ventana Serial Monitor nos aparece como deberia

numero de pantallas = 1
-----------------------
Screen#0
title = Time
num of segments => 16
-----------------------
Segment#0
-----------------------
Segment#1
-----------------------
Segment#2
-----------------------
Segment#3
-----------------------
Segment#4
-----------------------
Segment#5
-----------------------
Segment#6
-----------------------
Segment#7
-----------------------
Segment#8
-----------------------
Segment#9
-----------------------
Segment#10
-----------------------
Segment#11

Os agradeceria cualquier ayuda o comentario, ya que me siento en punto muerto.

Muchas gracias

Hola.
De momento hay una cosilla que no me casa (aunque no he profundizado del todo en tu estructura de datos).
Has definido en screen segments[16]; sin embargo en la definición de screens no defines los 16 segments en nunguno de los dos screens.

Mas problemas mi amigo, a mi la compilación con
Board : UNO

Me da que excede la RAM

Sketch uses 4.770 bytes (14%) of program storage space. Maximum is 32.256 bytes.
Global variables use 2.545 bytes (124%) of dynamic memory, leaving -497 bytes for local variables. Maximum is 2.048 bytes.

noter:
Hola.
De momento hay una cosilla que no me casa (aunque no he profundizado del todo en tu estructura de datos).
Has definido en screen segments[16]; sin embargo en la definición de screens no defines los 16 segments en nunguno de los dos screens.

Si es cierto, lo he definido con 16, porque tengo otra pantalla con un segmento de 16 opciones.

Se que estoy desperdiciando memoria, ya que por ahora, no uso mas de 7

Gracias

surbyte:
Mas problemas mi amigo, a mi la compilación con
Board : UNO

Me da que excede la RAM

Sketch uses 4.770 bytes (14%) of program storage space. Maximum is 32.256 bytes.
Global variables use 2.545 bytes (124%) of dynamic memory, leaving -497 bytes for local variables. Maximum is 2.048 bytes.

Es posible, no me habia dado cuenta.... Disculpa mi ignorancia, pero pensaba que disponia de 32Kb, pero veo que en las Global variables esta a 124%!!!!

Sólo dispongo de 2Kb, puff que poco...
No se mucho sobre la memoria del arduino. Sabeis alguna pagina con info que me pueda ilustrar sobre ello??

El problema es que es sólo la definicion de 2 pantallas y tengo 7 pantallas.

Me pregunto si me podeis ayudar a encontrar alguna solucion para poder codificar las 7 pantallas, que podran ser unos 16kb.

La verdad, es que solo necesito tener en RAM los datos de una pantalla, y cuando cambie cargo los datos de la siguiente pantalla.

Soy nuevo en esto del C, no se si hay alguna formula para codificarlo de una manera que ocupe menos.

Muy agradecido por vuestra ayuda!

Claro, rápidamente compra un MEGA
Tampoco será una panacea pero al menos tal como está me compila.

Luego tienes que pasar todo a constantes.

Dispones de buena cantidad de memoria FLASH para almacenar carteles no en RAM sino en FLASH. Asi que a repensar todo.

Buenas.
Yo te pediría que explicaras un poco qué es lo que estás intentando hacer, para enfocar un poco la cosa. De momento me parece que sí estás desperdiciando memoria, aunque es loable el trabajo que te has tomado en crear los enum, estructuras, e incluso uniones. Pero lo más probable es que tengas (intentaremos ayudarte) que iniciar el camino con otro enfoque.

surbyte:
Claro, rápidamente compra un MEGA
Tampoco será una panacea pero al menos tal como está me compila.

Luego tienes que pasar todo a constantes.

Dispones de buena cantidad de memoria FLASH para almacenar carteles no en RAM sino en FLASH. Asi que a repensar todo.

tengo un mega por ahi, lo probare, a ver cuanta memoria da... pero no, el camino es darle caña al C, y ser mas escrupuloso con la memoria... tiene que haber alguna otra solucion que me permita exprimir la memoria.

Lo que dices de utilizar la memoria Flash me parece buena idea, de echo habia pensado en utilizarla para guardar los datos de configuracion del programa.

Si tienes razón, toca comerse la cabeza..., para eso esta los problemas!

noter:
Buenas.
Yo te pediría que explicaras un poco qué es lo que estás intentando hacer, para enfocar un poco la cosa. De momento me parece que sí estás desperdiciando memoria, aunque es loable el trabajo que te has tomado en crear los enum, estructuras, e incluso uniones. Pero lo más probable es que tengas (intentaremos ayudarte) que iniciar el camino con otro enfoque.

El proyecto que estoy realizando es un sistema de climatización. Controlara algunos relés, la ventilación, temperatura y humedad.

Para poder controlarlo pretendia utilizar un LCD conectado por serial y un joystick analogico para poder moverse por la pantalla.

Realmente, me gustaría centrarme en el interface y finalmente, poder crear una librería que me permita crear cualquier interface en un LCD para poder reutilizarlo en otros proyectos.

Yo me llevo bien con los lenguajes web, javascript, php, actionscript, java, etc..., pero no se mucho de C. Leyendo sobre arduino, he podido ver que se puede programar orientado a objeto no es lo mejor para el pequeño microcontrolador y tampoco estoy muy puesto.

Asi que estaba intentandolo con unas structuras e uniones, con la intención de simplificar, pero veo que tengo restricciones con la memoria.

Me pregunto como puedo exprimir la memoria disponible. Esta claro que la ram es de solo 2048 bytes y una pantalla, en una estructura, debe ocupar 1024 bytes, asi que la ram no es su lugar.

Quizás, pudiera ser ampliar la EEPROM con un chip de 64Kb, o un SD Card donde añadir los datos... pienso que debo cargar los datos de una pantalla y debería hacerlo rápidamente, no se si alguien tiene experiencia y me podría dar su opinión sobre que tipo de memoria utilizar.

He encontrado una pagina con como guardar estructuras y arrays en la memoria EEPROM. Por si a alguien le interesa Arduino Playground - EEPROMWriteAnything

De todas maneras con 512 bytes, para mi no son suficientes

Y jamas pensaste que ya estaba resuelto no? Incluso con rotary encoder o joystick.
busca Arduino Phi menu rotary enconder
Pero directamente PHI MENU es la solución para LCDs Texto.

Trabaja con botones, con serial, con rotary enconder, con lcd shield. todas las situaciones. Optimizado en memoria. Es fantástico.