enc28J60 and Arduino (18)

by luca
15 comments

In the last months, important improvements to the Ethercard library have been made and it’s now possible to send data divided in multiple TCP packets: let’s see how to do it…

A bit of theory

Internet communications leverage a stack of protocols, that is a group of different protocols, each specialized to do a particular job. During the transmission, a protocol creates its data packet and sends it to the lower protocol, until it reaches the protocol that handles the physical layer, which translates the data into electrical signals and sends them through the cable:

tcp_stack

At each step, the packet is enriched with the information necessary to the different protocols for doing their jobs. In addition, each protocol may fragment a packet from the protocol above in multiple packets.

When you access an Internet site, your browser uses the HTTP protocol to communicate with the target webserver. The request is then encapsulated within one or more TCP packets, which are then included in packets by the lower protocols until they are sent on the network. When they reach the server, they are in turn processed by the protocols in the reverse order, until the original request is passed to the webserver application that “understands” the HTTP protocol:

http_flow

If the browser‘s request or the response from the webserver contains a huge number of bytes, the TCP protocol can fragment the data in multiple packets. Each TCP packet contains some flags, that are fields that carry information for the receiver. For each packet correctly received, a confirmation ACK is sent, while the last packet of a transmission has the FIN flag set to 1, to indicate the end of the transmission.

Ethercard

The Ethercard library now offers the ability to forge packets specifying which TCP flags they contain.

If we are developing a simple web server, like in today’s example, we can therefore:

[checklist]

  • when the request is received, send an ACK packet to confirm the correct reception
  • split the response in multiple packets, each one of them containing only the ACK flag
  • send the last packet with both ACK and FIN flags

[/checklist]

The methods we’re going to use are:

ether.httpServerReplyAck();

sends an ACK packet (without data)

ether.httpServerReply_with_flags(size, flags);

sends a packet with size bytes and the specified flags.

in the next page, I’m going to analyze the Arduino’s sketch

Related Posts

15 comments

Ruben Saturday September 20th, 2014 - 02:12 PM

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

Reply
luca Monday September 22nd, 2014 - 07:17 PM

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?

Reply
Ruben Thursday September 25th, 2014 - 01:50 PM

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

Reply
luca Monday September 29th, 2014 - 07:44 AM

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

Reply
jmv Saturday September 27th, 2014 - 12:54 PM

very good luca, waiting the next tut, thanks!

Reply
tech Monday September 29th, 2014 - 02:39 PM

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

Reply
luca Monday September 29th, 2014 - 07:00 PM

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

Reply
tech Tuesday September 30th, 2014 - 12:35 PM

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

Reply
luca Tuesday September 30th, 2014 - 12:44 PM

ciao, ma hai usato lo sketch del mio esempio?

Reply
tech Tuesday September 30th, 2014 - 01:00 PM

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

tech Tuesday September 30th, 2014 - 12:57 AM

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?

Reply
Ruben Wednesday October 1st, 2014 - 09:46 AM

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

Reply
Pavel Tuesday November 18th, 2014 - 11:51 PM

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

Reply
luca Wednesday November 19th, 2014 - 10:20 AM

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

Reply
Danny Monday November 24th, 2014 - 09:38 AM

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!

Reply

Leave a Reply to luca Cancel Reply

19 + 14 =