Arduino
The sketch is available on Github.
The sketch sends to the client an image, split into multiple packets. The image was converted in byte array using the bin2h utility already presented in a previous example and saved in the like.h file:
As soon as the Arduino receives a new request from the user’s browser, it sends an ACK packet:
ether.httpServerReplyAck(); |
In a while loop, the image is then split into blocks, each of 500 bytes (PAYLOAD_SIZE). Each block is copied (using memcpy_P because of thebyte array is stored in the PROGMEM) in the ethernet buffer and sent.
If it is sending the latest packet, this includes both the ACK and FIN flags:
ether.httpServerReply_with_flags(size, flags); |
otherwise the packet is sent with only the ACK flag, to keep the connection open:
else { memcpy_P(ether.tcpOffset(), like + like_index, PAYLOAD_SIZE); ether.httpServerReply_with_flags(PAYLOAD_SIZE, TCP_FLAGS_ACK_V); Serial.print(" -> sent packet "); Serial.println(packet_count); like_index += PAYLOAD_SIZE; packet_count += 1; } |
A test shows that the browser is able to receive all the image segments and to show it correctly:
Thanks to a network sniffer (Wireshark) you can also verify that all the packets are sent as programmed:
Conclusions
The ability to send fragmented data allows to write very flexible and powerful sketches… in this post you learned the theory behind and a very basic example (the image is hardcoded in the sketch).
In the next tutorial I’m going to show you how to develop a webserver that reads data from an external memory.
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
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?
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
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
very good luca, waiting the next tut, thanks!
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
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
piccolo edit:
ho provato a sniffare la rete ma non passa nessuna richiesta http, solo una connessione tcp da arduino al server
ciao, ma hai usato lo sketch del mio esempio?
si, con il tuo sketch non mi crea il file csv e inoltre con wireshark vedo che non passa nessuna richiesta.
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?
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
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
Hi Pavel, did you read my latest tutorial (SDWebServer)? It can publish an arbitrary number of HTML pages, stored on an SD card.
bye
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!