Simboli strani sul display

Sta succedendo che la RAM è pulita all'avvio ma nella RAM le variabili vengono continuamente create e distrutte, inoltre ogni stringa che deve essere stampata sul display viene letta dalla Flash e poi caricata in Ram, da cui viene poi elaborata.
Infine, nella Ram vive lo stack, dove vengono memorizzate tutti i punti di rientro di salti a subroutine.
Tenendo conto che di Ram l'Atmega ne ha 2 kB, si fa presto ad esaurirla.

Ti consiglio questa lettura:
http://www.leonardomiliani.com/?p=572

ed inoltre l'utilizzo della funzione F() per salvare direttamente su Flash tutti i messaggi testuali del tuo sketch.
Esempio:
lcd.print("TEMPERATURA: ");
diventa
lcd.print(F("TEMPERATURA: "));

ok...adesso mi metto all'opera..ma perchè l'errore non sussiste con il potenziometro?

Innanzi tutto leo72 grazie per la risposta....
Ho seguito la tua guida utilizzando l'avr-size e quello che mi restituisce sullo sketch del mio programma è questo:

Device: Unknown

Program: 18710 bytes
(.text + .data + .bootloader)

Data: 815 bytes
(.data + .bss + .noinit)

hermit274:
ok...adesso mi metto all'opera..ma perchè l'errore non sussiste con il potenziometro?

Non so. Dovresti studiarti il codice e vedere se ci sono possibili punti deboli. Ad esempio un array che va fuori indice. Delle conversioni ecc.. non so.

ho delle domande sulla funzione F() (a proposito ma nel Reference dove devo cercarla questa funzione)

  1. quando si usa la F() per memorizzare una stringa testuale, la stringa per essere visualizzata non deve cmq passare per la ram ?

  2. la si puo' usare anche per memorizzare una variabile, tipo la misura di un sensore ? (Credo cmq che non avrebbe senso farlo)

  1. No, è fatto apposta per evitare di consumare RAM.

  2. No, non è applicabile alle variabili.

Della funzione F() ne parla qui --> Serial.print() - Arduino Reference

You can pass flash-memory based strings to Serial.print() by wrapping them with F(). For example :
Serial.print(F(“Hello World”))

grazie, e progmem invece ? e' un suo concorrente o serve ad altro ?

quando ho scritto deve passare per la ram, intendo un passaggio in sottfondo, non so come spiegarmi, cioe' la cpu per poter stampare il dato non e' obbligata a ricevere il flusso dei dati attraverso la ram ? credo abbia a che fare con le architetture delle cpu, invece di studiarmelo chiedo e faccio prima :slight_smile:

Testato:
grazie, e progmem invece ? e' un suo concorrente o serve ad altro ?

progmem è un alias dell'attributo ATTR_PROGMEM definito nelle librerie avr che servono ad istruire il compilatore a trattare i dati seguenti dalla Flash:
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

La funzione F() altro non è che un altro alias che inserisce questo codice:

#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

Rilevata la parola chiave __FlashStringHelper, la libreria Print.h recupera i dati della stringa in byte alla volta dalla memoria Flash

size_t Print::print(const __FlashStringHelper *ifsh)
{
  const char PROGMEM *p = (const char PROGMEM *)ifsh;
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    n += write(c);
  }
  return n;
}

quando ho scritto deve passare per la ram, intendo un passaggio in sottfondo, non so come spiegarmi, cioe' la cpu per poter stampare il dato non e' obbligata a ricevere il flusso dei dati attraverso la ram ? credo abbia a che fare con le architetture delle cpu, invece di studiarmelo chiedo e faccio prima :slight_smile:

Normalmente in un'architettura Harvard i dati vengono sempre caricati in Ram e poi da lì trattati.
Ovviamente un microcontrollore è capace anche, con determinati comandi, di gestire dei dati dalla Flash. E' ciò che aiuta a fare PROGMEM, grazie al quale il compilatore viene istruito affinché carichi i dati non in Ram prima di passarli nei registri ma direttamente in essi.

grazie ora e' tutto piu' chiaro
ultima cosa, quindi sia progmem che f() sono strumenti per caricare dei dati senza passare dalla ram, ma ad oggi, con le release attuali dell'ide, la f() ha sostituito completamente il comando progmem, oppure ci sono casi in cui e' meglio usare l'uno e non l'altro ? (si capisce che non ho colto granche' dal codice allegato ? :grin:)

Testato:
grazie ora e' tutto piu' chiaro
ultima cosa, quindi sia progmem che f() sono strumenti per caricare dei dati senza passare dalla ram, ma ad oggi, con le release attuali dell'ide, la f() ha sostituito completamente il comando progmem, oppure ci sono casi in cui e' meglio usare l'uno e non l'altro ? (si capisce che non ho colto granche' dal codice allegato ? :grin:)

Partiamo da un concetto. In Flash con PROGMEM puoi gestire SOLO costanti. Dati fissi che non cambiano durante l'esecuzione del programma perché in Flash non puoi scriverci (non è del tutto vero, però prendi per buona quest'affermazione relativamente al discorso che stiamo facendo).
Ora, F() serve solo per gestire stringhe, che in C sono costanti. Difatti una stringa è un array di char, un tipo di dati non modificabile.
Se devi usare altri tipi di dato, allora devi usare PROGMEM.

Attento che il problema non è tanto dire al compilatore di lasciare un dato in Flash, quanto quello di farglielo recuperare, quel dato. :wink:

karma+1
thanks :slight_smile:

Ciao Ragazzi!
Sono ancora alle prese con il progetto sopra indicato. Dai consigli di leo72, ho fatto tutto ciò che mi ha detto cercando di alleggerire il codice e liberare quanta più ram possibile.
Per sapere quanta ram mi rimane libera durante l'esecuzione del programma, ho utilizzato la funzione freeRam() presente nella sua guida al link che lui ha indicato.
Durante l'esecuzione del programma, sto facendo stampare sul display LCD la memoria libera e mi visualizza costantemente 1579byte liberi.
Il bello è che dopo un oretta che arduino è acceso, i simboli strani sul monitor si presentano di nuovo...
uffaaaaa!!!come mai?non ci sto capendo più niente

nessuno ha un consiglio?

Controlla i collegamenti e creati un secondo sketch col minimo indispensabile per il funzionamento del display.
Se è tutto a posto allora il problema è nel codice corrente.

1579 libero vuol dire che ne stai consumando veramente poca, il tuo problema deve essere di carattere hardware.
prova semplicemente a tenere in stampa hello world e vedi cosa fa.

Oppure che lo sketch riempie col tempo la RAM (stack e/o heap che saturano la memoria). Il fatto che prima il problema compariva quasi subito ed ora, a RAM sgombra, compaia in ritardo (perché ci mette di più a consumare tutta la RAM) fa pensare anche a questo.

Ciao ragazzi, scusate il ritardo, ma questi giorni sto costantemente testando Arduino con il monitor acceso e sta continuando a dare problemi.
L'unico modo in cui non da problemi è quando faccio stampare sul monitor delle stringhe del tipo

P1 (memorialibera)
H20: (temperatura) T-c: (temperatura)

In questo modo non da assolutamente problemi. Se gli faccio stampare una cosa del tipo

Programma 1
H20: (temperatura) T-c (temperatura)

Dopo qualche ora inizia a sbiellare.
Per stampare sul monitor sto usando le funzioni lcd.print(F("Programma 1"))....secondo voi quale è il problema?E' possibile che è un problema hardware? vi dico già da adesso che tutti i cavi sono saldati sul monitor, quindi non ci sono falsi contatti o cose del genere....

Se alleghi lo sketch ad un post forse è meglio, qualcuno può dargli un'occhiata.

Questo non è lo sketch completo, è solo dal loop() in giù. Manca tutto quello che c'è sopra (setup, define, inclusione di lib e var globali).

Comunque vedo una marea di chiamate a funzioni varie. Ogni chiamata a funzione incrementa lo stack. Se l'errore viene fuori dopo un po' è probabile che la Ram pian piano si saturi.

Potresti provare con un altro modo. Ogni 10 minuti prova a stampare a video il valore della RAM libera, per vedere se questa si satura nel tempo oppure no. Se non si satura allora ci può essere un errore logico (ad esempio un indice che esce da un array).

Non compila. Mancano le funzioni carica_programma() e accensioneBottone()