Problema memoria dinamica

Buongiorno, sono nuovo in questo forum e ne approfitto subito per un problema a cui non riesco trovare soluzione. Ho creato un piccolo sketch per creare un orologio crepuscolare da abbinare ad un Arduino Nano, il mio problema sta nel fatto che quando utilizzo i valori di mese e giorno, prelevati da un ds3231, come indice di un array 3d, in fase di compilazione mi dice che sono arrivato al 147% di memoria dinamica.
Questo non succede se al posto di variabili dinamiche, uso dei valori statici, ed anche se compilo lo sketch per arduino Mega o arduino Due. Come posso fare per far lavorare il codice su Arduino Nano? Allego parte del codice per spiegarmi meglio

>Decachi: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non avrai sistemato il codice come richiesto, nessuno ti potrà rispondere, quindi ti consiglio di farlo al più presto. :wink:
P.P.S: E comunque da quel pezzetto NON si capisce, posta anche il resto del codice dove definisci il vettore.

int m=(Clock.getMonth(Century));
int g=(Clock.getDate());
 accH= orari[m][g][2];   
 accM= orari[m][g][3];
 speH= orari[m][g][0];
 speM= orari[m][g][1];

Fai 2 conti:
i mesi possono andare fino a 12 e i giorni fino a 31.
percui 12314 é 1488
Percui stai usando un array di 1488 byte su un controller con 2048 byte di memoria. I restanti ca 1500 Byte RAM segnati dal compilatore li userai per altre variabili. Inoltre il conto della mamoria in fase di compilazione non prevede l' uso di altra memoria durante l'esecuzione come per lo stack e come per esempio per il Serial.print("testo");
Con altri modelli di Arduino non hai problemi perché quei 2 modelli hanno molta piú RAM.

Ripensa la logica del Tuo Sketch.
Cosa é quel Array e perché Ti serve nella RAM?
Potresti mettere i dati nella FLash con progmem();
Ciao Uwe

Scusate ma non sono molto pratico con i forum.
Spero che così vada bene.
Ecco il mio codice:

/**
* Centrale Attivazione luci notturne con orario crepuscolo
* Connessioni:
* A5 - SCL - DS3231
* A4 - SDA - DS3231
*/
#include <DS3231.h>

DS3231 Clock;

byte Year;
byte Month;
byte Date;
byte DoW;
byte oras;
byte minutis;
byte secondis;
int ora;
int minuti;
int secondi;
byte j=0;
bool Century=false;
bool h12;
bool PM;
char InString[20];
int accH;   
int accM;
int speH;
int speM; 
static uint8_t gg;
static uint8_t mins;
const uint8_t  SPRINTF_BUFFER_SIZE =     32;       
char          inputBuffer[SPRINTF_BUFFER_SIZE]; 
byte orari[13][32][6]={{{0,0,0,0},{0,0,0,0}},
                      {{1,0,0,0},{7,15,17,16},{7,15,17,17},{7,15,17,18},{7,15,17,19},{7,15,17,20},
...
{5,55,17,48},{5,50,17,45}}
};

void setup(){ 
  Serial.begin(57600); // Initialize serial communications with the PC
  Wire.begin();  // Start the I2C interface
  Clock.enableOscillator(true, true, 3);
} 

void loop() {    
// SEZIONE IMPOSTAZIONE ORA DA SERIALE ------------------------------------------------------------------------
  // Imposta l'ora da seriale
  if (Serial.available()) {
    set_datetime();
  }
    ora=(Clock.getHour(h12, PM));
    minuti=(Clock.getMinute());
    secondi=(Clock.getSecond());

// SEZIONE CONTROLLO CAMBIO MINUTO ----------------------------------------------------------------------------  
  if (mins != Clock.getMinute()) { // Output if minutes have changed   // 
    sprintf(inputBuffer,"%02d:%02d:%02d %02d/%02d/%02d", Clock.getHour(h12,PM),Clock.getMinute(), Clock.getSecond(), Clock.getDate(), Clock.getMonth(Century), Clock.getYear()); 
    Serial.println(inputBuffer);    
          if (ora >= accH & minuti >= accM || ora <= speH & minuti <= speM){
          Serial.println(F("Luci accese..."));
          }
      else{
          Serial.println(F("Luci spente..."));
      }
    mins = Clock.getMinute();  
  }
  
// SEZIONE CONTROLLO CAMBIO GIORNO ---------------------------------------------------------------------------- 
  if (gg != Clock.getDate()) { // controllo cambio giorno
int m=(Clock.getMonth(Century));
int g=(Clock.getDate());
 accH= orari[m][g][2];   
 accM= orari[m][g][3];
 speH= orari[m][g][0];
 speM= orari[m][g][1];    
  
Serial.println(F("E' un nuovo giorno!!"));
Serial.println(F("Inposto i nuovi orari di accensione e spegnimento."));
Serial.print(F("Orari Spegnimento/Accensione: "));
    sprintf(inputBuffer,"%02d:%02d - %02d:%02d", speH,speM,accH,accM); 
    Serial.println(inputBuffer); 
    gg = Clock.getDate(); 

  }
  
// FINE VOID LOOP --------------------------------------------------------------------------------------------------------------------
}
///////////////////////////////////////////////////////
void GetDateStuff(byte& Year, byte& Month, byte& Day, byte& DoW, byte& ora, byte& minuti, byte& secondi) {
  // Formato data/ora da seriale YYMMDDwHHMMSS, con 'x' alla fine.
  boolean GotString = false;
  char InChar;
  byte Temp1, Temp2;
  while (!GotString) {
    if (Serial.available()) {
      InChar = Serial.read();
      InString[j] = InChar;
      j += 1;
      if (InChar == 'x') {
        GotString = true;
      }
    }
  }
  Serial.println(F("Nuova date e ora inserita"));
  // Read Year first
  Temp1 = (byte)InString[0] -48;
  Temp2 = (byte)InString[1] -48;
  Year = Temp1*10 + Temp2;
  // now month
  Temp1 = (byte)InString[2] -48;
  Temp2 = (byte)InString[3] -48;
  Month = Temp1*10 + Temp2;
  // now date
  Temp1 = (byte)InString[4] -48;
  Temp2 = (byte)InString[5] -48;
  Day = Temp1*10 + Temp2;
  // now Day of Week
  DoW = (byte)InString[6] - 48;   
  // now Hour
  Temp1 = (byte)InString[7] -48;
  Temp2 = (byte)InString[8] -48;
  ora = Temp1*10 + Temp2;
  // now Minute
  Temp1 = (byte)InString[9] -48;
  Temp2 = (byte)InString[10] -48;
  minuti = Temp1*10 + Temp2;
  // now Second
  Temp1 = (byte)InString[11] -48;
  Temp2 = (byte)InString[12] -48;
  secondi = Temp1*10 + Temp2;
}

///////////////////////////////////////////////////////
void set_datetime(){
    GetDateStuff(Year, Month, Date, DoW, oras, minutis, secondis);
    Clock.setClockMode(false);  // inposta 24h
    Clock.setYear(Year);
    Clock.setMonth(Month);
    Clock.setDate(Date);
    Clock.setDoW(DoW);
    Clock.setHour(oras);
    Clock.setMinute(minutis);
    Clock.setSecond(secondis);
    mins=0;
    gg=0;
}

manca un pezzo dell’array perchè non ci stava.

Decachi:
Ecco la parte del mino codice:

NON ci serve una parte ... ci serve TUTTO il codice, per vedere le dichiarazioni delle variabili ... te l'ho anche scritto nel mio post #1 ... ::slight_smile:

Guglielmo

grazie uwefed, ma quello che non capisco è perchè se il codice lo scrivo così:

//int m=(Clock.getMonth(Century));
//int g=(Clock.getDate());
int m=12;
int g=31;
 accH= orari[m][g][2];   
 accM= orari[m][g][3];
 speH= orari[m][g][0];
 speM= orari[m][g][1];

non mi da probemi.

>Decachi: ... ma li hai letti i miei post #1 e #4 ? ? ? :o :o :o

Stiamo aspettando TUTTO il codice per vedere come dichiari quelle benedette variabili !!!

Guglielmo

… scusa ma, forse errando ho corretto il mio post #3 inserendo tutto il codice. Ora lo allego anche come file. Spero che così vada bene.

Orologio_Crepuscolare2.ino (9.27 KB)

Allora, Arduino Nano momnta un ATmega328P che a sua volta ha 2KBytes (2048 bytes) di SRAM, ora ...
... solo questo tuo vettore:

byte orari[13][32][6] = ...

... occupa 13x32x6 = 2496 bytes!!!

Come pensi che possa funzionare su una MCU che ha in tutto 2KB ? ? ? :o

Guglielmo

P.S.: Se sono valori fissi, che cambi solo a livello di "codice", allora potresti pensare di spostare tutto ciò che è costante in PROGMEM :wink:

grazie gpb01, ho risolto utilizzando PROGMEM.

Decachi:
grazie gpb01, ho risolto utilizzando PROGMEM.

Magari lo hai già, ma ti allego un documento molto utile per un semplice utilizzo di PROGMEM … :wink:

Guglielmo

Progmem.pdf (182 KB)

byte orari[13][32][6]

ancora peggio di quello che vedevo.
Ciao Uwe