Pages: [1] 2 3 ... 5   Go Down
Author Topic: Simboli strani sul display  (Read 5439 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao ragazzi!innanzi tutto Buon Natale a tutti!
Volevo chiedere un consiglio agli esperti di questo forum. Da qualche giorno mi sono imbattuto in un problema strano!
Sto usando un termistore per rilevare la temperatura dell'acqua dei miei termosifoni e in base alla temperatura rilevata, viene visualizzato un programma sul mio display LCD.
Esempio
0 -40°C --->Programma1
40-50°C ---> Programma2
.
.
.
fino a qui tutto bene, funziona tutto e viene tutto visualizzato sul display per una mezzoretta circa, dopo di che appaiono dei simboli tipo questi:


sapreste aiutarmi?vi posto anche il codice che ho creato per stampare su monitor:

Code:
void stampalcd(int valore_programma, int t_acqua, int t_sonda, int errore){

  if(errore ==0){
    if(t_sonda_precedente != t_sonda || t_acqua_precedente!= t_acqua || programma_precedente != valore_programma)
    {
      lcd.clear();
      lcd.setCursor(0,0);

      if (valore_programma == 1){
        lcd.print("Load Wood");
      }
      if (valore_programma == 2){
        lcd.print("Programma 1");
      }
      if (valore_programma == 3){
        lcd.print("Programma 2");
      }
      if (valore_programma == 4){
        lcd.print("Programma 3");
      }
      if (valore_programma == 5){
        lcd.print("Programma 4");
      }

      lcd.setCursor(0,1);
      lcd.print("H20:");
      lcd.print(t_acqua);
      lcd.print(" / ");
      lcd.print("T-c");
      lcd.print(t_sonda);
      t_sonda_precedente = t_sonda;
      t_acqua_precedente = t_acqua;
      programma_precedente = valore_programma;
    }
  }
  else
  {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Errore!");
  }
}
non so proprio più che pesci prendere.
« Last Edit: January 09, 2013, 02:11:40 pm by hermit274 » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22938
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi sembra un classico caso di saturazione della memoria Ram.
Lo sketch che stai usando è molto grande o include molte librerie o fa uso di tante variabili testuali?
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, in effetti lo sketch è molto grande e poi uso 4 librerie. Come variabili testuali uso soltanto una variabile di tipo string
« Last Edit: December 26, 2012, 05:32:10 am by hermit274 » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

comunque mi sembra strano. Perchè per accendere e spegnere il sistema ho un pulsante.
Quando spengo il sistema riazzero tutte le variabili, che penso sia utile a svuotare la ram.
Il problema adesso sono due:
- quando si presenta questo problema, anche quando schiaccio il pulsante per spegnere il sistema, al riavvio il problema si presenta fin dall'inizio. Per ripristinare tutto devo per forza utilizzare il tasto di reset.
- provando qualunque cosa, adesso ho tolto il termistore e a posto di questo ho messo un semplice potenziometro che utilizzo per far variare, in modo manuale, la temperatura.
Il sistema è acceso da circa un ora e non fa una piega...

cosa sta succedendo?! smiley-eek
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22938
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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: "));
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22938
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5959
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7183
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

2. No, non è applicabile alle variabili.

Della funzione F() ne parla qui --> http://arduino.cc/en/Serial/Print
Quote
You can pass flash-memory based strings to Serial.print() by wrapping them with F(). For example :
Serial.print(F(“Hello World”))
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5959
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22938
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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
Code:
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;
}

Quote
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 smiley
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.
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5959
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?  smiley-mr-green)
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22938
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?  smiley-mr-green)
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.
http://arduino.cc/en/Reference/PROGMEM

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


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5959
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

karma+1
thanks  smiley
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Pages: [1] 2 3 ... 5   Go Up
Jump to: