[Risolto] Domenica scorsa questo skecth funzionava

Salve a tutti,

da domenica scorsa (giorno della mia ultima prova) questo sketch mi funzionava, da oggi non mi funziona più nonostante io non abbia fatto modifiche al sistema (pc con win 7 64).
Sto usando diverse schede arduino uno r3 abbinate con diverse ethernet shield (tutte W5100).

/*
 Apertura cancello
 Novembre 2013
 Roberto Ceccherini
 */
//Librerie impiegate per il progetto
#include <SPI.h>
#include <Ethernet.h>

//Creo un array di byte per specificare il mac address
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0xCC, 0xFF, 0xBC };
//creo un array di byte per specificare l'indirizzo ip
IPAddress ip( 192, 168, 1, 46); //modificare questo valore in base alla rete
//Creo un array per definire il gateway
IPAddress gateway(192, 168, 1, 254);
//Creo un array per la subnet
IPAddress subnet(255, 255, 255,0);
IPAddress remoteV(192, 168, 1, 47);
IPAddress remoteC(192, 168, 1, 48);
//costanti
char Data_RX;
int apriCancello = 2; // collegare relay apertura cancello
int apriCancelloR = 5; // collegare pulsante apertura ritardata
int suonaCampanello = 6; // collegare pulsante suoneria campanello
int accendiLuce = 7; // collegare il relay che controlla la accendiLuce a 220v
String msg = "";
unsigned long tAttuale;
unsigned long tLimite = 420000;
int ritardo;
//creo un oggetto server che rimane in ascolto sulla porta specificata
EthernetServer ArduinoServer(80);
EthernetClient client;

void setup()
{
  delay(50);
  //inizializza lo shield con il mac e l'ip  
  Ethernet.begin(mac, ip, gateway, subnet);
  ArduinoServer.begin();
  //inizializza la porta seriale
  Serial.begin(9600);
  //il pin 2(cancello)
  //il pin 5 mi serve per aprire il cancello in differita dal consenso
  //il pin 6(campanello) come ingresso in PULLUP
  //il pin 7(accendiLuce) come uscita 
  pinMode(apriCancello, OUTPUT);
  pinMode(accendiLuce, OUTPUT);
  pinMode(suonaCampanello, INPUT_PULLUP);
  pinMode(apriCancelloR, INPUT_PULLUP);
  Serial.println("Arducancello Ver. 2.0");
  Serial.println(Ethernet.localIP());
  //  digitalWrite(apriCancello, HIGH); da utilizzare con i nuovi relay con pcb blu
}
void loop()
{
  //IMPORTANTE pulisco la variabile msg
  msg = "";
  EthernetClient pc_client = ArduinoServer.available();
  //controllo se pc_client è true
  if (pc_client != false)
  {
    //controllo continuamente che il client sia connesso
    while (pc_client.connected())
    {
      //Controllo se ci sono byte disponibili per la lettura
      if (pc_client.available())
      {
        //leggo i byte disponibili
        //provenienti dal client
        Data_RX = pc_client.read();
        Serial.write(Data_RX);
        //ricostruisco la stringa ricevuta concatenando i singoli byte
        msg += 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
        if (Data_RX == '\n')
        {
          //cerco all'interno della stringa il parametro che mi interessa
          //quindi piloto l'uscita
          if (msg.indexOf("apri") > 0)
          { 
            pc_client.print("Apertura cancello");
            digitalWrite(apriCancello, HIGH);
            delay(500);
            digitalWrite(apriCancello, LOW);
          }  
          if (msg.indexOf("L=1") > 0)
          { 
            digitalWrite(accendiLuce, HIGH);
          }
          if (msg.indexOf("L=0") > 0)
          { 
            digitalWrite(accendiLuce, LOW);
          }
          if (msg.indexOf("rapr") > 0)
          {
            tAttuale = millis();
            do
            {
              ritardo = digitalRead(apriCancelloR);
              suonacampanello();
              if ((millis() - tAttuale) > tLimite) 
              {
                break;
              }  
            } 
            while (ritardo == HIGH);
            if (ritardo == LOW)
            {
              delay(150); // per evitare rimbalzi del pulsante
              if (ritardo == LOW)
              {
                digitalWrite(apriCancello, HIGH);
                delay(500);
                digitalWrite(apriCancello, LOW);
              }
            }  
          }
          break;
        }
        pc_client.println(F("HTTP/1.1 200 OK"));
        pc_client.println(F("Content-Type: text/html"));
        // inizializzo pagina (da togliere se uso ajax)
        pc_client.print("<html><head><title>Pannello di controllo cancello Tenuta il Sassone</title></head><body>");
        //inizai il body
        pc_client.println(F("<body bgcolor=#720000 text=#D2B210 link=#FFD713 vlink=#000000>"));
        pc_client.println(F("<div style='width:720px; height:1280px;'>"));
        pc_client.println(F("<h1 align='center'>Tenuta Il Sassone</h1>"));
        pc_client.println(F("<hr />"));
        pc_client.println(F("<h2 align='center'>Gestione cancello via intranet</h2>"));
        pc_client.println(F("<hr />"));
        pc_client.println(F("<h2 align='center'>Apertura cancello</h2>"));
        pc_client.print("<h3 align='center'><a href='/apri/'>Apri</a>");
        pc_client.println(F("<hr />"));
        pc_client.println(F("
"));
        pc_client.println(F("<h2 align='center'>Apertura cancello ritardata</h2>"));
        pc_client.print("<h3 align='center'><a href='/rapr/'>Apri ritadato</a>");
        pc_client.println(F("<hr />"));
        pc_client.println(F("<h2 align='center'>Luce cancello</h2>"));
        pc_client.print("<h3 align='center'><a href='/L=1'>Accendi</a> | <a href='/L=0'>Spegni</a></h3>");
        pc_client.println(F("<hr />"));
        pc_client.println(F("
"));
        pc_client.println(F("</div>"));
        pc_client.println(F("</body></html>"));
      }
    }
    //fermo il client
    pc_client.stop();    
  }
  suonacampanello();
}

void suonacampanello()
{
  //spedici messaggio se premono il pulsante del campanello
  int camp = digitalRead(suonaCampanello);
  if (camp == LOW)
  {
    delay(250); // aspetto per essere sicuro che non sia un rimbalzo del pulsante
    camp = digitalRead(suonaCampanello);
    if (camp == LOW)
    {
      if (client.connect(remoteV,80))
      {
        Serial.println(F("Suono in Villa"));
        client.println(F("PUT /suona/ HTTP/1.1"));
        client.stop();  
        delay(150);
      }
      if (client.connect(remoteC,80))
      {
        Serial.println(F("Suono in Cantina"));
        client.println(F("PUT /suona/ HTTP/1.1"));
        client.stop();  
        delay(150);
      }
    }
  }
}

grazie a tutti

per completezza... uso IDE 1.0.5.
Per non mi funziona più intendo che non mi fa più vedere la pagina web ed inoltre sul serial monitor i comandi che riceve li visualizza con una lentezza mostruosa (nell'ambito di un carattere ogni mezzo secondo), se invece la parte web la elimino (la commento per esempio) il tutto ricomincia a funzionare bene. dite che potrebbe essere un problema di memoria?

Misura in esecuzione l'occupazione e fattela stampare sul monitor seriale ...
... dai un'occhiata QUI per vedere come puoi fare :wink:

Guglielmo

Se non hai cambiato niente nello Sketch si puó presuppore un falso contatto da qualche parte. Controlla bene tutti i cavetti.
Ciao Uwe

Vedo un errore basilare:

String msg = "";

Evitare l'uso degli oggetti String.
Se proprio non se ne può fare a meno, mai dichiararle vuote! Sempre dichiararle inizializzandole con una stringa senza senso che sia lunga almeno quanto il massimo numero di caratteri che poi andrai a metterci. Ad esempio:

String msg = "kljdrhgklewhnigvlerhgvehcgileuhcgeiwrcgeliwotuewljcgeoljcteorjctorctrer";

Una volta fatto questo, prima di usarla puoi svuotarla con msg = "";
In questo modo eviti la frammentazione della memoria causata dalla continua distruzione e ricreazione dell'oggetto in RAM

ok grazie a tutti per l'aiuto.... faccio le prove che mi avete consigliato e vi faccio sapere se ho risolto o no

gpb01:
Misura in esecuzione l'occupazione e fattela stampare sul monitor seriale ...
... dai un'occhiata QUI per vedere come puoi fare :wink:

Guglielmo

ecco l'occupazione con avr-size

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

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

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

leo72:
Vedo un errore basilare:

String msg = "";

Evitare l'uso degli oggetti String.
Se proprio non se ne può fare a meno, mai dichiararle vuote! Sempre dichiararle inizializzandole con una stringa senza senso che sia lunga almeno quanto il massimo numero di caratteri che poi andrai a metterci. Ad esempio:

String msg = "kljdrhgklewhnigvlerhgvehcgileuhcgeiwrcgeliwotuewljcgeoljcteorjctorctrer";

Una volta fatto questo, prima di usarla puoi svuotarla con msg = "";
In questo modo eviti la frammentazione della memoria causata dalla continua distruzione e ricreazione dell'oggetto in RAM

fatto anche questo grazie :slight_smile:

killrob:
ecco l'occupazione con avr-size

Quella è l'occupazione statica, non a run-time ... io t'avevo detto :

gpb01:
Misura in esecuzione l'occupazione e fattela stampare sul monitor seriale ...

... usando la funzione memoryFree(), descritta in quel link ... :wink:

Guglielmo

ok ok lo faccio :slight_smile: speravo bastasse la statica :stuck_out_tongue:

killrob:
ok ok lo faccio :slight_smile: speravo bastasse la statica :stuck_out_tongue:

Non solo ma fallo in più punti ed in differenti condizioni del programma .. così vedi come cambia ... :wink:

Guglielmo

la memoryfree mi riporta su seriale il valore "699" fisso

Inizia a fare un pò di debug sano e semplice, mettendo in tutti i punti del programma una serie di Serial.println(F("riga...xxx")) e vedi un pò dov'è che si blocca/rallenta. Altrimenti non ne vieni più a capo :sweat_smile:

alla fine ho capito....

la arduino uno che utilizzo solo per fare test (in "produzione" ci mando solo schede "vergini") pare che abbia problemi di comunicazione con la shield ethernet.
Ho provato un altro arduino uno con la medesima shield ed ha funzionato.
come posso verificare che i contatti vengano fatti bene sulla scheda? posso provare a collegare i PIN della shield ad arduino senza accoppiarle?

L'ethernet shield dialoga con il connettore ICSP che c'è a DX dell'Arduino. Controlla che i contatti dentro non siano sporchi. Forse possono essere usurati, se hai infilato/sfilato spesso il connettore.

ok ci guardo che mi pare sia la cosa principale da controllare...

però la arduino uno ha gli ICSP maschi, adesso mi ha funzionato perchè ho usato una arduino uno "nuova" ma la ethernet, che ha ICSP femmine, era la stessa

Vero, non ricordavo che il connettore sulla scheda è maschio.
Forse allora una saldatura alla base che ha ceduto un pò? va visto un pò tutto.