[RISOLTO] AIUTO ETHERNET SHIELD

Buona sera vi espongo il mio problema : ( premetto che non sono un gran esperto .. )

Ho la necessità che ARDUINO scriva su un DATABASE MYSQL il valore degli ingressi digitali e che recuperi da un altro DATABASE un valore BINARIO per pilotare le uscite

Ho sviluppato questo :

#include <Ethernet.h>
#include <SPI.h>

int in1 = 0;
int in2 = 1;
int in3 = 2;
int in4 = 3;
int in5 = 4;


int out1 = 5;
int out2 = 6;
int out3 = 7;
int out4 = 8;
int out5 = 9;


int read1;
int read2;
int read3;
int read4;
int read5;

byte server[] = { xxx, xxx, xxx , xxx };

String location = "/~xxxxxx/xxxxxxx.php?id=xxxxx HTTP/1.0";

byte mac[] = { 0xXY, 0xXY, 0xXY, 0xXY, 0xXY, 0xXY };


EthernetClient client;

char inString[32];
int stringPos = 0; 
boolean startRead = false; 
char charArray[10];

void setup(){
  Ethernet.begin(mac);
  Serial.begin(9600);
  
  pinMode(in1, INPUT);
  pinMode(in2, INPUT);
  pinMode(in3, INPUT);
  pinMode(in4, INPUT);
  pinMode(in5, INPUT);
  
  pinMode ( out1 , OUTPUT);
  pinMode ( out2 , OUTPUT);
  pinMode ( out3 , OUTPUT);
  pinMode ( out4 , OUTPUT);
  pinMode ( out5 , OUTPUT);
}

void loop(){
  String pageValue = connectAndRead();

  

  pageValue.toCharArray(charArray, 10);
  unsigned long result = atoi(charArray);
  // il valore num e un numero intero letto dal database
  
  Serial.println(result); 

  digitalWrite(out5, result & B00001);
  digitalWrite(out4, result & B00010);
  digitalWrite(out3, result & B00100);
  digitalWrite(out2, result & B01000);
  digitalWrite(out1, result & B10000);
  
  
  delay(2500);


  
}

String connectAndRead(){


  if (client.connect(server, 80)) {
    Serial.println("Leggo dal database il valore delle Uscite");
    client.print("GET ");
    client.println(location);
    client.println();

    return readPage();

  }else{
    return "connection failed";
  }

}

String readPage(){


  stringPos = 0;
  memset( &inString, 0, 32 ); 

  while(true){

    if (client.available()) {
      char c = client.read();

      if (c == '<' ) { 
        startRead = true; 
      }else if(startRead){

        if(c != '>'){ 
          inString[stringPos] = c;
          stringPos ++;
        }else{
      
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return connectAndWrite();

        }
      }
    }
  }
}

String connectAndWrite(){
  
  
  read1 = digitalRead(in1);
  read2 = digitalRead(in2);
  read3 = digitalRead(in3);
  read4 = digitalRead(in4);
  read5 = digitalRead(in5);
  
  
   if (client.connect(server, 80)) {
    Serial.println("Invio al database ingressi digitali");
    client.print("GET /xxxxxx.php?xxxxx=xxxxxx");
    client.print("&in1=");
    client.print(read1);
    client.print("&in2=");
    client.print(read2);
    client.print("&in3=");
    client.print(read3);
    client.print("&in4=");
    client.print(read4);
    client.print("&in5=");
    client.print(read5);
    client.println(" HTTP/1.0");
    client.println("HOST: xxxxx.it");
    client.println();
  
  }
  
  
          startRead = false;
          client.stop();
          client.flush();
          delay(100);
          return inString;
          
          
          
}

Funziona alla perfezione , ma ogni tanto si interrompe la comunicazione ed ARDUINO entra in un limbo dal quale non esce più ... per ristabilire la connessione al SERVER devo riavviare. Il codice lo ho scritto "scopiazzando" pezzi qua e la ma non trovo una via di uscita a questo problema

Grazie in anticipo

Entri in un argomento dolente, la ethernet shield (w5100) ogni tanto si freeza.
http://arduino.cc/forum/index.php/topic,94572.0.html

alla pag 9 trovi una apparente risoluzione da testare, nel caso decidessi di accettare la missione :slight_smile: sarebbe utile alla comunità conoscere l'esito della modifica, quindi ritorna ed esprimi la tua opinione a riguardo, grazie
https://github.com/johannrichard/Arduino/commit/47c46c4f254cb073b08e6e0fcfdff8dea797a39a#diff-0

buona lettura

ciao

Ciao pablos e grazie per il link ...

Sai la cosa strana ??

Ho 3 ARDUINO con relativi ETHERNET SHIELD ( premetto 3 indirizzi MAC diversi ) tutti e 3 con lo stessoprogramma che gira ( quello del post precedente )

ognuno comunica con il mio SERVER ma con ID univoco , il SERVER memorizza l'ultima esistenza in vita di ARDUINO ..

Assurdo ma vero.. tutte e tre smettono di funzionare alla stessa ora ( minuto e secondo ) anche se le accendo in tempi diversi

Quindi credo che il SERVER ogni tanto rifiuti la connessione eforo si impallano... infatti chiedevo se era possibile fare in modo che , se non trovano la connessione , il programma riparti da zero.

Ho provato con il WATCH DOG ma il problema e che , quando resetta , le uscite che avevo attive mi si spengono e ciò non posso farlo accadere !! ( controllano l'irrigazione penza che bordello )

Grazie

Bhe quello che ti succede è proprio quello definito su quel link dove viene proposta una modifica alla libreria. Il testo tradotto da Vanzati dice:

Tra le situazioni in cui il chip sembra freezarsi e una delle cause potrebbe essere che quando si trova nella condizione di lasciare una connessione, si mette nello stato di CLOSE_WAIT, quindi sta lì ad aspettate una risposta che di fatto non riceve perchè qualcosa è andato storto nella trasmissione precedente.

L'importante in tutto questo è che la ethernet non si pianti, può cadere la connessione e la ethernet deve essere in grado di chiudersi in caso di mancata risposta. Visto che tu arduino lo usi come client ed è lui che chiama il server, potrebbe ristabilire la connessione da solo appena passato il disservizio.

quindi potresti provare, al massimo resta tutto come prima

soluzioni che potrebbero essere dei ripieghi sono:
Mandare al server l'ultimo status delle porte, in caso di riavvio arduino chiede al server "mi sono riavviato mandami l'ultimo stato!!"
Scrivere su SD i parametri ogni n secondi e caricarli con un file.ini al riavvio

ciao

Il pin 0 e 1 sono usati dalla seriale, ti consiglio di non usarli per leggere dati da sensori esterni.

maxvetro:

int in1 = 0;

int in2 = 1;

Poi mandi segnali anche sui pin 4 e 10 che servono per selezionare la SD o la Ethernet. Potrebbe essere causa di problemi anche quello.

Ti ricordo che rimappando i pin analogici da 14 a 19 puoi usarli come uscite o ingressi digitali.

risposta a PaoloP :

OK per il PIN 1 , 2 effettivamente li ho usati in quanto non utilizzavo la seriale e volevo sfruttare tutte le risorse di ARDUINO ( MA LI POSSO CAMBIARE )

Il PIN 4 lo utilizzo in quanto non ho necessità della SD card ( NON SAPEVO ANDASSE LASCIATO LIBERO )

Il PIN10 non lo sto utilizzando !

risposta a pablos :

In realtà utilizzo già il SERVER per memorizzare lo stato delle uscite , infatti se lo riavvio le uscite tornano come erano... ma il problema e che si SPENGONO e poi RIACCENDONO e ciò non dovrebbe accadere

Serial.println(result); 

  digitalWrite(out5, result & B00001);
  digitalWrite(out4, result & B00010);
  digitalWrite(out3, result & B00100);
  digitalWrite(out2, result & B01000);
  digitalWrite(out1, result & B10000);

Come vedi dalla porzione di codice , leggo il numero dal DATABASE , lo converto in BINARIO e attivo le uscite !

L'ideale sarebbe "RIAVVIARE" a cicli regolari l'ETHERNET SHIELD sensa "RIAVVIARE" ARDUINO

Scusa, non avevo notato che avessi saltato i pin 4 e 10. :roll_eyes:

maxvetro:
L'ideale sarebbe "RIAVVIARE" a cicli regolari l'ETHERNET SHIELD sensa "RIAVVIARE" ARDUINO

Mi sembra che l'utente DanielaES nel suo progetto http://arduino.cc/forum/index.php/topic,81321.0.html abbia fatto una cosa del genere.

Ho già provato a isolare i 2 pin di reset e resettare solo la ethernet in corsa, ma questa non riparte più, ha bisogno di essere resettato insieme ad arduino.

Si in effetti avevo già fatto anche io la prova di RESET del solo SHILED ma non riparte..

Cercavo un sistema affidabile.. uff

Chiedo se possibile un altra cosa..

se usassi ARDUINO come SERVER , ( non vorrei usare termini errati ) il problema si presenta lo stesso ?

Mi spiego meglio

Arduino rimane in ascolto su una porte , io gli invio un comando dalla rete e lui accende la luce su un PIN.. anche così si pianta ?

Grazie

No, a me così non si pianta, la ethernet è a riposo e ogni tanto la chiamo.
Non ho esperienza diretta su una connessione continua, quindi non so dirti se c'e' una possibilità di schianto.
Hai una necessità di avere una comunicazione di 24h/24?

ciao

Il progetto lo avevo pensato in questo modo :

ogni 2 minuti ARDUINO legge lo stato di 5 ingressi , si collega ad un SERVER ed invia i dati ( tramite una pagina PHP ) a un DB MYSQL
contestualmente chiede al DB MYSQL come deve impostare le uscite ed esegue

E funziona tutto bene ( a parte il freeze )

Ho preferito questa soluzione per evitare di dover attivare servizi DDNS ( non devo cercarlo in rete ed inviargli richieste )

Si , ho la necessita di monitorare ingressi in modo continuo 24 ore su 24 ore

Grazie per l'interesse

P.S.

Nel frattempo ho modificato la libreria "libraries/Ethernet/EthernetClient.cpp" ( come da LINK postati da altri utenti ) e lo sto testando

 for (int i = 0; i < MAX_SOCK_NUM; i++) {
        uint8_t s = W5100.readSnSR(i);



        // originale
        if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {


        // modificata
        if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {




        _sock = i;
        break;

}

Nel frattempo ho modificato la libreria "libraries/Ethernet/EthernetClient.cpp" ( come da LINK postati da altri utenti ) e lo sto testando

Ottimo: se scopri che risolve il tuo problema fammi sapere.

ciao

Assolutamente si ... domani sera posto i risultati !! Normalmente si piantava entro 4 / 5 ore ...

Nel frattempo se qualcuno avesse qualche idea tengo il post aperto ancora qualche giorno

Grazie a tutti

Spero che i progressi aiutino tutti !!

Ho connesso alla rete 3 moduli ARDUNO con la libreria modificata "libraries/Ethernet/EthernetClient.cpp" come da post precedente

In questo momento ( a 20 ore di connessione continua ) i tre moduli sono sempre connessi , li vedo dal database che aggiorna ogni 5 minuti lo stato trasmesso

In uno dei tre ho attivato le uscite digitali ( dove ci sono connessi dei LED ) tramite il codice

String pageValue = inString;

            pageValue.toCharArray(charArray, 10);
            unsigned long result = atoi(charArray);
          
            
            //Serial.print("risultato letto ==> ");
            //Serial.println(inString);
            
            
            digitalWrite(out5, result & B00001);
            digitalWrite(out4, result & B00010);
            digitalWrite(out3, result & B00100);
            digitalWrite(out2, result & B01000);
            digitalWrite(out1, result & B10000);

dopo 20 minuti , il modulo in questione è andato in FREEZE... ora ho provato a mettere un ritardo tra l'attivazione delle uscite e la continuazione del programma

String pageValue = inString;

            pageValue.toCharArray(charArray, 10);
            unsigned long result = atoi(charArray);
          
            
            //Serial.print("risultato letto ==> ");
            //Serial.println(inString);
            
            
            digitalWrite(out5, result & B00001);
            digitalWrite(out4, result & B00010);
            digitalWrite(out3, result & B00100);
            digitalWrite(out2, result & B01000);
            digitalWrite(out1, result & B10000);

            delay (1000);

Attivo le uscite e vi tengo aggiornati

Brutte notizie..

Ho appena ricevuto la mail dal server che mi comunica che la periferica n°1 ( quella senza OUTPUT collegati ) non è più raggiungibile !!!
Ora attendo di vedere se si riprende da sola ( ne dubito ) altrimenti stasera arrivo a casa e vedo

Mi dispiace, probabilmente la patch non basta, non è escluso però che ne tuo caso ci possa essere un problema software.
tutti i moduli hanno lo stesso software?

ciao

Ciao pablos

Si tutte le periferiche hanno lo stesso software , l'unica differenza il delay dopo il comando delle uscite

linko la versione attuale

////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// PERIFERICA NUMERO XXXXXXXX///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <Ethernet.h>
#include <SPI.h>




int in1 = 19;
int in2 = 18;
int in3 = 2;
int in4 = 3;
int in5 = 4;


int out1 = 5;
int out2 = 6;
int out3 = 7;
int out4 = 8;
int out5 = 9;


int read1;
int read2;
int read3;
int read4;
int read5;

byte server[] = { xxx, xxx, xxx, xxx };

String location = "/~xxxxxx/xxxxxxxx.php?id=xxxxxxxx HTTP/1.0";

byte mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };

byte ip[] = { 192,168,1, 122 };


EthernetClient client;

char inString[32];
int stringPos = 0; 
boolean startRead = false; 
char charArray[10];

void setup(){
  

  
  
  pinMode(in1, INPUT);
  pinMode(in2, INPUT);
  pinMode(in3, INPUT);
  pinMode(in4, INPUT);
  pinMode(in5, INPUT);
  
  pinMode ( out1 , OUTPUT);
  pinMode ( out2 , OUTPUT);
  pinMode ( out3 , OUTPUT);
  pinMode ( out4 , OUTPUT);
  pinMode ( out5 , OUTPUT);
  
  
  
  
   ////Serial.begin(9600);
  
  
  ////Serial.println("ricavo IP usando DHCP");

  if (!Ethernet.begin(mac)) {

    ////Serial.println("DCHCP fallito , assegno Ip manuale");
    Ethernet.begin(mac, ip);
    
  }
  
  //Serial.print("My address:");
  //Serial.println(Ethernet.localIP());
  delay(2000);

}

void loop(){
  
   

  
  String pageValue = connectAndRead();
  
  
  delay(1000);


  
}

String connectAndRead(){


  if (client.connect(server, 80)) {
    //Serial.println("connesso alla pagina xxxxxxxxx.php");
    client.print("GET ");
    client.println(location);
    client.println();

    delay(1000);
    
    
    return readPage();

  }else{
    //Serial.println("errore connessione alla pagina xxxxxxxxxxx.php");
    //return "connection failed";
    
  }

}

String readPage(){


  stringPos = 0;
  memset( &inString, 0, 32 ); 

  while(true){

    if (client.available()) {
      char c = client.read();

      if (c == '<' ) { 
        startRead = true; 
      }else if(startRead){

        if(c != '>'){ 
          inString[stringPos] = c;
          stringPos ++;
          
        }else{
          
            String pageValue = inString;

            pageValue.toCharArray(charArray, 10);
            unsigned long result = atoi(charArray);
          
            
            //Serial.print("risultato letto ==> ");
            //Serial.println(inString);
            
            
            digitalWrite(out5, result & B00001);
            digitalWrite(out4, result & B00010);
            digitalWrite(out3, result & B00100);
            digitalWrite(out2, result & B01000);
            digitalWrite(out1, result & B10000);
            
            delay (1000);
            
          
      
          startRead = false;
          client.stop();
          client.flush();
        
  
          return connectAndWrite();
          
          

        }

      }
    }

  }

}

String connectAndWrite(){
  

  
  
  read1 = digitalRead(in1);
  read2 = digitalRead(in2);
  read3 = digitalRead(in3);
  read4 = digitalRead(in4);
  read5 = digitalRead(in5);
  
  
  delay(1000);
  
   if (client.connect(server, 80)) {
    //Serial.println("connesso alla pagina xxxxxxxxxx.php");
    client.print("GET /xxxxxxxxxxx.php?seriale=xxxxxxxx");
    client.print("&in1=");
    client.print(read1);
    client.print("&in2=");
    client.print(read2);
    client.print("&in3=");
    client.print(read3);
    client.print("&in4=");
    client.print(read4);
    client.print("&in5=");
    client.print(read5);
    client.println(" HTTP/1.0");
    client.println("HOST: tech-alarm.it");
    client.println();
  
  } else { 
  
  //Serial.println("errore connessione alla pagina xxxxxxxxxx.php"); 

}
  
  
          client.stop();
          client.flush();
          delay(100);
          return inString;
          
          
          
}

Se qualcuno volesse dargli un occhio....

credo di aver fuso... sono arrivato alla fine dei test

Unica soluzione possibile con watcdog esterno al quale azzeriamo il conteggio quando il programma effettua un ciclo completo.

Se nessuno lo resetta lui riavvia arduino

le uscite di arduino le ho fatte diventare impulsive in modo che , al riavvio , non cambi nulla

NON E' UNA SOLUZIONE MA UN ACCROCCHIO ( PERSONALMENTE A ME NON FA IMPAZZIRE ) SPERO IN FUTURI AGGIORNAMENTI DELLE LIBRERIE DELL'ETHERNET SHIELD

Qualcuno ha provato uno shield che monta un altro chip ??

Ciao e grazie

ciao

gli shield con l'enc28j60 di microchip non sembrano soffrire di problemi di blocco, ne ho in esecuzione da settimane senza particolari problemi... ho scritto anche un tutorial sul loro uso: http://www.lucadentella.it/category/enc28j60-arduino/

hai però altri limiti:

  • tutto lo stack TCP/IP è a carico di Arduino, il chip ENC28j60 si occupa "solo" della parte Ethernet... questo significa più carico e un diverso "approccio" alla programmazione (nel tuo loop devi prevedere esplicitamente chiamate al loop dei pacchetti);

  • anche il buffer di ricezione/trasmissione è in memoria Arduino (600-700bytes) quindi hai meno memoria disponibile per il tuo uso;

  • per ora le librerie non supportano la frammentazione del pacchetto TCP in più pacchetti IP, sei quindi limitato al valore MTU della rete (di solito 1500 bytes) come dimensione massima dei dati che puoi inviare...

bye

Sempre in quel link che ti ho messo tempo fa http://arduino.cc/forum/index.php/topic,94572.0.html si parla anche di chip ethernet alternativi, mi sembra "legacy" abbia testimoniato come lucadentella qui sopra che non ha problemi con enc28j60, ripeto riguardo a me sulla mia shield con il 5100 ho un traffico di 1 MB circa al minuto e non si è mai freezata il massimo di tempo in test che ho fatto sono 10-12 ore circa, poi aggiungo modifico e quindi riavvio spesso.

ciao