Arduino - Memoria dinamica esaurita

Ciao a tutti,

Ho un Arduino Uno in mano dal 2013 e credo sia arrivato finalmente il momento di chiedere agli esperti. Ho un progetto che misura temperatura ed umidità da un sensore DHT22, e ad ogni misurazione stampa su di un display OLED i relativi valori. In più utilizzo un RTC DS1302 per stampare sul display anche data e ora.

Fino a qui, il mio programma utlizza 1548 byte (75%) di memoria dinamica, lasciando altri 500 byte liberi per le variabili locali. (Questo è quanto l'IDE mi comunica).

Il passo successivo è aggiungere un metodo di scrittura dei due valori di umidità e temperatura su un file di testo, posizionato in una MicroSD che è inserita in un'ethernet shield. Il problema? Se inserisco il codice relativo alla SD lo spazio si esaurisce, nello specifico:

"Lo sketch usa 21870 byte (67%) dello spazio disponibile per i programmi. Il massimo è 32256 byte.
Le variabili globali usano 2205 byte (107%)[/color] di memoria dinamica, lasciando altri -157 byte liberi per le variabili locali."

Ho ridotto al minimo le variabili, usando CHAR anzichè STRING ed utilizzando la EEPROM per memorizzare i valori float. Questemodifiche mi hanno fatto guadagnare un buon 4% rispetto a prima, ma sotto il 107% non riesco a muovermi. Calcolate anche che ancora manca il metodo di inserimento dei valori sulla SD, per ora ho solo un metodo che inserisce nel file l'intestazione delle tre colonne.

Come posso fare a ridurre ancora di più lo spazio occupato?

Grazie in anticipo!

Logger2.ino (1.8 KB)

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

Purtroppo la vedo grigia ...
... ho avuto una necessità simile alla tua e ... ho dovuto cambiare board ed MCU; nella memoria del 328P non ci stai, sono solo 2KB di SRAM e tra il buffer dell'OLED la SD e quant'altro ... sfori.

Guglielmo

P.S.: io, in più, dovevo leggere anche messaggi che arrivavano sulla seriale, quindi anche il buffer per i dati in arrivo ::slight_smile:

Guglielmo,

Grazie per la risposta. E' un peccato ma immagino quindi di dover sacrificare l'OLED per mantenere quanto meno il salvataggio dei dati su SD, che è fondamentale rispetto alla loro visualizzazione.

Tengo comunque una lucina accesa, non si sa mai che trovi una soluzione nel sonno :smiley:

Grazie ancora,
Michele.

Intanto per l'OLED c'è Questa libreria che e' più parsimoniosa

brunello22:
Intanto per l'OLED c'è Questa libreria che e' più parsimoniosa

... ed io quella usavo ... ma comunque il buffer di quel display si porta via, se ben ricordo, 1K (128x64 pixel) :confused:

Guglielmo

La oled_i2c, a mio avviso la migliore in assoluto per i piccoli oled monocromatici, richiede comunque un buffer da 1 k, questo perché tutte le modifiche vengono prima fatte dentro questo e poi viene trasferito in toto nella ram del display aggiornando la videata.
Purtroppo tra oled e sd servono almeno 1536 byte di ram (1k + 512) per i rispettivi buffer, poi c'è la ram usata dallo stack e dal heap, come minimo altri 200 byte, e quella per le variabili, è un attimo sforare i 2k disponibili sul 328P.

Vi ringrazio per i consigli.

Ho appena finito di adattare il codice alla nuova libreria OLED che mi avete consigliato. E' un po' meno completa della precedente ma fa quel che deve, e sono arrivato a 1986 byte (96%) di memoria dinamica, lasciando altri 62 byte liberi per le variabili locali (includendo il metodo di inizializzazione della SD e del file di testo).

Spero di riuscire a strizzare per bene il metodo di salvataggio dei dati, magari arrivo a destinazione (probabili instabilità permettendo).

Vi aggiorno,
Michele.

miky158:
... e sono arrivato a 1986 byte (96%) di memoria dinamica, lasciando altri 62 byte liberi per le variabili locali (includendo il metodo di inizializzazione della SD e del file di testo).

Troppi pochi ... avrai crash inspiegabili e reset di Arduino altrettanto inspiegabili ...
... causati da "stack overflow" e quant'altro ::slight_smile:

Ti sconsiglio di far girare un'applicazione con quella poca memoria ... è del tutto inaffidabile e può bloccarsi in qualsiasi momento (... ci sono passato varie volte).

Guglielmo

Grazie Guglielmo,

Elimino quindi il display e mantengo le funzioni vitali della SD. Esperienza breve ma intensa quella dell'OLED :smiley:

Alla prossima,
Michele

miky158:
Elimino quindi il display e mantengo le funzioni vitali della SD. Esperienza breve ma intensa quella dell'OLED :smiley:

Oppure passi a qualche cosa con più memoria, es. Arduino Mega e ti diverti con tutto quello che vuoi :slight_smile:

Guglielmo

E come mi spiegate che MyTrackr usa contemporaneamente OLED, MicroSD e GPS (quindi seriale) su un 328?

(Ma siamo proprio borderline :D)

a) Mistero della fede :grin:
b) Libreria per Oled che usa pagine da 256 byte :slight_smile:
c) Utilizzo di dati compressi. :smiley:

Una delle tre risposte è quella corretta, indovinate quale.

c) dati compressi ? (ma anche un bel pò d'uso di PROGMEM!! )
Da dove esce questa sugli enum ???
// We want enums to only use 1 byte
#ifdef GNUC
#define PACKED attribute ((packed))
#else
#define PACKED
#endif

nid69ita:
Da dove esce questa sugli enum ???

... semplicemente dal manuale di gcc ... QUI, dopo aligned c'è packed :wink:

Guglielmo

Yep. Da qualche versione di GCC in poi, gli enum tengono sempre 2 byte, con conseguente inutile dispendio di RAM e flash. Con quell'attributo le puoi forzare a un singolo byte, che spesso è più che sufficiente. In alternativa si potrebbe usare il flag -fshort-enums.

Inoltre uso effettivamente u8glib per l'OLED, che usa un buffer più piccolo, e infine una libreria per SD semplificata che supporta solo FAT16. Niente SD > 2 GB dunque, ma è un prezzo accettabile per me.

della u8 lo sapevo, per la sd, la tinyfat ?

No, questa: GitHub - greiman/Fat16: Smaller FAT16 only library for Arduino.