Arduino Forum

International => Italiano => Software => Topic started by: essere_digitale on Sep 08, 2012, 11:57 pm

Title: Strano freeze del loop
Post by: essere_digitale on Sep 08, 2012, 11:57 pm
Salve,
ho collegato un sensore SRF02 alla mia Leonardo per misurare l'altezza d'acqua in una vasca e pubblico il risultato usando una risposta http, di seguito il codice:

Code: [Select]

// librerie usate nel progetto
#include "SPI.h"             
#include "Wire.h"             
#include "SRF02.h"
#include <Ethernet.h>
// costanti che contengono il mac e l'IP della scheda di rete
byte mac[] = { 0x90, 0xA2, 0x__, 0x__, 0x__, 0x__ };
byte ip[] = { 192,168,1,50 };

// inizializzazione componente SRF con l'indirizzo 0x70
SRF02 sensor(0x70, SRF02_CENTIMETERS);
float larghezza_cisterna = 2;
float lunghezza_cisterna = 2;
float altezza_cisterna = 1.3;
float livello_acqua = 0;
float delta_sensore_galleggiante = 13;
const float capienza_metricubi = larghezza_cisterna * lunghezza_cisterna * altezza_cisterna;
const float capienza_litri = capienza_metricubi * 1000;
float disponibilita_metricubi = 0;
float disponibilita_litri = 0;
float livello_attenzione = 2000;
float livello_allerta = 1200;
float livello_allarme = 700;
bool attenzione = false;
bool allerta = false;
bool allarme = false;
String colore = "white";
unsigned long nextPrint = 0;

int led = 12;

//creo una variabile char per memorizzare i byte letti dal client
char Data_RX;
String msg = "";
int cmd = 0;
int real_level = 0;
int thelevel = 0;
String thelevel_txt;
float thelevel_flt;
//creo un oggetto server che rimane in ascolto sulla porta
//specificata
EthernetServer ArduinoServer(80);

void setup()
{
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  Serial.begin(9600);
  Wire.begin();
  sensor.setInterval(500);
  //inizializza lo shield con il mac e l'ip
  Serial.println("Ethernet initialization ...");
  Ethernet.begin(mac, ip);
  String secs_txt;
  for(int i = 1; i < 6; i++){
    secs_txt = String(30 - i * 5);
    Serial.println("Ethernet ready in " + secs_txt + " sec.");
    digitalWrite(led, HIGH);
    delay(100);
    digitalWrite(led, LOW);
    delay(4900);
  };
  Serial.println("Ethernet ready");
  //inizializza l'oggetto server
  ArduinoServer.begin();
  Serial.println("Webserver ready");
  sensor.update();
  Serial.println("SRF ready");

  // stato di fine setup e inizio loop
  for(int j = 0; j < 5; j++){
    digitalWrite(led, HIGH);
    delay(250);           
    digitalWrite(led, LOW);
delay(250);
  };
}

void loop()
{
  //IMPORTANTE pulisco la variabile msg
  msg = "";
  //Ascolto le richieste dei client controllo se ci sono dati da leggere
  //e creo un oggetto relativo a client che sta interrogando l'Ethernet shield
  EthernetClient pc_client = ArduinoServer.available();
  //controllo se pc_client è diverso da false
  if (pc_client != false)
  {
    digitalWrite(led, HIGH);
    //controllo se il client è connesso
    while (pc_client.connected())
    {
      //leggo i byte disponibili
      //provenienti dal client
      Data_RX = pc_client.read();
      //invio i dati letti al Serial Monitor
      Serial.write(Data_RX);
      //Attendo che tutti i byte siano letti
      //quando Data_RX contiene il carattere
      //di nuova line capisco tutti i byte sono
      //stati letti
      msg += Data_RX;
      if (Data_RX == '\n')
      {
        Serial.println("richiesta http completata");
        //Invio la risposta al client
        //invio lo status code
        pc_client.println("HTTP/1.1 200 OK");
        //imposto il data type
        pc_client.println("Content-Type: text/html");
        pc_client.println();
        //invio codice html
        pc_client.println("<html>");
        pc_client.println("<head>");
        pc_client.println("<title>Water level</title>");
        pc_client.println("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">");
        pc_client.println("<META HTTP-EQUIV=\"PRAGMA\" CONTENT=\"NO-CACHE\">");
        pc_client.println("</head>");
        pc_client.println("<body bgcolor=\"black\" text=\"white\" link=\"lime\" vlink=\"lime\">");
        pc_client.println("<div align=\"center\" style=\"font-family:tahoma,verdana,arial;font-size:18px;font-style:italic\">");
        // chiedo il valore all'SRF
        Serial.println("before sensor.update");
        sensor.update();
        Serial.println("after sensor.update");
        if (millis() > nextPrint)
        {
          Serial.println("before sensor.read");
          real_level = sensor.read();
          thelevel = real_level;
          thelevel = thelevel - delta_sensore_galleggiante;
          thelevel_txt =  String(thelevel, DEC);
          thelevel_flt = (float) thelevel / 100;
          livello_acqua = altezza_cisterna - thelevel_flt;
          disponibilita_metricubi = livello_acqua  * lunghezza_cisterna * larghezza_cisterna;
          disponibilita_litri = disponibilita_metricubi * 1000;
          Serial.print("disponibilita = ");
          Serial.println(disponibilita_litri);
          colore = "white";
          if (disponibilita_litri <= livello_attenzione) {
            attenzione = true;
            colore = "yellow";
            Serial.println("stato attenzione");
          };     
          if (disponibilita_litri <= livello_allerta) {
            attenzione = false;
            allerta = true;
            colore = "orange";
            Serial.println("stato allerta");
          };     
          if (disponibilita_litri <= livello_allarme) {
            attenzione = false;
            allerta = false;
            allarme = true;
            colore = "red";
            Serial.println("stato allarme");
          };     
          Serial.println("stato attenzione");
          Serial.println("after sensor.read");
          Serial.println("livello = " + thelevel_txt);
          nextPrint = millis () + 1000;
        };
        pc_client.print("valore al sensore ");
        pc_client.print(real_level);
        pc_client.println("<br>");
        pc_client.println("valore per i calcoli ");
        pc_client.println(thelevel_flt);
        pc_client.println("</div><br><br><br><br><br>");
        pc_client.println("<div align=\"center\" style=\"font-family:tahoma,verdana,arial;font-size:72px\">");
        pc_client.println(disponibilita_metricubi);
        pc_client.println("m<sup>3</sup> di ");
        pc_client.println(capienza_metricubi);
        pc_client.println("m<sup>3</sup>");

        pc_client.println("</div>");
        pc_client.println("<div align=\"center\" style=\"color:" + colore + ";font-family:tahoma,verdana,arial;font-size:72px\">");
        pc_client.println(disponibilita_litri);
        pc_client.println(" di ");
        pc_client.println(capienza_litri);
        pc_client.println("litri");
        pc_client.println("</div>");
        pc_client.println("</body>");
        pc_client.println("</html>");
        //aspetto 10 ms affinche la risposta giunga al browser del client
        delay(10);
        //esco dal ciclo while una volta completato l'invio della risposta
        break;
      }
      //chiudo la connessione
    }
    pc_client.stop();
    pc_client = false;
    msg = "";
delay(7500);
    digitalWrite(led, LOW);
  } else {
    digitalWrite(led, HIGH);
    delay(80);           
    digitalWrite(led, LOW);
    delay(80);           
    digitalWrite(led, HIGH);
    delay(80);           
    digitalWrite(led, LOW);
    delay(80);           
    digitalWrite(led, HIGH);
    delay(80);           
    digitalWrite(led, LOW);
    delay(250);
  };
}



metto un pò di lampeggi del led per vedere cosa succede anche quando non ho l'IDE collegato.

Il problema sorge a random almeno 30 minuti dopo l'avvio: il led non lampeggia più, se effettuo una richiesta al webserver non ho alcuna risposta, ma se lancio un ping, la scheda mi risponde.
Infine, con la scheda in questo stato, se provo ad uploadare uno sketch, l'IDE resta su upload binary (o qualcosa del genere, adesso non ricordo).

Quale potrebbe essere il problema?
Grazie
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 09, 2012, 08:50 am
La risposta al ping credo sia data dall'altra scheda, non dalla Leonardo, giusto? (non conosco le schede Ethernet).
Quando la scheda si blocca, hai altri LED accesi, oltre a quello ON?
Hai provato ad usare la funzione F() per leggere le stringhe direttamente dalla Flash? Potrebbe essere un problema di RAM saturata.
Title: Re: Strano freeze del loop
Post by: cyberhs on Sep 09, 2012, 01:47 pm
Quasi certamente ha ragione Leo, il tuo problema è la variabile stringa msg (e forse anche le altre variabili stringa).

Correttamente ad ogni ciclo la resetti, ma il problema è la sua lunghezza variabile: se supera una certa dimensione, alloca altro spazio nella HEAP e dopo alcuni cicli saturi la memoria.

Di solito risolvo il problema inizializzando in setup la stringa non con una stringa vuota, ma con una "piena" (tipo msg = "123456789012345") in modo da allocare sufficiente spazio in memoria.

Ettore Massimo Albani

Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 12, 2012, 11:50 pm
provo e vi faccio sapere, grazie
Title: Re: Strano freeze del loop
Post by: superp on Sep 13, 2012, 01:21 am
Secondo me se eviti di stampare tutti sti messaggi di debug, il loop non si freeza. Tutto quello che passi a serial. Printl e client.println va in RAM che, grazie anche a msg, tende a saturarsi. Se ti rimane spazio in flash e non vuoi eliminare i messaggi di debug, prova come dice Leo a mandare tutte le stringhe in flash con PROGMEM o,  se ide>1.0, utilizzando la funzione F().  qua (http://arduino.cc/playground/Main/Printf) dice:
Quote
Version 1.0 of the Arduino IDE introduced the F() syntax for storing strings in flash memory rather than RAM. e.g.
Serial.println(F("This string will be stored in flash memory"));

N.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 13, 2012, 08:35 am
Ok, qualche esempio sull'uso di F(), dove lo trovo?
Title: Re: Strano freeze del loop
Post by: PaoloP on Sep 13, 2012, 09:59 am

Ok, qualche esempio sull'uso di F(), dove lo trovo?

E' semplice.
Ad esempio una parte del tuo codice
Code: [Select]
pc_client.println("<html>");
pc_client.println("<head>");
pc_client.println("<title>Water level</title>");
pc_client.println("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">");

con la funzione F() diventa
Code: [Select]
pc_client.println(F("<html>"));
pc_client.println(F("<head>"));
pc_client.println(F("<title>Water level</title>"));
pc_client.println(F("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">"));


Applicalo a tutti i print, pc_client e serial, e sei a posto.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 13, 2012, 10:44 pm

Quasi certamente ha ragione Leo, il tuo problema è la variabile stringa msg (e forse anche le altre variabili stringa).

Correttamente ad ogni ciclo la resetti, ma il problema è la sua lunghezza variabile: se supera una certa dimensione, alloca altro spazio nella HEAP e dopo alcuni cicli saturi la memoria.

Di solito risolvo il problema inizializzando in setup la stringa non con una stringa vuota, ma con una "piena" (tipo msg = "123456789012345") in modo da allocare sufficiente spazio in memoria.

Ettore Massimo Albani




con questa soluzione gira da più di 24 ore senza freeze ...
grazie

adesso provo con F(), che mi pare la soluzione migliore, in vista di arricchire le risposte web ...
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 13, 2012, 11:43 pm


Ok, qualche esempio sull'uso di F(), dove lo trovo?

E' semplice.
Ad esempio una parte del tuo codice
Code: [Select]
pc_client.println("<html>");
pc_client.println("<head>");
pc_client.println("<title>Water level</title>");
pc_client.println("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">");

con la funzione F() diventa
Code: [Select]
pc_client.println(F("<html>"));
pc_client.println(F("<head>"));
pc_client.println(F("<title>Water level</title>"));
pc_client.println(F("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">"));


Applicalo a tutti i print, pc_client e serial, e sei a posto.


mi torna questo errore "initializer fails to determine size of '__c'"
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 14, 2012, 12:15 am
Forse la libreria che usi tu non supporta la funzione F().
La funzione F() è stata aggiunta a partire dall'ultima versione dell'IDE ed è inclusa in Print.h, che a sua volta viene invocata dalla libreria Stream.h, usata come base per gli oggetti Serial e LiquidCrystal.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 14, 2012, 12:21 am

Forse la libreria che usi tu non supporta la funzione F().
La funzione F() è stata aggiunta a partire dall'ultima versione dell'IDE ed è inclusa in Print.h, che a sua volta viene invocata dalla libreria Stream.h, usata come base per gli oggetti Serial e LiquidCrystal.


la versione dell'IDE è la 1.0.1 e ho provato ad includere anche Print.h o Stream.h, ma niente.
Altri suggerimenti?
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 14, 2012, 12:31 am
Non basta includerla tu, deve essere il codice scritto per poterla usare.
L'altro suggerimento è modificare il codice della lib oppure riscrivere il tuo inserendo il supporto alle stringhe in Flash con ProgMem.
Title: Re: Strano freeze del loop
Post by: cyberhs on Sep 14, 2012, 12:32 am
E' evidente che la libreria che usi per inviare comandi HTML non supporta la funzione F().

Puoi risparmiare spazio, invece, usandola con tutte le istruzioni Serial.print.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 15, 2012, 03:30 pm

E' evidente che la libreria che usi per inviare comandi HTML non supporta la funzione F().

Puoi risparmiare spazio, invece, usandola con tutte le istruzioni Serial.print.


L'errore "initializer fails to determine size of '__c'" mi viene tornato quando nel Serial.println o pc_client.println c'è una variabile, ad esempio:
Serial.println(F("Ciao")); // non da errore
Serial.println(F(nome_variabile_di_tipo_testo)); // da errore

qual'è il corretto utilizzo di F()?
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 15, 2012, 03:53 pm
Ma "nome_variabile_di_tipo_testo" di che tipo è?
F() dovrebbe lavorare con i tipi String.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 15, 2012, 04:08 pm

Ma "nome_variabile_di_tipo_testo" di che tipo è?
F() dovrebbe lavorare con i tipi String.


nel mio codice
Code: [Select]

String secs_txt;
  for(int i = 1; i < 6; i++){
    secs_txt = String(30 - i * 5);
    Serial.println(F("Ethernet ready in " + secs_txt + " sec.")); // ERRORE
    digitalWrite(led, HIGH);
    delay(100);
    digitalWrite(led, LOW);
    delay(4900);
  };
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 15, 2012, 08:27 pm
Ho dato un'occhiata meglio al core e la funzione F() vedo che è un define per prendere direttamente una stringa. Non essendo una funzione, non accetta parametri in forma di variabili.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 15, 2012, 11:59 pm

Ho dato un'occhiata meglio al core e la funzione F() vedo che è un define per prendere direttamente una stringa. Non essendo una funzione, non accetta parametri in forma di variabili.


Possibili workaround?
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 16, 2012, 12:09 am
Mettilo solo nelle parti di codice dove hai stringhe definite, ad esempio "<html>" o "<head>". Per il resto prova ad usare PROGMEM.
http://www.arduino.cc/en/Reference/PROGMEM
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 17, 2012, 11:36 pm

Mettilo solo nelle parti di codice dove hai stringhe definite, ad esempio "<html>" o "<head>".


già fatto, ma freeza ancora


Per il resto prova ad usare PROGMEM.
http://www.arduino.cc/en/Reference/PROGMEM



ho provato e anche solo nella dichiarazione di msg, ma mi da questo errore: error: "__c causes a section type conflict"
quindi, invece di
String msg = "";
ho scritto
PROGMEM String msg = "";

Non c'è un modo di debugare l'esecuzione dello sketch e vedere se la scheda freezata fa qualcosa?
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 17, 2012, 11:47 pm
Conferma del freeze:
con la scheda che non emette alcun lampeggio del led, ho provato a mandare lo sketch con alcune modifiche e mi dice che la porta è già occupata da un altro processo.

Se disabilito l'uso della seriale (che mi serve solo per debug), credete che risolverei il problema?
Grazie
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 18, 2012, 12:15 am
Risparmi un po' di RAM (elimini il buffer seriale che sono 64 byte più le variabili della libreria).
Prova ma non so se risolvi.

PS:
hai provato a controllare con avr-size l'occupazione di memoria del tuo sketch?
http://arduino.cc/forum/index.php/topic,121319.msg913287.html#msg913287
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 27, 2012, 12:52 am

Risparmi un po' di RAM (elimini il buffer seriale che sono 64 byte più le variabili della libreria).
Prova ma non so se risolvi.

PS:
hai provato a controllare con avr-size l'occupazione di memoria del tuo sketch?
http://arduino.cc/forum/index.php/topic,121319.msg913287.html#msg913287


ok, vorrei provare: è possibile impostare delle direttive al compilatore che mi permettano di non fargli vedere del codice?
Esempio:
<direttiva1 on>

<if direttiva1>
codice processato dal compilatore
<endif direttiva1>

oppure

<direttiva1 off>

<if direttiva1>
codice ignorato dal compilatore
<endif direttiva1>

vorrei usarlo per toglire tutti i riferimenti alla seriale, visto che mi serve solo per debug.

Grazie
Title: Re: Strano freeze del loop
Post by: superp on Sep 27, 2012, 01:04 am


Risparmi un po' di RAM (elimini il buffer seriale che sono 64 byte più le variabili della libreria).
Prova ma non so se risolvi.

PS:
hai provato a controllare con avr-size l'occupazione di memoria del tuo sketch?
http://arduino.cc/forum/index.php/topic,121319.msg913287.html#msg913287


ok, vorrei provare: è possibile impostare delle direttive al compilatore che mi permettano di non fargli vedere del codice?
Esempio:
<direttiva1 on>

<if direttiva1>
codice processato dal compilatore
<endif direttiva1>

oppure

<direttiva1 off>

<if direttiva1>
codice ignorato dal compilatore
<endif direttiva1>

vorrei usarlo per toglire tutti i riferimenti alla seriale, visto che mi serve solo per debug.

Grazie

Ciao, questa discussione credo faccia al caso tuo
http://arduino.cc/forum/index.php/topic,110922.15.html
N.
Title: Re: Strano freeze del loop
Post by: marcello.romani on Sep 27, 2012, 01:27 pm
Spannometricamente direi che F() mette delle costanti stringa in progmem, quindi mi sembra del tutto normale che usando una variabile (di qualunque tipo) si generi un errore.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 30, 2012, 09:16 am

Spannometricamente direi che F() mette delle costanti stringa in progmem, quindi mi sembra del tutto normale che usando una variabile (di qualunque tipo) si generi un errore.


scusa ma non ho capito cosa intendi
Title: Re: Strano freeze del loop
Post by: leo72 on Sep 30, 2012, 09:58 am
F() è una funzione aggiuntiva del metodo .print introdotta con l'ultima versione dell'IDE di Arduino che permette di gestire le stringhe in memoria Flash. Però non puoi fare la conversione da un tipo di dato a stringa in Flash, ottieni errore. E' ciò che ti abbiamo già detto: non va bene fare print(F(mario + " pippo")), puoi fare print(F("pippo")) e basta
Title: Re: Strano freeze del loop
Post by: marcello.romani on Sep 30, 2012, 11:41 am


Spannometricamente direi che F() mette delle costanti stringa in progmem, quindi mi sembra del tutto normale che usando una variabile (di qualunque tipo) si generi un errore.


scusa ma non ho capito cosa intendi


Se solo trovassi la pagina di documentazione relativa ad F()...  :smiley-roll-sweat:
Title: Re: Strano freeze del loop
Post by: essere_digitale on Sep 30, 2012, 01:18 pm

F() è una funzione aggiuntiva del metodo .print introdotta con l'ultima versione dell'IDE di Arduino che permette di gestire le stringhe in memoria Flash. Però non puoi fare la conversione da un tipo di dato a stringa in Flash, ottieni errore. E' ciò che ti abbiamo già detto: non va bene fare print(F(mario + " pippo")), puoi fare print(F("pippo")) e basta


Adesso é più chiaro. Scusate.
Quanto prima voglio usare un #define per togliere Serial dal codice di produzione e vedere se risolvo.
Mi chiedo, la Leonardo potrebbe essere guasta?
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 04, 2012, 11:03 pm


F() è una funzione aggiuntiva del metodo .print introdotta con l'ultima versione dell'IDE di Arduino che permette di gestire le stringhe in memoria Flash. Però non puoi fare la conversione da un tipo di dato a stringa in Flash, ottieni errore. E' ciò che ti abbiamo già detto: non va bene fare print(F(mario + " pippo")), puoi fare print(F("pippo")) e basta


Adesso é più chiaro. Scusate.
Quanto prima voglio usare un #define per togliere Serial dal codice di produzione e vedere se risolvo.
Mi chiedo, la Leonardo potrebbe essere guasta?



impostato il #define che mi toglie completamente la seriale, ma niente, dopo un pò si blocca sempre.
Potrebbe essere guasta la Leonardo?
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 04, 2012, 11:57 pm
Scusa, ma se dipendesse dalla Ethernet? Molte vecchie Ethernet Shield andavano in blocco, se non ricordo male. Non potrebbe dipendere dalla quella scheda? L'hai provata su un altro Arduino?
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 05, 2012, 12:00 am

Scusa, ma se dipendesse dalla Ethernet? Molte vecchie Ethernet Shield andavano in blocco, se non ricordo male. Non potrebbe dipendere dalla quella scheda? L'hai provata su un altro Arduino?


credo sia l'ultima versione della Ethernet Shield ... ma posso provare perchè ne ho un'altra.
Adesso la monto e provo.
Grazie
Title: Re: Strano freeze del loop
Post by: pablos71 on Oct 05, 2012, 12:06 am
Scusa usi un serial.write, hai qualche dispositivo collegato alla seriale?
poi sempre sulla seriale visualizzi il debug che utilizzano in ambo i casi pin 0 e 1, mi sfugge qualcosa? 
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 05, 2012, 12:21 am


Scusa, ma se dipendesse dalla Ethernet? Molte vecchie Ethernet Shield andavano in blocco, se non ricordo male. Non potrebbe dipendere dalla quella scheda? L'hai provata su un altro Arduino?


credo sia l'ultima versione della Ethernet Shield ... ma posso provare perchè ne ho un'altra.
Adesso la monto e provo.
Grazie


montata ... vediamo se supera la notte!
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 05, 2012, 12:39 am

Scusa usi un serial.write, hai qualche dispositivo collegato alla seriale?


si, il serial monitor dell'IDE!



poi sempre sulla seriale visualizzi il debug che utilizzano in ambo i casi pin 0 e 1, mi sfugge qualcosa? 


non proprio: creo una direttiva al compilatore con #DEFINE DEBUG 0 che "gli dice" di non tenere in considerazione il codice compreso fra
#if DEBUG e #endif.
Esempio, il codice
Code: [Select]

void ToSerial(String stringa)
{
  #if DEBUG
  Serial.println(stringa);
  #endif
}


se #DEFINE DEBUG è uguale a 0, il compilatore vede questo codice
Code: [Select]

void ToSerial(String stringa)
{
//
}


quindi se uso la funzione ToSerial non fa nulla!
Viceversa se #DEFINE DEBUG è uguale a 1, il compilatore vede il codice originale e quindi la chiamata a Serial.

Spero di essere stato chiaro, altrimenti chiedi pure.
Ciao
Title: Re: Strano freeze del loop
Post by: pablos71 on Oct 05, 2012, 12:43 am
comunque se posso permettermi.

sarebbe utile settare il pin 10 utilizzato dalla ethernet

aggiungi nelle dichiarazioni variabili
byte SD_CS = 4;  // pin 4 is the SPI select pin for the SDcard
byte ETHER_CS = 10; // pin 10 is the SPI select pin for the Ethernet


nel setup()
pinMode(ETHER_CS, OUTPUT);      
 digitalWrite(ETHER_CS, HIGH);
 pinMode(SD_CS, OUTPUT);      
 digitalWrite(SD_CS, HIGH);    

prima di chiudere il client svuota il buffer
   pc_client.flush();
   pc_client.stop();

elimina quel serial.write
//Serial.write(Data_RX);

ciao
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 05, 2012, 08:16 am

comunque se posso permettermi.


;)



sarebbe utile settare il pin 10 utilizzato dalla ethernet

aggiungi nelle dichiarazioni variabili
byte SD_CS = 4;  // pin 4 is the SPI select pin for the SDcard
byte ETHER_CS = 10; // pin 10 is the SPI select pin for the Ethernet


nel setup()
pinMode(ETHER_CS, OUTPUT);      
 digitalWrite(ETHER_CS, HIGH);
 pinMode(SD_CS, OUTPUT);      
 digitalWrite(SD_CS, HIGH);    


per curiosità, a che serve?



prima di chiudere il client svuota il buffer
   pc_client.flush();
   pc_client.stop();


provo



elimina quel serial.write
//Serial.write(Data_RX);

ciao


tanto non viene eseguito perchè è sotto #define.

ciao e grazie
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 05, 2012, 08:34 am
Il pin CS, Chip Select, serve per selezionare quale dispositivo attivare con cui comunicare via SPI.
Title: Re: Strano freeze del loop
Post by: pablos71 on Oct 05, 2012, 09:32 am
Quote
tanto non viene eseguito perchè è sotto #define.


No. Lo devi proprio togliere, indifferentemente dal define debug, nel bel mezzo di client.read mi mandi byte alla seriale se per funzionare lo devi lasciare il define a 0 che lasci a fare quella riga.... la ethernet è già molto rognosa di suo, interrompere il suo lavoro per fare altre cose e poi riprenderle non la prende bene. Fagli finere il ciclo e poi stampa il debug sempre che sia attivato. I serial.print li metterei al di fuori del while (pc_client.connected())

il tuo sketch ce l'ho in test da ieri sera, è ancora li che gira

ciao
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 05, 2012, 09:43 am

Quote
tanto non viene eseguito perchè è sotto #define.


No. Lo devi proprio togliere, indifferentemente dal define debug, nel bel mezzo di client.read mi mandi byte alla seriale se per funzionare lo devi lasciare il define a 0 che lasci a fare quella riga.... la ethernet è già molto rognosa di suo, interrompere il suo lavoro per fare altre cose e poi riprenderle non la prende bene. Fagli finere il ciclo e poi stampa il debug sempre che sia attivato. I serial.print li metterei al di fuori del while (pc_client.connected())

il tuo sketch ce l'ho in test da ieri sera, è ancora li che gira

ciao


domani provo, ti ringrazio
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 20, 2012, 04:57 pm
finalmente ho due minuti per scrivere ...

Code: [Select]

// librerie usate nel progetto
#include "Wire.h"             
#include "SRF02.h"
#include "Ethernet.h"
#include "SPI.h"             
#define DEBUG 0
// costanti che contengono il mac e l'IP della scheda di rete
//byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x50, 0x18 }; //ethernet shield mia
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0C, 0x00, 0x6D }; //ethernet shield mia 2
byte ip[] = { 192,168,1,50 };

// inizializzazione componente SRF con l'indirizzo 0x70
SRF02 sensor(0x70, SRF02_CENTIMETERS);
float larghezza_cisterna = 2;
float lunghezza_cisterna = 2;
float altezza_cisterna = 1.3;
float livello_acqua = 0;
float delta_sensore_galleggiante = 13;
const float capienza_metricubi = larghezza_cisterna * lunghezza_cisterna * altezza_cisterna;
const float capienza_litri = capienza_metricubi * 1000;
float disponibilita_metricubi = 0;
float disponibilita_litri = 0;
float livello_attenzione = 2000;
float livello_allerta = 1200;
float livello_allarme = 700;
bool attenzione = false;
bool allerta = false;
bool allarme = false;
String colore = "white";
unsigned long nextPrint = 0;
byte SD_CS = 4;  // pin 4 is the SPI select pin for the SDcard
byte ETHER_CS = 10; // pin 10 is the SPI select pin for the Ethernet

int led = 12;

//creo una variabile char per memorizzare i byte letti dal client
char Data_RX;
String msg = "";
int cmd = 0;
int real_level = 0;
int thelevel = 0;
String thelevel_txt;
float thelevel_flt;
//creo un oggetto server che rimane in ascolto sulla porta
//specificata
EthernetServer ArduinoServer(80);

void ToSerial(String stringa)
{
  #if DEBUG
  Serial.println(stringa);
  #endif
}

void ToSerial(float stringa)
{
  #if DEBUG
  Serial.println(stringa);
  #endif
}


void setup()
{
  pinMode(ETHER_CS, OUTPUT);     
  digitalWrite(ETHER_CS, HIGH);
  pinMode(SD_CS, OUTPUT);     
  digitalWrite(SD_CS, HIGH);
 
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  #if DEBUG
  Serial.begin(9600);
  #endif
  Wire.begin();
  sensor.setInterval(500);
  //inizializza lo shield con il mac e l'ip
  ToSerial("Ethernet initialization ...");
  Ethernet.begin(mac, ip);
  msg = "1234567890123456789012345678901234567890123456789012345678901234567890";
  String secs_txt;
  for(int i = 1; i < 6; i++){
    secs_txt = String(30 - i * 5);
ToSerial("Ethernet ready in " + secs_txt + " sec.");
    digitalWrite(led, HIGH);
    delay(100);
    digitalWrite(led, LOW);
    delay(4900);
  };
  ToSerial("Ethernet ready");
  //inizializza l'oggetto server
  ArduinoServer.begin();
  ToSerial("Webserver ready");
  sensor.update();
  ToSerial("SRF ready");

  // stato di fine setup e inizio loop
  for(int j = 0; j < 5; j++){
    digitalWrite(led, HIGH);
    delay(250);           
    digitalWrite(led, LOW);
delay(250);
  };
}

//String toWeb(lastringa

void loop()
{
//  SRF02::update();

  //IMPORTANTE pulisco la variabile msg
  msg = "";
  //Ascolto le richieste dei client controllo se ci sono dati da leggere
  //e creo un oggetto relativo a client che sta interrogando l'Ethernet shield
  EthernetClient pc_client = ArduinoServer.available();
  //controllo se pc_client è diverso da false
  if (pc_client != false)
  {
    digitalWrite(led, HIGH);
    //controllo se il client è connesso
    while (pc_client.connected())
    {
      //leggo i byte disponibili
      //provenienti dal client
      Data_RX = pc_client.read();
      //invio i dati letti al Serial Monitor
      ToSerial(Data_RX);
//   Serial.write(Data_RX);
      //Attendo che tutti i byte siano letti
      //quando Data_RX contiene il carattere
      //di nuova line capisco tutti i byte sono
      //stati letti
      msg += Data_RX;
      if (Data_RX == '\n')
      {
        ToSerial("richiesta http completata");
        //Invio la risposta al client
        //invio lo status code
        pc_client.println(F("HTTP/1.1 200 OK"));
        //imposto il data type
        pc_client.println(F("Content-Type: text/html"));
        pc_client.println(F("\n"));
        //invio codice html
        pc_client.println(F("<html>"));
        pc_client.println(F("<head>"));
        pc_client.println(F("<title>Water level</title>"));
        pc_client.println(F("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"10\">"));
        pc_client.println(F("<META HTTP-EQUIV=\"PRAGMA\" CONTENT=\"NO-CACHE\">"));
        pc_client.println(F("</head>"));
        pc_client.println(F("<body bgcolor=\"black\" text=\"white\" link=\"lime\" vlink=\"lime\">"));
        pc_client.println(F("<div align=\"center\" style=\"font-family:tahoma,verdana,arial;font-size:18px;font-style:italic\">"));
        // chiedo il valore all'SRF
        ToSerial("before sensor.update");
        sensor.update();
        ToSerial("after sensor.update");
        if (millis() > nextPrint)
        {
          ToSerial("before sensor.read");
          real_level = sensor.read();
          thelevel = real_level;
          thelevel = thelevel - delta_sensore_galleggiante;
          thelevel_txt =  String(thelevel, DEC);
          thelevel_flt = (float) thelevel / 100;
          livello_acqua = altezza_cisterna - thelevel_flt;
          disponibilita_metricubi = livello_acqua  * lunghezza_cisterna * larghezza_cisterna;
          disponibilita_litri = disponibilita_metricubi * 1000;
          ToSerial("disponibilita = ");
          ToSerial(disponibilita_litri);
          colore = "white";
          if (disponibilita_litri <= livello_attenzione) {
            attenzione = true;
            colore = "yellow";
            ToSerial("stato attenzione");
          };     
          if (disponibilita_litri <= livello_allerta) {
            attenzione = false;
            allerta = true;
            colore = "orange";
            ToSerial("stato allerta");
          };     
          if (disponibilita_litri <= livello_allarme) {
            attenzione = false;
            allerta = false;
            allarme = true;
            colore = "red";
            ToSerial("stato allarme");
          };     
          ToSerial("stato attenzione");
          ToSerial("after sensor.read");
          ToSerial("livello = " + thelevel_txt);
          nextPrint = millis () + 1000;
        };
        pc_client.print(F("valore al sensore "));
        pc_client.print(real_level);
        pc_client.println(F("<br>"));
        pc_client.println(F("valore per i calcoli "));
        pc_client.println(thelevel_flt);
        pc_client.println(F("</div><br><br><br><br><br>"));
        pc_client.println(F("<div align=\"center\" style=\"font-family:tahoma,verdana,arial;font-size:72px\">"));
        pc_client.println(disponibilita_metricubi);
        pc_client.println(F("m<sup>3</sup> di "));
        pc_client.println(capienza_metricubi);
        pc_client.println(F("m<sup>3</sup>"));

        pc_client.println(F("</div>"));
        pc_client.println("<div align=\"center\" style=\"color:" + colore + ";font-family:tahoma,verdana,arial;font-size:72px\">");
        pc_client.println(disponibilita_litri);
        pc_client.println(F(" di "));
        pc_client.println(capienza_litri);
        pc_client.println(F("litri"));
        pc_client.println(F("</div>"));
        pc_client.println(F("</body>"));
        pc_client.println(F("</html>"));
        //aspetto 10 ms affinche la risposta giunga al browser del client
        delay(10);
        //esco dal ciclo while una volta completato l'invio della risposta
        break;
      }
      //chiudo la connessione
    }
pc_client.flush();
    pc_client.stop();
    pc_client = false;
    msg = "";
delay(7500);
    digitalWrite(led, LOW);
  } else {
    digitalWrite(led, HIGH);
    delay(80);           
    digitalWrite(led, LOW);
    delay(2000);
  };
}


ecco il codice montato sulla mia leonardo, ma dopo circa 12/15 ore di funzionamento si blocca.
Potrebbe essere guasta? La shield ethernet l'ho già cambiata.

Ho anche una mega 2560, provo con quella?

Ciao e grazie a tutti
Title: Re: Strano freeze del loop
Post by: uwefed on Oct 20, 2012, 08:58 pm
Quote
Ho anche una mega 2560, provo con quella?

Sí.
Potrebbe essere un problema di RAM. Facendo la prova con la MEGA puoi controllarlo.

Ciao Uwe
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 21, 2012, 10:49 am

Quote
Ho anche una mega 2560, provo con quella?

Sí.
Potrebbe essere un problema di RAM. Facendo la prova con la MEGA puoi controllarlo.

Ciao Uwe


montata ... speriamo bene!
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 21, 2012, 10:54 am
Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..

Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.
Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.
So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 21, 2012, 11:02 am

Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..


no, come si fa?


Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.


si, ma solo con il define DEBUG a 1


Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.


già ho provato ad usare F() in tutto le Serial.println che non avevano all'interno variabili, ma il sistema andava lo stesso in loop.


So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.


questo non è un problema, puoi farmi un esempio? Grazie
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 21, 2012, 11:09 am


Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..


no, come si fa?

Compili lo sketch senza farne l'upload e con la modalità verbose attiva.
Nel terminale dell'IDE leggi dove sono stati creati i file temporanei del progetto e ti sposti in quella cartella.
Lì dai il comando:
Code: [Select]
avr-size -C nomeFirmware.cpp.elf

Quote


Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.


si, ma solo con il define DEBUG a 1
.
No, sempre! Il check se hai la modalità debug attiva lo fai all'interno della funzione ToSerial, quindi la funzione ToSerial viene chiamata sempre, col risultato che la variabile stringa viene sempre creata nella Ram e passata alla funzione, anche quando poi non stampi sulla seriale.

Quote


Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.


già ho provato ad usare F() in tutto le Serial.println che non avevano all'interno variabili, ma il sistema andava lo stesso in loop.


So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.


questo non è un problema, puoi farmi un esempio? Grazie


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 21, 2012, 11:56 am
Quote




Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..


no, come si fa?

Compili lo sketch senza farne l'upload e con la modalità verbose attiva.
Nel terminale dell'IDE leggi dove sono stati creati i file temporanei del progetto e ti sposti in quella cartella.
Lì dai il comando:
Code: [Select]
avr-size -C nomeFirmware.cpp.elf



ecco il risultato

AVR Memory Usage
----------------
Device: Unknown

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

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


Quote

Quote

Quote


Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.


si, ma solo con il define DEBUG a 1
.
No, sempre! Il check se hai la modalità debug attiva lo fai all'interno della funzione ToSerial, quindi la funzione ToSerial viene chiamata sempre, col risultato che la variabile stringa viene sempre creata nella Ram e passata alla funzione, anche quando poi non stampi sulla seriale.

Quote


Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.


già ho provato ad usare F() in tutto le Serial.println che non avevano all'interno variabili, ma il sistema andava lo stesso in loop.


So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.


questo non è un problema, puoi farmi un esempio? Grazie


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash




ok, adesso lo modifico
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 21, 2012, 12:30 pm

Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash



il codice sta già girando ... speriamo bene!

Piccolo appunto: se attivo il debug, il compilatore mi segnala errori perchè alla funzione F() posso passare solo stringhe e non variabili che contengono stringhe.
Code: [Select]

    #if DEBUG
    Serial.println(F("Ethernet ready in " + secs_txt + " sec.")); ////ERRORE DEL COMPILATORE
    #endif


invece

Code: [Select]

  #if DEBUG
  Serial.println(F("Ethernet initialization ...")); //// NESSUN ERRORE
  #endif



Per queste uso Serial.println senza F() ?
Grazie
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 21, 2012, 05:33 pm
Code: [Select]
Serial.println(F("Ethernet ready in " + secs_txt + " sec.")); ////ERRORE DEL COMPILATORE
Scomponila in più parti, no?  ;)

Esempio:
Code: [Select]
#if DEBUG
Serial.print(F("Ethernet ready in "));
Serial.print(secs_txt); //solo questo verrà copiato in Ram
Serial.println(F(" sec."));
#endif

Nota l'uso di println solo con l'ultima stampa.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 25, 2012, 10:47 pm


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash



il codice sta già girando ... speriamo bene!



Niente da fare: dopo 36 ore si blocca.
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 25, 2012, 10:50 pm
Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 25, 2012, 11:13 pm

Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?
Title: Re: Strano freeze del loop
Post by: marcello.romani on Oct 25, 2012, 11:20 pm
Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.
Title: Re: Strano freeze del loop
Post by: leo72 on Oct 25, 2012, 11:40 pm


Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?

Ho scritto un articolino apposta:
http://www.leonardomiliani.com/?p=572


Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.

10 secondi come intervallo sono troppo pochi. Basta 1 volta all'ora, visto che gli è andato in crash l'Arduino dopo 36 ore.
Title: Re: Strano freeze del loop
Post by: essere_digitale on Oct 26, 2012, 12:01 am



Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?

Ho scritto un articolino apposta:
http://www.leonardomiliani.com/?p=572


Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.

10 secondi come intervallo sono troppo pochi. Basta 1 volta all'ora, visto che gli è andato in crash l'Arduino dopo 36 ore.


Non ho parole ...