memoria e chiamate a funzione

È possibile che molte chiamate a funzione, che fa delle cose tra cui dichiarare al suo interno variabili ed usarle, possa creare errori di memoria?
Ho una funzione, non chiamata ricorsivamente, che dichiara 2 long e un int e legge da termocoppia MAX6675 e scrive su display lcd.

Avevo creato un while che chiamava ciclicamente molte volte questa funzione per molti minuti e durante l'uso ho avuto dei malfunzionamenti casuali che non sono riuscito ancora ad isolare e riprodurre.

Ora ho ridotto le chiamate alla funzione spostando il while all'interno della funzione e sembra non essersi più riproposto il problema ma non ho un campione di prove sufficiente per esserne certo.

uso un nano e le variabili globali usano 725 byte (35%) di memoria dinamica.

Ho letto molti bei thread sulla questione memoria ma non ho capito cosa succeda alla memoria se e quando viene liberata mi sapete dare qualche info in più o vostre esperienze?

se le variabili vengono create dentro alla funzione, quando esci dalla stessa vengono eliminate e morta li, per lo meno per le numeriche, se crei delle variabili di tipo String, ho idea che qualche casino possano farlo lo stesso. Se le variabili sono create globali anche qui se sono numeriche o ci stanno oppure il compilatore ti avverte dicendoti appunto che hai esaurito la memoria. Se sono di tipo stringa pian piano ti saturano la memoria e ti provocano reset e malfunzionamenti vari.

senza sketch é una discussione teorica su possibili e mono possibili cause.
Ciao Uwe

Patrick_M:
se le variabili vengono create dentro alla funzione, quando esci dalla stessa vengono eliminate e morta li, per lo meno per le numeriche, se crei delle variabili di tipo String, ho idea che qualche casino possano farlo lo stesso. Se le variabili sono create globali anche qui se sono numeriche o ci stanno oppure il compilatore ti avverte dicendoti appunto che hai esaurito la memoria. Se sono di tipo stringa pian piano ti saturano la memoria e ti provocano reset e malfunzionamenti vari.

le string le uso globali ma non vengono modificate, solo lette quindi non dovrei aver problemi.
mi bastava capire se la memoria limitata rendesse il sistema suscettibile ad errori di questo tipo.
comunque credo ci siano altri problemi dovuti all'hardware, prima di tutto la cineseria, anche delle sonde.
Ieri mentre funzionava ho visto un lampo in cielo, un fulmine di quelli tra le nuvole e contemporaneamente
la temperatura ha oscillato fino al fondo scala negativo per poi tornare al valore corretto.
Davvero carino e inquietante.

uwefed:
senza sketch é una discussione teorica su possibili e mono possibili cause.
Ciao Uwe

Si solo che preferisco non sfidare il regolamento ed evitare di parlare di certe cose qui visto che non si può.
Comunque grazie.

Credo che il problema sia che ad ogni ciclo di loop scrivi i valori aggiornati sul display, giusto? Se è così è quello che porta blocchi non predicibili e comportamenti anomali.

si ovviamente i dati vengono aggiornati in tempo reale, temperatura e tempo (un countdown)
è un problema della libreria lcd o altro?

Se scrivi ad ogni ciclo di loop sull'lcd vai incontro a problemi tipo il tuo.
Per aggiornare i dati in tempo reale puoi usare la strategia d'aggiornare solo se necessario, sempre se i dati da visualizzare non cambiano troppo rapidamente (che ti porterebbe di nuovo alla tua siatuazione attuale).
Mettiamo per esempio che visualizzi due grandezze temperatura ed umidità e che memorizzi il valore attuale in

long tempAtt;
long humAtt;

per decidere se scrivere sull'lcd puoi creare due variabili che memorizzano il vecchio valore e fare un contronto tipo:

if(tempAtt!=oldTemp || humAtt!=oldHum)
{
   //Scrivo sull'lcd
   oldTemp = attTemp;
   oldHum = humAtt;
}

Ovvio che le variabili di backup deveno essere globali

Se comunque i tuoi valori oscillano con troppo frequenza allora oltre i controlli sopra citati dovrai aggiungere un controllo basato su millis() per aggiornare solo ogni tot millisecondi per non incappare nel problema

ti ringrazio. Purtroppo ho fatto un termostato con timer e quindi la temperatura e il tempo cambiano di continuo. Volendo potrei introdurre uno spegnimento display se servisse.
Ma il problema è la frequenza di aggiornamento, quindi un limite tecnico dei display, un overflow o cos'altro?
Se abbasso il refresh a 1 Hz cambia qualcosa? c'è una soglia o è cumulativo?

Si ma la temperatura mica varierà mille volte al secondo... il timer a che precisione è? un secondo suppongo, quindi si tratta di aggiornare il display una volta al secondo e non ad ogni ciclo di loop (che avviene svariate centinaia di volte al secondo).
Se così è con l'uso delle variabili dovresti risolvere, poi sta a te decidere se stai costruendo una cosa per cui se un utente non è informato che la temperatura è variata di un grado meno di un secondo fa è un problema o meno.
Per la mia esperienza è sempre bene andare ad aggiornare il display solo lo stretto necessario e solo per le parti necessarie, ovvero evitare lcd.clear() e riscrittura di tutto ma usare le funzioni per posizionare il cursore e sovrascrivere le sole parti interessate, ne guadagni in stabilità e velocità nonché in assenza di sfarfallii nel display. Certo è meno semplice...

La temperatura varia come può variare in un forno, posso ridurre la frequenza visualizzata, attualmente termocoppia + max richiedono comunque 200ms di delay per restituire un valore valido quindi credo che il refresh massimo sia 5 Hz, ovviamente viene scritto solo il valore che cambia.
Non so se possa essere già un valore sicuro. Ma questo bug è documentato? Non ne avevo mai sentito parlare.
lcd.clear() ci sono, ma solo in corrispondenza di cambi schermate, quindi niente dentro a loop.
L'unica cosa che potrebbe essere critica è una struct con String e due piccoli array di String ma tutti globali e in sola lettura.

String ahi ahi ahi ahiahiahiahi :slight_smile: come ti avranno già consigliato stai alla larga dalla classe String, visto che qui sono in sola lettura dovresti failmente riuscire a convertire il tutto in array di char, ma comnque qui il problema non sembrano essere loro.
Non è un bug documentato in quanto dipende anche molto dal display, dalle connessioni e dalla bontà dell'hardware quindi non c'è una formula che permetta di definire la frequenza critaca d'aggiornamento.
Se si tratta di un forno (e se non mi inganno il progetto è qualcosa che riveste ricette et simila di altro topic) aggiornare la temperatura così spesso è più (perdonami e passami il termine) "una sega mentale" che una reale necessità.
Anche se tu aggiornassi la temperatura ogni dieci secondi non noteresti una grande differenza nell'utilizzo, nei prodotti commerciali dubito si aggiorni più volte al minuto, anche se si trattasse di un forno reflow per saldatura, poi ripeto sta a te determinare quanto sia critico avere la temperatura ogni tot ms e quanto sia critico avere un hardware stabile che non rischi blocchi improvvisi dopo alcuni minuti/ore d'utilizzo a casaccio per aggiornamenti troppo frequenti e/o overflow di memoria per altri motivi (vedi uso di classi C++ con allocazione di memoria al volo)

Ho vari termometri digitali e sono tutti sul 1Hz come frequenza di aggiornamento della temperatura.
Non ho mai considerato fosse problema quindi non ho fatto caso a quante volte al secondo si aggiornava.
Proverò a ridurre il refresh con il solito giochetto del millis.
Si non ci si può aspettare miracoli da hardware che costa si e no 3€ spedito.
Mi bastava sapere cosa potesse generare errori e mi pare di avere una bella rosa di candidati.
Grazie

gianlucaf:
Ho vari termometri digitali e sono tutti sul 1Hz come frequenza di aggiornamento della temperatura.

Si non metto in dubbio quello, esistono anche sonde con tre/cinque punti di rilevazione con media automatica e frequenze d'aggiornamento pazzesche ma certo non le usano per verificare temperatura ambiente, forno o cose simili dove ci sono latenze tra calore emesso dall'elemento riscaldante e temperatura del vano riscaldato, quello intendevo

gianlucaf:
Si non ci si può aspettare miracoli da hardware che costa si e no 3€ spedito.

:slight_smile: si quello può incidere ma a volte anche strapagando il solito hardware su Amazon et simila non si va più di tanto lontano.

Ti auguru un buon debug e ottimizzazione :slight_smile:

secondo me ci sono troppi pochi elementi per cercare di capire cosa possa causare i tuoi problemi.
quale lcd usi? (oled, 16x2, spi, i2c???)
come hai impostato il codice? utilizzi millis() per le letture (non mi pare poiché parlavi di while)? e per aggiornare il display?
con un oled 0,96" i2c e libreria ridotta al minimo indispensabile il time refresh minimo che ho ottenuto è stato di 70 millis.. poco più di 10 hz con un avg di 6 hz... stesso lcd in spi è un'altra storia...

16x2 in i2c, uso millis per controllare tempi di esecuzione e pause varie.
uso i while nelle funzioni chiamate perchè trovo più intuitivo ragionare per sottoprogrammi.
Per aggiornare il display uso una funzione scrittura_dati(a,b) chiamata al bisogno che mi stampa temperature e tempo.

Questi giorni ho lavorato parecchio al codice, mi è capitato solo una volta un errore di visualizzazione sul display,
in pratica accade che il menù vada in crisi quando cerco di selezionare un elemento e scriva male, come se non eseguisse un clear o la riscrittura del display, cosa che normalmente esegue.
Dovrei cercare di riprodurre l'errore solo che mi capita sempre quando sto facendo mille altre cose e non faccio caso a cosa ho fatto.

gianlucaf:
L'unica cosa che potrebbe essere critica è una struct con String e due piccoli array di String ma tutti globali e in sola lettura.

Ma scusa, la "comodità" della String è quella di poter manipolare le stringhe in modo più "comodo" (al costo di piantamenti del sistema, ma questa è "solo" una conseguenza..), se ti bastano costanti a che ti serve farle String?

Intanto prova a sostituirle con array di char, poi vediamo. Ma almeno parte del codice devi farcelo vedere, altrimenti qui stiamo solo "miagolando nel buio" (cit. Guzzanti-Quelo).