enc28J60 e Arduino (18)

luca 18/09/2014 15

Negli ultimi mesi ci sono stati importanti sviluppi sulla libreria Ethercard che abbiamo imparato ad utilizzare per gestire gli ethernet shield basati su ENC28J60 ed è finalmente possibile inviare dati spezzandoli in più pacchetti TCP: vediamo come fare…

Un po’ di teoria

Le comunicazioni attraverso Internet sfruttano uno stack di protocolli, ovvero un insieme di protocolli diversi, ognuno specializzato in un particolare compito. In fase di trasmissione, un protocollo prepara il proprio pacchetto dati e lo invia al protocollo sottostante fino ad arrivare al protocollo che regola lo strato fisico, ovvero la traduzione dei dati in segnali elettrici e il loro invio attraverso il cavo di rete:

tcp_stack

Ad ogni passaggio, il pacchetto dati viene arricchito di informazioni necessarie ai vari protocolli per assolvere i loro compiti. Inoltre, ogni protocollo può frammentare un pacchetto proveniente dal protocollo soprastante in più pacchetti.

Quando accediamo ad un sito Internet, il nostro browser utilizza il protocollo HTTP per comunicare con il webserver di destinazione. La richiesta viene poi incapsulata all’interno di uno o più pacchetti TCP, i quali poi vengono a loro volta racchiusi in pacchetti dai protocolli sottostanti fino ad essere inviati in rete. Quando i pacchetti arrivano al server, questi vengono di volta in volta elaborati dai protocolli in ordine inverso, finché la richiesta originale viene passata all’applicativo che fa da webserver e che “capisce” il protocollo HTTP:

http_flow

Se la richiesta del browser o la risposta del webserver contiene un elevato numero di bytes, il protocollo TCP è in grado di frammentare tali dati in più pacchetti. Ogni pacchetto TCP contiene alcuni flags, ovvero campi che danno informazioni al ricevente. Per ogni pacchetto ricevuto, viene inviato un ACK di conferma, mentre l’ultimo frammento di una trasmissione avrà il flag FIN1, ad indicare che la trasmissione è terminata.

Ethercard

La libreria Ethercard offre ora la possibilità di creare pacchetti specificando quali flags TCP tali pacchetti conterranno.

Se stiamo sviluppando un semplice server web come nell’esempio di oggi, possiamo quindi:

  • una volta ricevuta la richiesta, inviare un pacchetto di ACK per confermare l’avvenuta ricezione
  • spezzare la risposta in più pacchetti, ognuno contenenti solo il flag di ACK
  • inviare l’ultimo pacchetto con i flag di ACK e di FIN

I metodi che andremo ad utilizzare sono:

ether.httpServerReplyAck();

invia un pacchetto contenente il solo ACK

ether.httpServerReply_with_flags(size, flags);

invia un pacchetto di dimensioni size con i flags indicati.

Nella prossima pagina analizzeremo lo sketch Arduino…

Pagine: 1 2

15 Comments »

  1. Ruben 20/09/2014 at 14:12 - Reply

    Ciao Luca
    Ti ringrazio per i tutorial sull’utilizzo dello shield enc28j60. Li ho seguito tutti e devo dirmi mi hanno molto aiutato a comprendere meglio la library ethercard, cosa non facile se parti dal loro sito. Avevo iniziato ad utilizzare il modulo con la library UIPEthernet, ma ho trovato molti problemi di freeze della scheda. Sto lavorando con una arduino uno e uno shield IE del ITEAD.
    Sto sviluppando un primo progetto di controllo della caldaia attraverso una pagina web. Ho iniziato impostando un client che postava e leggeva dati dal mio server, ovvero arduino riceveva istruzioni in base ai parametri che passava al server.
    Ho trovato pero’ problematico il fatto che il client dovesse leggere il server ad ogni loop per vedere se vi fossero nuove istruzioni. Cosi’ ho pensato fosse meglio impostare un server all’ascolto di una nuova richiesta da un client, e qui mi sono tornati molto utili i tuoi tutorial. Tuttavia ho notato che: 1. Nonostante il server e’ in attesa di una richesta da un client, i due comandi ether.packetreceived e ether.packetloop, venendo richiamati ad ogni esecuzione dal loop, apparentement fanno riscaldare, e non poco il chip e, 2. Di tanto in tanto il programma (molto semplice, che dire) si blocca ed e’ necessario riavviare la scheda ( forse impostero’ un watchdog x rilevare blocchi nel codice?).
    Secondo te, quale soluzione e’ migliore e piu’ robusta? Ovvero un client oppure un server?
    E’ chiaro che non ci si puo’ permettere una soluzione che richiede costanti riavvi della scheda per blocchi del programma, anche se questi riavvi avvengano, si fa per dire, una volta alla settimana. Ti ringrazio in anticipo per la tua risposta.
    Ruben

    • luca 22/09/2014 at 19:17 - Reply

      Ciao Ruben,

      sicuramente l’approccio di far fare da server ad Arduino è più “lineare”… onestamente non ho mai riscontrato problemi di surriscaldamento del chip (quale? l’atmega o l’enc28j60?) temo che questo possa anche influire sui blocchi (anche qui ho un arduino+enc28j60 che da mesi è acceso senza blocchi)… sicuro che sia tutto collegato correttamente? Usi uno shield o un modulo esterno? Che sia in qualche modo difettoso?

  2. Ruben 25/09/2014 at 13:50 - Reply

    Grazie Luca per la tua risposta
    sto utilizzando uno shield posto sopra una scheda Arduino Uno, quindi non ci sono collegamenti volanti. Quando parlo di surriscaldamento mi riferisco al chip enc. nella fattispecie sto provando un semplice sketch che prevede all’inizio un aggiornamento dell’ora attraverso il tuo programmino ntp, quindi ogni volta che viene interrogato da un client restituisce data e ora.
    Ma la vera soluzione all’architettura web di una scheda arduino l’ho pensata proprio ieri: ovvero utilizzare il server principale di casa su pc per interrogare a sua volta il server arduino. In questo modo posso programmare qualsivoglia pagina web sul pc combinando html e php senza intaccare la (povera) memoria dell’arduino. Che ne pensi? Puo’ essere una soluzione “furba”?
    Grazie,
    Ruben

    • luca 29/09/2014 at 07:44 - Reply

      Ciao Ruben, è strano davvero che scaldi… comunque la tua soluzione è ottima se hai a disposizione un server di appoggio: puoi interrogare Arduino solo per i dati “dinamici” e lasciare al server di casa la gestione del resto del sito

  3. jmv 27/09/2014 at 12:54 - Reply

    very good luca, waiting the next tut, thanks!

  4. tech 29/09/2014 at 14:39 - Reply

    ciao Luca,complimenti per i tuoi tutorial.
    Sto progettando un lettore rfid che legge dalla carta il seriale e lo invia ad un database mysql.

    sulla parte php residente sul server non ho problemi mentre ho dei problemi sull’invio della stringa da arduino al server.

    utilizzo una enc28j60 con la libreria ethercard.

    supponendo che ho una stringa da inviare( ad esempio codiceLetto=”abcefg”) mi potresti fare un esempio di come inviarla correttamente?

    ho costruito nel mio server una pagina php che riceve in ingresso una variabile

    $id=$_POST[‘codiceLetto’]
    echo $id;

    ho provato con vari metodi come browseUrl, httpPost ma non riesco a farli funzionare bene. Ho ottenuto un indirizzo ip da arduino e quindi la connessione funziona ma al server non arriva niente.

    potresti darmi una mano?
    ti ringrazio anticipatamente

    • luca 29/09/2014 at 19:00 - Reply

      Ciao! E’ più facile usando GET che POST, tanto per te lato php è uguale… se guardi il mio esempio 14 faccio proprio quello che serve a te: invio un valore (nel caso è una temperatura ma non cambia nulla) ad una pagina php

      • tech 30/09/2014 at 12:35 - Reply

        piccolo edit:
        ho provato a sniffare la rete ma non passa nessuna richiesta http, solo una connessione tcp da arduino al server

        • luca 30/09/2014 at 12:44 - Reply

          ciao, ma hai usato lo sketch del mio esempio?

          • tech 30/09/2014 at 13:00 -

            si, con il tuo sketch non mi crea il file csv e inoltre con wireshark vedo che non passa nessuna richiesta.

  5. tech 30/09/2014 at 00:57 - Reply

    ciao ho provato a seguire il tuo tutorial ma con zero risultati, il file csv non viene creato e anche se lo creo io non viene riempito di nessun valore.
    potresti farmi un esempio semplice semplice di come spedire una stringa e riceverla su un server php?

  6. Ruben 01/10/2014 at 09:46 - Reply

    Ciao Luca
    grazie delle tue risposte e commenti. Ora tutto sta funzionando correttamente, tuttavia ho notato che in presenza delle righe di comando
    word pos=ether.packetLoop(ether.packetReceived)
    if (pos)
    non è possibile fare eseguire ad Arduino altri comandi al di fuori della comunicazione tcp. Ovvero nella fattispecie io sto rilevando una temperatura da sensore DS18, ma se questa rilevazione avviene nel loop principale del programma, allora il server smette di funzionare, ovvero non risponde più. L’unico modo che ho trovato per far funzionare il tutto è inserire le due/tre righe di lettura della temperatura all’interno del if(pos). Ogni altro tentativo mi blocca il server, ovvero non riesce più a rispondere.
    Come si può risolvere questo (apparente) conflitto?
    Ti ringrazio in anticipo
    Ruben

  7. Pavel 18/11/2014 at 23:51 - Reply

    Hello.
    Sorry for my bad English.
    I have a question.
    Could you make a tutorial based on several html pages. For example index.html, sensors.html, leds.html.

    How this can be done?

    Thanks in advance

    • luca 19/11/2014 at 10:20 - Reply

      Hi Pavel, did you read my latest tutorial (SDWebServer)? It can publish an arbitrary number of HTML pages, stored on an SD card.
      bye

  8. Danny 24/11/2014 at 09:38 - Reply

    Ciao,
    anche a me l’ENC si surriscaldava e ho risolto comprando un modello cinese che sembra più stabile.
    Quando si scaldava andava in blocco totale. Ora sto lavorando con la scheda WZ5100, che è molto più stabile, ma i tuoi tutorial mi hanno aperto la mente su molti problemi. Grazie!

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi