Probabilmente sei tra gli appassionati che hanno già letto il mio articolo su Arduino Ethernet e SD Card, e probabilmente come altri che mi hanno scritto ti sei chiesto se è possibile realizzare un piccolo WebServer in grado di gestire più pagine e non solo la home …
… eccoti accontentato 🙂
Ti mostro oggi uno sketch con cui puoi gestire più pagine e fare anche qualche cosa in più 😆
Come nel precdente articolo anche in questo caso le pagine che lo sketch carica sono sulla SD Card da 2Gb inserita nello slot della Ethernet Shield:
in questo modo è più facile fare le modifiche alle pagine inserendo la scheda di memoria nel tuo computer o mac per costruire le tue pagine web e poi spostarla nella shield per farle eseguire al server.
Curiosità: mi sono accorto solo nel realizzare questo tutorial che la Ethernet Shield ha un adesivo sul retro con 6 numeri esadecimali separati da un trattino, questa notazione è tipica dei Mac Address, ho inserito questo numero sul sito: http://www.coffer.com/mac_find/?string=90-A2-DA-00-5A-82 dove il numero 90-A2-DA-00-5A-82 è quello che ho letto sull’etichetta ed ho scoperto che il vendor è: GHEO SA una azienda svizzera:
ed ecco il Mac Address della mia shield:
a cosa serve questa info? Io ho pensato di modificare il mio sketch inserendo come mac address quello della scheda, in generale anche inserire un Mac Address inventato non da problema, potresti incontrare dei problemi se la tua Arduino Ethernet Shield fosse connessa direttamente ad Internet senza passare per un router o altro dispositivo, in tal caso i Mac Address nel Web devono essere univoci per questo sono composti da 6 numeri, i primi 3 indicano il vendor (produttore) ed i secondi 3 indicano un numero progressivo che il produttore assegna a ciascuna scheda.
Lo sketch del miniWebServer è il seguente:
#include <SPI.h> #include <Ethernet.h> #include <SD.h> #define maxLength 25 byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x5A, 0x82 }; byte ip[] = { 192,168,2,130 }; File htmlFile; EthernetServer server(80); void setup() { Ethernet.begin(mac, ip); server.begin(); if (!SD.begin(4)) { return; } } void loop() { char* file_to_load = "home.htm"; String inString = String(maxLength); EthernetClient client = server.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (inString.length() < maxLength) { inString += c; } if (c == '\n' && currentLineIsBlank) { if (inString.indexOf(".htm") > -1) { String new_file_load; int rootIndex = inString.indexOf("/"); new_file_load = inString.substring((rootIndex+1), (rootIndex+13)); int endIndex = new_file_load.indexOf(" "); if (endIndex > -1) { new_file_load = new_file_load.substring(0, endIndex); } if (new_file_load != "") { new_file_load.toCharArray(file_to_load,12); } } client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); read_file( "header.htm",client ); read_file( file_to_load,client ); read_file( "footer.htm",client ); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } } void read_file( char* page_html, EthernetClient client ) { htmlFile = SD.open( page_html ); if (htmlFile) { while (htmlFile.available()) { client.write(htmlFile.read()); } // close the file: htmlFile.close(); } }
rispetto al precedente sketch che hai visto ci sono alcune differenze che ti mostro nel dettaglio:
linea 05: definisci una costante maxLength di 25 sarà la costante su cui si basa l’oggeto String per l’istanza inString che vedrai nelle righe succesive;
linea 07: nota il mac address che ho inserito è quello della mia scheda, puoi sostituirlo con il tuo;
le linee successive relative a Ip, File, sono identiche;
linea 10: l’oggetto Server nella versione dell’IDE 1.0 è cambiato in EthernetServer per cui ho adeguato il codice;
la funzione setup() è invariata;
linea 21: all’interno della funzione loop() definisci una variabile di tipo char* in cui inserisci il nome della prima pagina in caso non sia specificata alcuna pagina da chiamare, ricorda che i file devono essere sempre del tipo 8.3 ( 8 caratteri per il nome, un punto e 3 caratteri per l’estensione)
linea 22: definisci l’istanza dell’oggetto String, chiama questa instanza inString e ci memorizzerai l’url chiamato, è importante che sia di tipo String così che tu possa usare tutti i metodi di manipolazione delle stringhe offerti da Arduino;
linea 24: come la Server anche la classe Client è stata sostituita con la EthernetClient nell’IDE 1.0;
le righe successive sono identiche a quelle già viste;
linee 30-32: questa condizione è nuova ed assegna alla variabile inString il risultato letto dal metodo read() della classe EthernetClient; in pratica assegna i valori di Header letti dalla chiamata del Browser;
linee 34-46: qui si compiono i giochi per far funzionare il tuo miniWebServer con Arduino, ecco cosa fa lo sketch linea per linea:
linea 34: usa il metodo indexOf() della classe String cercando il testo “.htm” sai che ogni file deve avere una estensione di tipo .xxx dove le tre x sono i tre caratteri dell’estensione, l’estensione tipica delle pagine HTML in notazione di tre caratteri è htm per cui tutte le tue pagine saranno .htm; il metodo indexOf(“.htm”) restituisce la posizione del valore cercato nella stringa e -1 se non lo trova per cui in questa riga se trova .htm entra nella condizione if. A cosa serve? la prima volta ti collegherai al tuo server solo con l’IP senza specificare nulla, a questo punto la condizione di if viene evitata e la pagina di default ( vedi linea 21 ) diventa la pagina chiamata, dalla seconda chiamata in poi la nuova pagina avrà estensione htm e ti farà entrare nella condizione if;
linea 35: definisci una nuova istanza della classe String;
linea 36: con il metodo indexOf cerca la prima occorrenza del carattere “/” siccome l’url è composto da http://192.168.2.130/[pagina].htm l’header conterrà una stringa simile alla seguente: 25GET /home.htm HTTP/1.1 dove la parte http://192.168.2.130 non è riportata e l’Url parte da /home.htm, trovato il carattere “/” sai dove inizia il nome della pagina da chiamare;
linea 37: assegna all’istanza new_file_load definita alla linea 35, il valore risultante dall’operazione di substring, il metodo substring( inizio, fine) estrae da una stringa una sua parte dal numero di carattere definito come inizio fino al numero di carattere definito come fine;
linea 39: nella stringa appena estratta new_file_load potrebbero esserci caratteri vuoti che determinano la fine della linea, questo perchè le pagine possono avere nomi di 12 caratteri ( 8.3 => 8+1+3 = 12 ) ma possono anche averne meno, in tal caso dopo aver tagliato i 12 caratteri massimi attesi verifica se ci sono spazi;
linea 40: controlla il risultato della indexOf precedente;
linea 41: estrae la parte della stringa dal carattere numero 0, inizio, fino al carattere spazio trovato;
linea 43: un ultimo controllo ti assicura che dopo tutti i tagli eseguiti esista ancora un nome pagina da chiamare;
linea 44: assegna la stringa estratta alla variabile file_to_load definita alla linea 21; per farlo utilizza il metodo toCharArray( istanza, numero di caratteri) questa operazione è necessaria in quanto new_file_load è di tipo String mentre file_to_load è di tipo char* e le funzioni che chiameremo dopo vogliono che il valore passato sia di tipo char*, per saperne di più sulla conversione String2char leggi i miei articoli: Tutorial Arduino e le stringhe e Tutorial Arduino e le stringhe II
linee 48-50: sono invariate, impostano gli header di risposta per il Browser;
linee 52-54: sono identiche ma il loro scopo è ben preciso, tutte chiamano una pagina ma la prima e l’ultima chiamano una pagina definita e fissa che deve chiamarsi header.htm e footer.htm in queste due pagine potrai mettere intestazione e pié pagina fissa per tutte le pagine Html, ho fatto questo introducendo il concetto di pagina inclusa, se programmi in linguaggi come php, asp o altro conosci già questo trucco utilizzato per semplificare la vita del programmatore. In pratica le parti comuni di un sito, come ad esempio l’intestazione ed il pié pagina si scrivono una sola volta e le si includono in tutte le altre pagine, in questo modo se devi fare una modifica all’intestazione non dovrai modificare tutti i file del sito ma solo l’intestazione. In questo esempio ho voluto che fosse lo sketch a fare per te questa operazione per cui chiama in sequenza: l’intestazione ( header.htm ), la pagina che hai chiesto ( vedi linee 34-46 ) ed infine la chiusura pagina ( footer.htm );
linee 55-69: sono invariate;
linea 71: definisci la funzione richiamata alle linee 52-54, tale funzione deve accettare in ingresso 2 parametri: il primo è la pagina da chiamare, il secondo è l’istanza dell’oggetto Client con cui rispondere al browser;
linea 73: varia rispetto al precedente sketch solo per il nome del file chiamato che viene ripreso dal primo parametro passato alla funzione;
linea 76: c’è un piccolo cambiamento dovuto alla variazione della classe EthernetClient che non supporta più l’opzione BYTE nel metodo print per cui ho cambiato con il metodo write che non soffre il problema della codifica caratteri.
Tutte le righe non descritte non sono variate.
Ed ecco i file che io ho utilizzato nel mio Sketch, puoi scaricarli qui, poi decomprimi il file zip e metti tutti i file nella memory card senza cartelle o path, metti la memory card nella ethernet shield e premi il pulsante reset prima di collegarti con un browser.
Io mi ci sono collegato con il mio iPhone 3G ed ho catturato alcune schermate:
Buon divertimento.
155 commenti
1 ping
Vai al modulo dei commenti
Ciao, come faccio sfruttando questo progetto integrare dei comandi ad esempio di accensione e spegnimento di un led passando i parametri mendiate url? Ho provato a modificare il codice ma non sempre funziona.
Autore
Ciao Enzo,
hai provato a cercare nel blog se ci sono esempi che fanno al caso tuo?
Io ricordo di aver scritto qualcosa di simile: https://www.mauroalfieri.it/elettronica/tutorial-arduino-led-rgb-via-web.html
Prova a vedere se fa al caso tuo.
Mauro
Salve
Ho visitato alcune pagine del sito, molto interessante!
Vorrei chiederle una cosa riguardante proprio l’Ethernet Shield. Ebbene, io ho una SD che ha, in root, un file “index.htm” ed una cartella “css” la quale contiene un file, “Style.css”. Ora, dopo averla inserita sull’Ethernet Shield e aver caricato il relativo programma, tramite il quale alla richiesta invia il file “index.htm”, interrogo il Server da pc. Dopo l’interrogazione, la pagina rimane bianca. Le allego il codice della pagina index.htm
Arduino Ethernet Shield
Ciao, sono l’Ethernet Shield
di Arduino!!
e quello di Arduino
#include
#include
#include
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 130 };
File htmlFile;
Server server(80);
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
if (!SD.begin(4)) { return; }
}
void loop()
{
Client client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == ‘\n’ && currentLineIsBlank) {
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println();
htmlFile = SD.open(“index.htm”);
if (htmlFile) {
while (htmlFile.available()) {
client.print(htmlFile.read(), BYTE);
}
// close the file:
htmlFile.close();
}
break;
}
if (c == ‘\n’) {
currentLineIsBlank = true;
}
else if (c != ‘\r’) {
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}
che come vede, è preso direttamente da una delle pagine del sito 🙂
La mia domanda è: quando restituisce la pagina “index.htm”, di default invia anche “Style.css”? Se no, come penso, come devo modificare il codice affinche lo faccia?
Grazie
Autore
Ciao Mirco,
Hai intuito bene, la Ethernet Shield ed Arduino non inviano di default tutti i file come fai con un web server tradizionale, devi scrivertelo tu.
Come comprenderai non si tratta di 2 righe di codice scrivere un web server. Il modo più semplice che hai è inserire i cas nella pagina index.htm se non vuoi ti consiglio di cercare e provare dei web server già pronti x arduino.
Prossimamente lo farò anche io e scriverò qualche articolo sui web server disponibili.
Mauro
ciao, una piccola curiosità, e possibile avere un immagine sulla SD e mandarla via internet a un form?
mettiamo caso che l’immagine ha 100 kb, posso mandarla via ethernet? anche se l’immagine ha una dimensione maggiore della memoria di arduino? avevo letto da qualche parte che è possibile usare solo la ethernet shield o la microSD, uno alla volta.
spero che hai avuto a che fare con qualche storia simile 🙂 grazie mille
Autore
Ciao Leonid,
purtroppo no, non mi è mai capitata l’esigenza.
Ti invito a cercare un web server scritto per arduino per non doverlo scrivere tutto tu.
Sull’uso alternato della SD rispetto alla Ethernet ciò che hai letto si riferiva all’impossibilità di usarle nello stesso istante a causa della concorrenza non gestita da arduino, penso, ma puoi utilizzarle nello stesso sketch senza problemi, io lo faccio spesso e trovi dei tutori al miei su questo argomento nel blog.
Mauro
si, ho capito questo, ho usato anche io entrambe nello stesso sketch, però pensavo che per mandare un’immagine dovrei passarla per arduino o posso mandarla direttamente dalla microSD?
grazie, bello il blog
Autore
Ciao Leonid,
Nella comunicazione Ethernet tutto ciò che arriva al client è processato dal server, si tratti di immagini, cas, js o html.
Per inviare un elemento via web devi avere un web server che faccia per te il la vero di codifica e streaming, con arduino puoi scrivertelo tu se vuoi, o cercare un web server già pronto e a disposizione della community.
Se hai dubbi su come funziona un web server e cosa fa ti invito a cercare sul web, molti siti ne parlano.
Mi sono ripromesso di scrivere un articolo sulla comunicazione Ethernet pechiare chiarezza su cosa sia da scrivere e cosa arduino fa già da solo.
Mauro
Ciao A tutti. volevo ringraziare l’autore del sito per i consigli utili. Per quanto riguarda
l’inserimento di immaggini ho modificato il codice come segue: (ho inserito dei commenti per capire il codice). Sarebbe da affinare per ora è solo da considerarsi una prova.
#include
#include
#include
#define maxLength 25
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x5A, 0x82 };
byte ip[] = { 10,0,0,200 };
File htmlFile;
EthernetServer server(80);
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
if (!SD.begin(4)) { return; }
Serial.begin(9600);
}
void loop()
{
char* file_to_load = “home.htm”;
String inString = String(maxLength);
String inStringHtml = “text/html”;
String inStringJpeg = “image/jpeg”;
String MIME= inStringHtml;
EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
//se la stringa non ha syperato il massimo consentito 25??
if (inString.length() -1) {
String new_file_load;
int rootIndex = inString.indexOf(“/”);
new_file_load = inString.substring((rootIndex+1), (rootIndex+13));
int endIndex = new_file_load.indexOf(” “);
if (endIndex > -1) {
new_file_load = new_file_load.substring(0, endIndex);
}
if (new_file_load != “”) {
new_file_load.toCharArray(file_to_load,12);
}
MIME=inStringHtml;
// Serial.println(“sono entrato dentro l’if HTML”);
}
if (inString.indexOf(“.jpg”) > -1) {
String new_file_load;
int rootIndex = inString.indexOf(“/”);
new_file_load = inString.substring((rootIndex+1), (rootIndex+13));
int endIndex = new_file_load.indexOf(” “);
if (endIndex > -1) {
new_file_load = new_file_load.substring(0, endIndex);
}
if (new_file_load != “”) {
new_file_load.toCharArray(file_to_load,12);
}
MIME=inStringJpeg;
delay(1);
// Serial.println(“sono entrato dentro l’if JPEG!”);
}
//Se non è entrato nel ciclo file_to_load è quello di default prima volta
//In pratica per la prima connessione tutto il lavoro fatto per le stringhe è inutile
//basta solo rilevare un doppio // e un client connesso sulla porta per spedire la pagina
//MEssaggio di risposta che manda in caso di pagina web questa risposta (da modificare in caso di mmagini con “Content-Type: image/jpeg”)
// Serial.println(“Content-Type: ” + MIME);
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: ” + MIME);
client.println();
MIME=inStringHtml;
// read_file( “header.htm”,client );
// Serial.println(file_to_load);
read_file( file_to_load,client );
// read_file( “footer.htm”,client );
break;
}
if (c == ‘\n’) {
currentLineIsBlank = true;
}
else if (c != ‘\r’) {
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}
void read_file( char* page_html, EthernetClient client )
{
htmlFile = SD.open( page_html );
if (htmlFile) {
while (htmlFile.available()) {
client.write(htmlFile.read());
}
// close the file:
htmlFile.close();
}
}
Autore
Grazie Andrea per aver condiviso il tuo lavoro con tutti noi, proverò anch’io questo tuo sketch quanto prima.
Mauro
Ciao Mauro, ti seguo costantemente sul tuo sito e lo trovo un ottimo spunto per idee e spunti per i miei progetti con Arduino.
Ho da chiederti 2 cose:
– dovendo creare un web server con pagine html caricate su sd, hai mai implementato un “sistema” di login?
– se volessi utilizzare dei pulsanti che lampeggiano o che altro, l’unica soluzione è utilizzare la libreria tiny web server? Tu l’hai mai utilizzata?
Ti ingrazio anticipatamente per la tua disponibilità
Buon pomeriggio
Nicola
Autore
Ciao Nicola,
Non ho mai implementato un vero web server su arduino, so che il tiny web server che tu citi mette a disposizione una versione base di un web server e ti offre già una serie di metodi con cui comandare le uscite digitali di arduino.
Purtroppo non ho mai sperimentato questa strada, se fai dei test e ti occorre aiuto provo comunque a darti delle dritte.
Mauro
Ciao Mauro
Sei sempre una miniera di informazioni.
Su questo tutorial ho scoperto quel sito che ricerca i mac address. E visto che a casa ho una schiera di dispositivi con mac address, mi sto divertendo a scoprire di più per ogni dispositivo.
Buona giornata
ciao Mauro
volevo chiederti le 3 pagine che hai visualizzato
sono sull’ SD come faccio io a creare queste pagine ?
ho bisogno di un programma apposta?
di qualcosa in particolare ??
grazie
Macca96
Autore
Ciao Macca96,
io ho usato vi di linux e scritto in HTML, ma puoi utilizzare un editor gratuito che ti piace.
Mauro
grazie ho trovato il programma Rj textEd
è semplice e riesco a capire
volevo chiederti
se si poteva stampare nelle varie pagine i valori non so della temperatura, accensione led ecc…
non so come fare i riferimenti alle varie pagine
è possibile??
grazie per tutto
macca96
Autore
Ciao Macca,
si é possibile.
Siccome Arduino non dispone di un web server devi far in modo c’è quando un valore arriva ad arduino e vuoi inserirlo in una pagina sia tu a scriverlo in HTML usando le funzioni String di Arduino.
Ho scritto qualche tutorial su queste funzioni, prova a leggerlo, non sono semplici ma neppure impossibili da usare.
Mauro
grazie ho creato un progettino usando anche la libreria webserver
volevo chiederti ancora (sono un rompi scatole)
se è possibile comandare e leggere i valori di arduino
da un cellulare o computer ma lontano da casa
dovrei entrare nel mio router per poi scrivere l’indirizzo ip di arduino
o sbaglio??
grazie
Macca 96 🙂
Autore
Ciao Macca,
si puoi ma devi consentire al tuo router di inoltrare la porta su cui ti risponde arduino al tuo cellulare e dovresti possedere anche un IP statico o configurarti un servizio di Dynamic DNS.
Mauro
ok grazie
ho creato un servizio di Dynamic DNS
sono andato su no-ip e ho eseguito le operazione e adesso
ho una specie di sito da provare che mi dovrebbe collegare al mio ruter adesso proverò
ho detto giusto??
grazie
macca96
Autore
Ciao Macca,
corretto.
Mauro
ciao Mauro vorrei chiederti un aiutino,ho creato uno stretch con arduino che si collega a una pagina html dove ci sono dei pulsanti che comandano relè, la pagina in questione si trova su arduino ma io vorrei spostarla sulla SD in modo da poterla migliorare graficamente come posso fare ? grazie
Autore
Ciao Michele,
in questo articolo è spiegato proprio quello che ti occorre.
Hai provato a seguire le mia indicazioni riportate nella spiegazione dello sketch ?
Mauro
ok me lo leggo tutto per bene e vedo come poterlo adattare grazie tante.
ciao Mauro volevo chiederti un’altra cosa, io accedo ad arduino tramite dyndns io vorrei però proteggere la pagina con password, ne senso che prima di accedere alla pagina completa dovrei digitare la password, mi potresti aiutare ? grazie per la tua disponibilià
Autore
Ciao Michele,
quello che ti occorre è impostare l’autenticazione http, non ho mai provato con Arduino.
Prima ti consiglio di provarla nella tua pagina con un webserver classico ( apache, IIS, lightHttp ) e solo quando funziona puoi provare a portarla su Arduino, dove dovrai scriverti tutto il codice per utilizzarla.
Mauro
ciao scusa sto cercando di fare qualcosa del genere…solo che in piu vorrei metterci il comando di led.. l’utilizzo di sensori ecc quello penso non sia un problema.. basta capire come scrivere e leggere sulla sd credo … il problema pero e che non capisco come hai fatto a farlo funzionare questo sketch…posso chiederti se potresti commentare so sketch cosi vedo se riesco a capirlo e me lo studio bene? grazie mille in anticipo saluti ^^:)
Autore
Ciao Davide,
se leggi l’articolo ti accorgerai che lo sketch è commentato linea per linea subito sotto.
Scrivo i tutorial proprio per spiegare come funzionano anche se spesso mi rendo conto che molti
copiano e incollano il codice senza leggere nulla di quello che scrivo.
Mauro
Ciao, innanzitutto complimenti per il blog, ci sono davvero un sacco di informazioni utili.
E’ da un pò che cerco informazioni per poter visualizzare in una pagina web salvata su SD il valore di una variabile dello sketch di Arduino ma, complice la mia scarsa conoscenza di http, non sono riuscito a capire bene come potrei fare. Inoltre vorrei sapere se fosse possibile leggere un file su SD via web…
Temo siano cose oltre le mie competenze, ma ultimamente ho imparato tanto e potrei imparare anche questa!
Grazie in anticipo…
Autore
Ciao Maurizio,
tutto si può imparare, basta buona volontà.
Se spulci tra i commenti a questo articolo troverai già la risposta al tuo primo quesito.
Quando dico risposta non intendo lo sketch già fatto.
Devi lavorare con le Stringhe e sostituire ad un “segnaposto” che metti nell’HTML il valore che leggi dal sensore.
Per la seconda domanda puoi leggere quello c’è vuoi da SD e visualizzarono via Ethernet purché:
A) sia un file che inviato su un browser possa essere visualizzato, es.: immagine, pdf, swf
B) devi scriverti tutto il sw lato arduino in grado di farlo xchè di base arduino non ha un suo web server pronto, puoi cercare un webserver già fatto e usarlo per il tuo progetto.
Mauro
Grazie per le risposte, tuttavia non mi sono chiare un paio di cose, credo a causa della mia scarsa dimestichezza con l’html.
io dovrò scrivere nell’html un pezzo di sketch arduino? o è possibile richiamare la pagina (es. index.htm) aggiungendo delle stringhe che saranno i valori della mia variabile? Ho letto la risposta a Macca, ma non sono in grado di capirla bene… 😛
Crede sia possibile passare dei file .txt ? Magari salvandoli direttamente nel pc (più dura credo….)?
Grazie ancora per la disponibilità
Maurizio
Autore
Ciao Maurizio,
non preoccuparti, nell’HTML ci metti un segnaposto es.:
TEMPERATURA
E nel codice Arduino sostituisci a stringa con il valore letto dalla sonda o da dal pin che vuoi.
Per il file .txt non comprendo cosa tu voglia ottenere, raccontarmi l’obiettivo di quello c’è sai realizzando, magari esiste un modo semplice di realozzarlo.
Mauro
Ho risolto la prima parte! Ci ho messo un pò, ma studiando la lettura della SD e l’invio dei dati al client, sono riuscito a isolare una stringa utilizzando dei caratteri speciali. Poi interpreto la stringa e invio al client quello che voglio…
Autore
Grande Maurizio,
se ti va di condividere la tua esperienza io sarò felice di pubblicarlo.
Inviami foto,video,schemi,testi e sketch ( insomma tutto il materiale che ritiene utile) al l’email info del blog.
Sono sicuro c’è a molti darai un grande contributo.
Mauro
Ecco lo sketch. In realtà ho solo modificato un pò uno sketch trovato in rete (ora non ricordo dove, probabilemte è proprio tuo :P) inserendo i controlli di cui sopra. Mi sono accorto che anche l’utilizzo della variabile a definita come int e la successiva conversione in char probabilente è superflua, bastava definirla subito come char, ma ora non ho l’Arduino con me per verificarlo…
Comunque lo sketch funziona, basta inserire nel file index.htm la stringa “¿maury¿” per vederla sostituita con la scritta “pincopallo” nella pagina visualizzata dal browser.
Spero di poter essere d’aiuto ad altri nello spirito open e di Arduino!
#include
#include
#include
byte mac[] = {inserire il mac};
byte ip[] = { inserire l’ip };
byte subnet[] = { inserire la subnet mask };
String lista=””;
File htmlFile;
EthernetServer server(80);
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac);
server.begin();
if (!SD.begin(4)) { return; }
}
void loop()
{
EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == ‘\n’ && currentLineIsBlank) {
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println();
int a=-1;
htmlFile = SD.open(“index.htm”);
if (htmlFile) {
while (htmlFile.available())
{
a=(htmlFile.read());
if (a==191) // se il carattere letto da SD è ¿ (alt+168)
{
a=-1; // inizializzo nuovamente la variabile
while (a!=191) // finchè non leggo un altro carattere speciale
{
a=(htmlFile.read()); // leggo un altro carattere
if (a!=191) // se è diverso dal carattere speciale (serve per non avere salvato sulla stringa l’ultimo carattere speciale)
lista+=char(a); // lo aggiungo alla mia stringa convertendolo in carattere (dalla SD leggo un int che rappresenta il codice ASCII
}
if (lista==”maury”) // (in caso di scelte multiple magari è meglio usare uno switch-case)
client.write(“pincopallo”); // invio al client la mia variabile o quello che mi pare
lista=””; // ripristino la stringa per la prossima variabile
}
else
client.write(a); // se non leggo il carattere speciale invio direttamente al client
}
// close the file:
htmlFile.close();
}
break;
}
if (c == ‘\n’) {
currentLineIsBlank = true;
}
else if (c != ‘\r’) {
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}
Autore
Grazie Maurizio sketch molto interessante.
Lo toglierò dai commenti per dedicargli un articolo 🙂
Mauro
ciao Mauro,
complimenti per il sito,
ho riscontrato un problema proprio con la trasmissione dati utilizzando l’ethernet shield in 3G (iPhone),
Ho l’arduino Due ed Ethernet shield Rev3,
in pratica io ho fatto uno sketch molto simile al tuo (e’ praticamente equivalente ad un web server) in cui dopo avere ricevuto la richiesta dal client, mando lo sream HTTP/1.1 200 OK, lo /r/n e poi una serie di dati in sequenza (senza mai il /r/n).
Accade che se i dati sono tanti (dopo i 1000 caratteri) la comunicazione viene interrotta. Me ne accorgo facendo la richiesta in telnet (mi da connection reset by peer)
ti spiego, io mando i 2000 caratteri e dopo che li ho mandati ovviamente faccio client.stop().
Accade che lo stop mi blocca la comunicazione mentre i dati non sono ancora arrivati al client. In pratica sembra che lo stop() arrivi mentre il client sta ancora bufferizzando i dati,
Lo so che sembra strano, ma il problema si risolve mettendo un delay di 500ms prima dello stop, ma questo non mi piace poiche’ tutto quello che viene dopo si ritarda,
volevo sapere se tu avevi avuto un problema simile o no,
grazie,
Andrea
Autore
Ciao Andrea,
non ho riscontrato problemi simili, é pur vero che inviare 2000 caratteri non ci ho mai provato.
La tua analisi é molto approfondita e sicuramente é di grande aiuto per tutti gli appassionati che vorranno riproporre questo progetto.
Hai provato a separare con del \r\n qualcuna delle istruzioni che invii?
Mauro
Ciao Mauro,
grazie della condivisione. Da newbie dell’html mi è stato molto utile.
Stavo integrando l’uso di header, page e footer (e anche il multipage) con aggiornamento dati da arduino con ajax.
Ho dei problemi nel visulizzare la pagina se invio al client header o footer.
mi daresti qualche consiglio?
Grazie,
Carlo
Autore
Ciao Carlo,
il mio consiglio è di non costruire pagine troppo complesse per questo progetto in quanto il server Ethernet lato Arduino non possiede interpreti come php,cgi o python ma tutto quello che vuoi costruire dinamicamente devi gestirlo nello sketch arduino.
Puoi inserire javascript e ajax che sono componenti gestite dal browser e che arduino non deve interpretare.
Mauro
ciao e complimenti per il tuo lavoro e utilissimo per tutti noi. Avrei delle domande da farti…. io vorrei farmi della domotica creando un webserver con raspberry collegato via seriale ad arduino ma il problema e’ che ne capisco poco di php e html . vorrei poi utilizzare il webserver per crearmi un applicazione per android. in rete ho trovato un progetto con il nome di ardudome ma non riesco ad adattarlo al mio progetto…. . tu che consigli?
Autore
Ciao Giovanni,
se il tuo problema é solo php e html é il meno, puoi impararli da un corso on-line in 3/4 giorni per fare quelle che occorre penso siano sufficienti.
Un progetto come il tuo richiede conoscenze di:
– Linux per Rasbian
– elettronica per adattare i segnali seriali di Raspberry ad Arduino
– impiantistica
– programmazione App per Android
– networking
E solo per citare i primi, php e HTML sono una passeggiata.
Io stesso non conosco in modo approfondito tutti questi aspetti per affrontare un progetto simile, anche se mi incuriosisce 🙂
Mauro
ciao Mauro allora un pc con Linux lo uso quindi per il raspberry non ci sono problemi…. impiantistica nemmeno… in quanto ad app android uso app inventor ho fatto già qualche applicazione una multipresa con Arduino e shield ethernet comandata da app ed un app accendere le strisce led della mia scala. farò un corso php e html….
Autore
Ciao Giovanni,
sai molte più cose di me 🙂 se ti va di condividere qualcuno dei tuoi progetti sul blog sono a disposizione per scriverti gli articoli.
Con tutte le conoscenze che hai php e html saranno una passeggiata.
Mauro
ciao mauro appena ho un po di tempo ti mando un po dei miei progetti .
Autore
Wow Giovanni,
Non vedo l’ora di riceverli 🙂
Mauro
Ciao Mauro sono Daniel e siccome sto iniziando a fare il mio primo progetto arduino basato sull’automazione di una casetta, sto cercando più informazioni possibili per fare un buon progetto(che verrà presentato in sede di esame di stato a luglio, quindi deve “spaccare” 😀 ) comunque io vorrei gestire la mia casetta tramite una pagina HTML e salvare in un database accessibile da questa pagina HTML tutte le varie informazioni recuperate dai sensori.
ho trovato il tuo articolo molto interessante ma volevo chiederti chiarimenti sull index of(“.htm”).
E se hai consigli da darmi per il mio progetto li accetto più che volentieri.
Grazie in anticipo. 🙂
Autore
Ciao Daniel,
il tuo è un progetto molto diffuso su internet e troverai certo moltissimo materiale.
Considera tuttavia che con Arduino devi scriverti quasi tutto l’interprete delle pagine, come avrai capito dal mio articolo, e non esiste database che io conosca da usare.
Puoi seguire due strade:
1 – semplificare il progetto ometterndo DB, pagine da interpretare, ecc..
2 – usare un’arduino Yun che ha già un propio server web già configurato e su cui puoi installare l’interprete php
Mauro
ciao mauro, ho provato a fare questo sketch, ma ho avuto un problema, sul pc leggo le pagine che abbiamo inserito sulla micro SD, se ci provo con il cellulare invece mi dice che non può trovare la pagina.
a cosa è dovuto?
come posso visualizzare la pagina anche sul mio smartphone?
Autore
Ciao Daniel,
devi avere lo smartphone collegato alla stessa rete del Pc, altrimenti non riuscirai a trovare la pagina che cerchi.
Mauro
lo smartphone lo collego tramite wifi alla stessa linea a cui è collegato il pc
Autore
Ciao Daniel,
se il tuo smartphone è connesso alla stessa rete del Pc e dell’arduino prova a disabilitare la connessione GSM o GPRS del cellulare, mettilo in modalità aereo e attiva solo il WiFi, potrebbe essere dovuto ad un cattivo istradamento della richiesta da parte del browser.
Mauro
niente stesso problema
Autore
Ciao Daniel,
è di certo un problema di rete in quanto il Pc riesce a connettersi alla pagina per cui ti consiglio di concentrarti sulla configurazione della rete ( smartphone/router/access point/ethernet shield )
Mauro
va bene ti ringrazio comunque per il tuo aiuto 🙂
se riuscirò a risolvere il problema ti farò sapero come ho risolto.
daniel
Autore
Ottimo Daniel,
attendo fiducioso, so che lo risolverai 🙂
Mauro
ciao mauro
mi è venuto un dubbio. l’indirizzo IP che andiamo a mettere dove lo prendiamo?
Autore
Ciao Daniel,
é un indirizzo valido sulla tua rete Ethernet, libero da altri Pc o apparati di rete ( router,mediacenter,smartphone,tablet,ecc…)
Mauro
mauro ho risolto il problema 😀 e mi rendo conto che sono stato un idio** ahah, io attaccavo il cavo ethernet tra lo shileld ethernet e il pc, ho provato ad attaccarlo all’ADSL e funziona benissimo sul cellulare ma non sul pc no..va beh a me interessa la gestione tramite cellulare che funziona perfettamente 😀
Autore
Ciao Daniel,
benissimo, era un problema di networking, sono contento.
Per il Pc controlla che sia collegato alla stessa rete di arduino e dello smartphone, magari usa il WiFi del Pc così dovresti essere sul medesimo segmento di rete ( virtuale ) dello smartphone.
Ricorda che dall’esterno di casa la faccenda si complica e ti servono alcune importanti conoscenze di rete, protocolli, dns e routing 🙂
Mauro
dove posso informarmi su tutto il necessario?
Autore
Ciao Daniel,
ti suggerire internet come punto su cui informarti, in modo specifico cerca corsi di networking on-line.
Mauro
Salve Mauro. prima di tutto complimenti per il sito. Mi chiedo cosa faremmo senza l’aiuto di gente come lei. Premetto: sono un informatico con basi di programmazione. Mi sono avvicinato ad arduino perchè lo ritengo uno strumento utilissimo. Vengo al punto. Nessun problema ad accendere un led su una pagina web creata con lo sketch. Ma io vorrei farlo da una pagina inserita nella sd. E qui sta il problema. Mettere insieme le due cose. Ha un piccolo esempio di sketch (che poi provo io)? Del tipo apro una pagina index.htm situata sulla sd. Sulla pagina clicco un link che accende un led. Grazie e buon lavoro. Luca
Autore
Ciao Luca,
purtroppo non ho uno sketch già pronto per fare quello che mi chiedi.
Tuttavia ho pubblicato anche un tutorial su come visualizzare pagine multiple presenti su una SD con arduino.
Sono sicuro che con i due tutorial e le basi di programmazione che possiedi non avrai difficoltà, del resto neanche io sono un programmatore 🙂
ciao mauro
seguo spesso il tuo blog dal quale ricavo molto utili consigli, faccio i miei sentiti complimenti per la chiarezza di espozione, che spesso rende il tutto ben comprensibile.
volevo porti una domanda:
ho modificato il tuo scheck per ottenere un web server che mi permetta di controllare degli attuatori, ma ho riscontrato un problema sul caricamento di pagine di terzo livello, mi spiego meglio
home, nessun problema –> entro in un link, ancora nessun problema (e mi trovo nella pagina di secondo livello) –> entro in un’altro link, quindi per andare ad una pagina di terzo livello, qui il dilemma
la riga 34, utilizza “indexOf” su inString (richiesta del broswer ) e restituisce l’indice di “.htm” entrando nel “if”
a questo punto si salva l’indice dello slasch “indexOf(“/”)
ma se siamo nella pagina di terzo livello, il link sará di tipo IP / seconda pagina.htm / terza pagina.htm
in questo caso index of restituisce l’indice del primo slash, e quindi carica nuovamente la seconda pagina e non la terza, giusto?
come potrei fare per caricare anche pagine di terzo livello? che ne pensi di “lastIndexOf” per trovare sempre l’indice dell’ultima slasch? ho provato a sostituirlo nella riga 36 ma snza riuscire a compilare (mi dava effore su lastIndexOf)
premessa: non conosco bene i broswer e pertanto non so se nell’indirizzo chiamato al server c’é sempre una slash finale!
spero in una rapida risposta, si tratta di tesina di maturitá
grazie in anticipo, lorenzo
Autore
Ciao Lorenzo,
l’errore a mio avviso risiede nell’url che hai indicato.
Lurl: IP / seconda pagina.htm / terza pagina.htm è sbagliato già a livello html dovrebbe essere: IP / livello1 / terza_pagina.htm dove livello 1 è una dir in cui trovi la pagina terza_pagina.htm
Ti consiglio di leggere qualche articolo su come è fatto un url html standard.
In alternativa limitati a pagine contenute nel primo livello visto che devi scriverti tutta la gestione dei path su arduino se vuoi utilizzare sottolivelli.
Ciao Mauro bel tutorial. Ho solo il problema che quando da pagina web chiamo le altre pagine, invece della normalissima pagina html, mi carica il codice tipo xml. Come mai?
Autore
Ciao Mario,
controlla il file .htm che hai salvato, deve contenere i tag prima di tutto e alla chiusura
I tag? Io però ho scaricato i file che tu hai linkato,non ho cambiato nulla
Autore
Ciao Mario,
controlla che nel copiare i file non si siano corrotti o presentino dei tag sbagliati, a volte capita.
Anch’io ho lo stesso problema di Mario: la prima pagina funziona, ma quelle aperte dai link, anziche’ mostrare la pagina, mostrano il codice ….. pero’ c’e’ qualche refuso nel contenuto.
I file HTM sono corretti, ma cio’ che vedo (e che non viene visualizzato correttamente perche’ la formattazione e’ errata) inizia cosi’:
m
Content-Type: text/html
…..
Ho il dubbio che ci sia qualche sforamento della memoria o qualche buffer birichino…. qualche idea?
Grazie e complimenti per il sito !
Autore
Ciao Emilio,
ad occhio sembra un carattere sporco nella pagina destinazione.
Prova a controllare con un browser sul tuo computer che riesca a richiamare le pagine da un disco locale copiando le pagine sul disco fisso.
Ciao Mauro, ho proseguito nella ricerca del problema e mi sono accorto che rinominando tutti i file con estensione .html (lo so che dovevo usare 8.3 ma ero disperato ! ) ottenevo il risultato che segue, dove nella prima riga trovo gli ultimi due caratteri del nome del file, mentre nella seconda riga, cio’ che mi vedo e’ proprio il contenuto della riga 49:
ml
Content-Type: text/html
Con una serie di tentativi ho determinato che rinominando tutti i file ed i relativi link in formato 4.3 non avevo piu’ alcun problema. Un problema rimane invece se ricerco una pagina che non esiste, poiche’ poi non mi viene piu’ caricata nessuna pagina.
Purtroppo non sono in grado di capire quale sia il problema del codice (o del FW ?), ma con il work-around di avere file 4.3 ho risolto il problema.
Preciso che uso Arduino Ethernet r.3 provando con lo stesso sketch pubblicato sopra.
Buon lavoro a tutti e di nuovo i complimenti a Mauro!
Autore
Ciao Emilio,
grazie per la sessione di test, effettivamente questo codice è qualche anno che non lo modifico e testo.
Rileggendolo mi sembra corretto 8.3 in quanto 8+1(.)+3 = 12 e se leggi alle linee 36-37 vedrai che individuata la / (root) parto da root+1 e conto 13 ( 12+1 ).
Se con 4.3 funziona va benissimo lo stesso, l’unica accortezza è l’estensione che deve essere .htm come lessi alla linea 34.
Ultimo test: con browser del computer che accede direttamente alla SD (come disco locale), nessun problema !
Autore
Ciao Emilio,
dall’ultimo tuo commento avevo dedotto che le pagine fossero corrette.
Grazie Emilio! Avevo il tuo stesso problema e, rinominando i file.htm con nomi di 4 caratteri ho risolto tutto!
Autore
Bene, sono contento ci sia scambio di consigli ottimi.
Ciao Mauro! Ci siamo già sentiti per mail qualche volta!
Ora ho un dubbio che forse riuscirai a colmare e che sono sicuro c’entri in qualche modo con questo articolo.
Sostanzialmente io vorrei far sì che cliccando su un bottone di una pagina HTML risiedente su SD si apra un link diciamo: “http://192.168.1.20/?25
e che nel momento in cui leggo tramite GET questo URL Arduino mi accenda ad esempio un LED.
Posso farlo con il metodo descritto nel tuo articolo? Perchè tu prevedi sostanzialmente solo che da un link si vada a un’altra pagina HTML invece io vorrei che da un link Arduino esegua dei compiti!
Grazie!
Autore
Ciao Matteo,
ti consiglio di leggere anche il mio articolo sui led RGB controllati da smartphone, troverai descritta tutta la tecnica per realizzare quello che ti serve e potrai fondere lo sketch con quello presentato qui per la gestione delle pagine su SD Card.
Ho fatto come mi hai suggerito e funziona tutto, tuttavia è sorto un altro problema… ovvero una volta che il ciclo entra nella condizione if(action == 24) e il led si accende; la scheda non riesce a far ripartire il loop! Si blocca sulla pagina dell’IP (192.168.1.20) con una pagina bianca! Ti linko lo sketch:
[[ codice rimosso in automatico ]]
GRAZIE!
Autore
Ciao Matteo,
come hai letto non è consentito incollare codici nei commenti, ti chiedo la cortesia di rispettare tale regola e leggere bene gli avvisi in fondo ad ogni articolo.
Per quello che mi scrivi ti consiglio di indagare, usando il monitor seriale per capire se una volta entrato nell’if si verifica qualche condizione per la quale lo sketch non riesce a procedere oltre o se si tratta di un crash di memoria.
Ciao Mauro , questo esempio e’ oro colato per moltissimi sviluppi futturi.
ho pero due domande :
a) ho leggermente modificato il tuo esempio per poter caricare file con estensione “txt” modificando la stringa nella ria 34, in questo modo a video posso accedere a i file di log dalla schermata.Il tutto funziona alla grade ,ladomanda e’per poter caricare anche pagine con estensioni diverse devo ricreare una seconda stringa (ho provato e non funziona) o posso dirgli tipo ” .*** ” cioe’ che mi carichi tutti i file presenti nella sd ?
b) accedo al mio logo es:http://192.168.0.130/casa.txt e lo vedo correttamente , eiste un modo che arduino mi copi il file in un indirizzo ip? avendo un nas sto cercando il modo che ogni giorno arduino mi carichi il file del datalogger in modo da poi poterlo elaborare in exel , inquanto non riesco ad accedere a tale file in nessun modo ,eccetto lapura visualizzazione nella pagine web ,ma e;inutile se devo elaborarlo,
Autore
Ciao Francesco,
rispondo ai tue due quesiti:
a) se hai letto la mia descrizione della linea sai che l’estensione che inserisci in questa linea è quella che puoi inserire come link, se vuoi più estensioni dovrai mettere nell’if le condizioni che valutino le altre estensioni; In arduino devi scriverti tutto quello che vuoi esegua lo sketch, lui non conosce i caratteri speciali tipo *** devi scrivere tu cosa significa, come leggere il contenuto di una dir e come trattare ogni singolo file.
b) Vale quello che ti ho scritto per il punto a, se vuoi che arduino salvi un file su un nas o altro dispositivo devi implementarti il codice per farlo.
Grazie mille per le tue risposte. Hai per caso qualche consiglio sul punto b) da seguire? Non vorrei spedire una stringa modello dataloggin su mysql ma il file intero. Ho provato il discorso ftp ma arduino non riesce a gestirmi sua web server che ftp server .o non sono capace io a farli convivere.
Autore
Ciao Francesco,
l’unico metodo che mi viene in mente è creare uno streaming di dati con un protocollo tipo nfs o cifs che servono a questo scopo.
Ciao Mauro,
son riuscito a fare tutto. Il problema è che non riesco a caricare i file css o javscript da sd, legati al mio html.
Puoi darmi qualche info in merito?
Grazie
Ciao
Autore
Ciao Michele,
io nel mio articolo ho incluso sia il css sia il js nel codice perchè in caso contrario devi crearti tutta la gestione di questo tipo di file lato arduino sketch.
ciao mauro,
vorrei chiedere un informazione, se il mio client non visualizza la pagina HTM ma la connessione è presente a cosa può essere dovuto?
Autore
Ciao Daniel,
descritto così potrebbe essere qualunque cosa.
Puoi fornire qualche dettaglio su cosa accade a livello network ?
a livello di network la connessone è presente, ma il file index.htm non me lo apre, addirittura ora continua a dirmi che la SD non è formattata(appena formattata), oppure che non è presente.
e quindi io mi sono chiesto, posso evitare l’SD???
e ho provatoo ad implementare questo coice:
[[ codice rimosso in automatico ]]
ecco..questo codice, non manda il segnale ad arduino di accendere la lucestanza..puoi darmi una mano?
Autore
Ciao Daniel,
non è consentito inserire codice nei commenti, leggi bene le istruzioni in fondo ad ogni articolo.
Puoi evitare la SD se vuoi, devi scrivere un codice adatto a gestire la pagina direttamente nello sketch senza appoggiarsi alla SD Card.
In ogni caso prima di provare sketch complessi in cui la SD è marginale io proverei con uno sketch di test della SD per verificare che la formattazione fatta sia corretta ( Fat16 ) e che la SD sia da 2Gb come indicato in tutti i tutorial sulla SD Card.
ok non visualizza bene il codice con i tag
..te l'ho inviato per email...
Autore
Ciao Daniel,
non ho ricevuto il tuo codice, tuttavia non correggo codice scritto da altri.
Se vuoi che sia io a sviluppare il tuo progetto posso farlo su commissione tra qualche mese.
Intanto complimenti per questo sketch!
Tutto ha funzionato al primo colpo.
Ora viene il bello. Partendo dalla posizione “.htm” volevo interpretare eventuali parametri successivi.
Dopo la linea 34
if (inString.indexOf(“.htm”) > -1) {
ho aggiunto banalmente queste righe di programma:
int posiz = inString.indexOf(“.htm”);
Serial.println(inString);
Serial.println(posiz);
Questi sono i risultati che ho ottenuto:
25GET /home.htm HTTP/1.1
11
25GET /whoami.htm HTTP/1.
13
25GET /home.htm HTTP/1.1
9
25GET /mauroa.htm HTTP/1.
7
25GET /home.htm HTTP/1.1
9
25GET /contact.htm HTTP/1
17
25GET /home.htm HTTP/1.1
13
25GET /mauroa.htm HTTP/1.
15
Come vedi la posizione restituita per lo stesso url varia.
All’inizio per capire meglio i vari passaggi avevo disseminato lo scketh di vari Serial.print, ottenendo valori della posizione di “.htm” davvero senza senso.
Sembra quasi che aumentando il codice il sistema perda il controllo.
Sai darmi un aiuto
Autore
Ciao Renzo,
a me sembra che lo script funzioni in modo egregio, gli chiedi di restituirti la stringa “inString” e la posizione del .htm nella striga e lui ti restituisce proprio quello.
ad esempio
012345678901234567890123456789
25GET /home.htm HTTP/1.1
se guardi la prima linea ( un banale contatore che ho scritto come sequenza da 0 a 9 ripetuta ) noti che .htm si trova proprio alla posizione 11
Conta anche gli altri e ti troverai.
Forse non hai osservato le varie righe.
Ho chiamato la pagina home.htm x 4 volte con questi risultati: 11, 9, 9, 13
Per la pagina mauroa.htm x 2 volte: 7 – 15
Nel forum di arduino ho letto che molti considerano più stabile la libreria
a quella String presente nell’IDE.
Comunque proverò a ripartire da zero e fare le cose in modo ordinato.
Autore
Ciao Renzo,
perdonami non avevo visto le ripetizioni, effettivamente è strano quello che rilevi, io non mi sono mai accorto di questa imprecisione, non vorrei che la libreria String.h sia stata sostituita nel corso delle versioni dell’IDE portando ad una sua instabilità.
Tuttavia il metodo “indexOf” è così semplice che mi risulta strano possa essere così instabile, hai provato a verificare direttamente nella libreria se esista questa eventualità?
Mi ero perso la parola string.h
Nel forum di arduino ho letto che molti considerano più stabile la libreria string.h
a quella String presente nell’IDE.
Autore
Ciao Renzo,
se ti va di provarla e poi confrontare i due metodi “indexOf” magari segnali al gruppo di sviluppo il bug che riscontri e fai correggere quella ufficiale.
Buonasera,
ho realizzato, seguendo i consigli dei vari post, un piccolo progettino di domotica che mi permette di comadare alcuni dispositivi via web sfruttando arduino anche come webserver. Ho avuto alcune difficoltà che ho risolto in modo molto poco ortodosso con le variabili dinamiche…ho avuto l’impressione che dichiarandole prima di altre variabili statiche quest’ultime poi andassero a prendere locazioni di memoria che inizialmente erano state destinate alla variabile dinamica…vabbhe ma questo non è il vero problema…il problema sta nel fatto che utilizzando il nuovo browser del nuovo cellulare praticamente è come se non mi riiconosce più i comandi che arrivano via web …. mi sapresti dire come mai????
Ciao e grazie in anticipo
Autore
Ciao Roberto,
mi sembra strano che il cambio del browser influisca sul corretto invio dei comandi, tuttavia potrebbe dipendere da come hai scritto lo sketch.
La cosa migliore in questi casi è usare il monitor seriale e farti scrivere i dati ricevuti in modo da confrontarli con il parsing che esegui.
Ciao Mauro,
complimenti per tutto ciò che fai, volevo dirti che ho riscontrato gli stessi problemi riscontrati da Renzo, probabilmente da un un pò è cambiato qualcosa nell’IDE e più precisamente nell’uso delle stringhe char*
penso, ma è solo un mio pensiero, che ci sia un’errore nell’allocazione della memoria per le suddette stringhe.
Ho fatto qualche modifica al tuo sketch, e ora rifunziona tutto regolarmente.
In pratica ho solo evitato di usare le stringhe char*.
Ciao grazie
[ codice rimosso in automatico ]
Autore
Ciao Giuseppe,
purtroppo il codice viene rimosso in automatico e non posso leggerlo.
Ti chiedo di inviare la tua modifica alla mail da cui ti arrivano le notifiche del blog ( info ) in modo che io possa valutare e pubblicare la correzione.
Ciao Mauro,
ho iniziato da poco a usare Arduino Uno. Ho collegato a questo un modulo Bluetooth e una memoria micro sd. Il mio obiettivo sarebbe quello di scaricare i file da un cellulare Android, via Bluetooth, nella scheda micro sd. Ho trovato sketch che eseguono questo solo con stringhe.
Puoi darmi qualche dritta?
Grazie,
Leo
Autore
Ciao Leo,
sicuramente è un progetto ambizioso e penso che la strada delle stringhe sia in primo luogo preferibile al trasferimento byte.
Molto dipende anche da come trasferisci il file, concentrati sulla visualizzazione del file sulla seriale analizzando come ti arrivano i dati dal cellulare e, solo successivamente, proverai a salvare il dato sulla SD.
Salve Mauro
vorrei utilizzare il tuo stesso codice per caricare dei file dalla scheda sd ma il problema è che ho dei file in php e non in html.
Come dovrei modificare il codice per permettere la lettura dei file in php?
E inoltre una volta fissati staticamente sulla scheda di rete gli indirizzi (ip,mac,gateway,subnet) qual’ è il percorso da inserire nell’URL del browser?
Grazie in anticipo.
Autore
Ciao Kevin,
arduino + ethernet non possiede un interprete Php per cui non è solo un problema di scrittura dei file sulla SD ma dovresti scriverti un interprete per poterli utilizzare, che come immagini e tutt’altro che banale, ammesso che la capacità computazionale dell’Atmega328 sia sufficiente, cosa che dubito accada.
In merito all’url del browser dovrai digitare http:// seguito dall’Ip assegnato al progetto.
Salve Alfieri volevo farle una domanda.
Io vorrei realizzare un database che contiene due variabili X-Y con valore massimo 0-1023.
Tutto questo per realizzare delle pistole con camera IR interna con comunicazione I2c.
Chiedo il database perchè vorrei mettere 24 pistole via cavo ethernet e gestirmi le pistole in modo dipendente magari collegando un hub o router switch, ma non so come fare un database che mi aggiorna i dati in real time in modo velocissimo.
Mi può aiutare o darmi qualche consiglio?
Tramite pagina web non mi interessa vedere i dati perchè verranno spedit iin un video gioco fatto con Unity. Mi serve solo avere una tabella che butta queste due variabili in sequenza riga dopo riga e che si aggiorni in base la posizione della camera.
Grazie mille
Giovanni
Autore
Ciao Giovanni,
potrei non aver compreso il problema ma da come lo descrivi ti suggerirei l’uso di una raspberry che è più adatta in termini di velocità di processore, ram, possibilità di usare mysql come db e l’i2c per comunicare.
ciao Mauro, ho copiato il tuo esercizio ma quando va sull indirizzo ip mi compare la pagina principale ma poi se clicco sui vari menu mi esce il codice e non la pagina web. Come potrei risolvere? Grazie!
Autore
Ciao Giovanni,
le pagine devono essere htm e non altri linguaggi.
Hai fatto così giusto?
Si sono htm
Autore
Ciao Giovanni,
è un comportamento anomalo con i file .htm in quanto è il browser ad eseguire la visualizzazione.
Verifica con il monitor seriale se vengano inviati dati o caratteri errati al browser e sul browser che la pagina ricevuta abbia la corretta codifica htm.
Ciao, confermo che ho lo stesso problema, anche facendo il log (printando) su seriale si vede che sostituisce “HTTP/1.1 200 OK” con “m”… non capisco!!!
Autore
Ciao Andrea,
lo stesso problema di chi?
La risposta HTTP/1.1 200 OK è corretta come risultato di una query http.
mi rispondo da solo… c’era un warning che mi sconsigliava di usare il char* (non ricordo esattamente cos’era scritto, ma sicuramente esce anche a voi). Ho sostituito la variabile char* con una semplicissima String e tutto si è risolto.
A proposito… perchè hai usato una char*?? 🙂
PS: colgo l’occasione per farti i miei più sentiti complimenti per il sito.
Saluti
Autore
Ottimo Andrea !!!
Ciao Mauro,
Ottimo blog e guida!! Volevo chiederti, è possibile usare pagine php?
Grazie mille
Autore
Ciao Emanuele,
purtroppo dovresti scrivere l’interprete php perchè non esiste, a meno che o sappia, un interprete o una libreria in grado di farlo.
Ciao volevo gfarti una domanda, ho un arduino uno con ethernet shield 2
L’arduino legge un valore di altezza di un liquido e tramite una funzione webserver lo scrive in una semplice pagina web.
Vorrei rendere visibile la pagina e il valore anche su un mio sito, ho pensato allora tramite un frame di incorporare la pagina risiedente su arduino nella pagina del sito, in pratica la pagina residente sul mio server di hosting dove gira il sito incorpora al suo interno la pagina residente su arduino web server.
Ho aperto la porta (ne ho usata una diversa dalla 80) su router e ho gia un servizio di dns per accedere dall’esterno.
Il problema è che se accedo una volta la bpagian funziona e carica all’interno del frame la pagina di arduino con il valore, ma se ci sono più accessi contemporanei negli altri casi si vede la pagina perché si vede il nero dello sfondo ma non si visualizza il valore, ho pensato che potesse essere una problema dovuto al numero di accessi massimi che il webserver di arduino supporta ma non ho trovato niente in rete a riguardo, hai qualche suggerimento ?
Grazie.
Autore
Ciao Stefano,
considera che Arduino ‘ un micro controllore e non un micro processore come quello usato dai server web.
La cosa migliore a mio avviso è usare in concomitanza alla lettura del valore un invio dati mediante ethernet al tuo sito.
In questo modo ottieni:
a) che non ti serve aprire alcuna porta del router o servizio dyndns ( o simili )
b) non esponi la tua rete a potenziali attacchi
c) lavori in nat dall’interno della tua rete verso il tuo sito
d) invii il dato solo quando viene letto, controllo da arduino
e) riduci il traffico da e verso arduino
f) puoi gestire meglio il valore sul sito web
g) puoi collegarti anche da casa al sito web usandolo come unico punto di visualizzazione del dato
h) puoi costruire sul server un data logger dei valori inviati
i) puoi realizzare dei grafici di andamento delle info sul web facilmente
Se tutto questo volessi farlo con Arduino avresti una strada molto complessa da seguire che quasi sempre si scontra con i limiti di potenza computazionale di arduino uno.
Purtroppo non conosco così bene i linguaggi di programmazione credo si necessario utilizzare delle pagine php come ho letto da qualche parte alla quale l’ arduino si collega via http e che poi prendono in consegna il valore letto dall’ arduino e lo scrivono in un database, ho trovato qualche esempio in giro proverò a lavorarci sopra e vedere se ne vengo fuori, a me sinceramente non mi interesserebbe avere un database di valori ma semplicemente mostrare la lettura fatta all’interno di una pagina web con ora e data , ma non conosco bene php e non credo di riuscire a scrivere una pagina con questa funzione, proverò a cercare in rete.
Grazie per la risposta.
Autore
Ciao Stefano,
se le ipotesi di data logger non sono di tuo interesse puoi evitarle, resta valido l’invio da arduino al webserver in modo da visualizzare il valore letto.
In questo caso puoi prendere l’esempio di come si scrive un file in php dal manuale (http://php.net/manual/en/function.file-put-contents.php) a cui passi un valore in query string e lo scrivi in un file.
Ho dato un occhiata ma non conosco il linguaggio php e non so come assemblarlo, non ne sono venuto a capo, mi arrangio con html, ma con php a parte qualche modifica in pagine già fatte per piccoli adattamenti di più non so fare, non conosci qualche esempio gia pronto da adattare al mio caso?
Grazie.
Autore
Ciao Stefano,
si, quello nella pagina che ti ho segnalato, devi solo cambiare il nome del file e scrivere nel file il valore che ti passi da url, tipo: http://www.tuosito.it/pagina.php?val=%5Bvalore]
nella pagina prenderai il valore come: $_SERVER[‘valore’] e lo scrivi nel file.
Scusa ma per me è arabo.
A che esempio ti riferisci, ho visto che all’inizio ce ne sono 2
Per creare la pagina php quale codice devo utilizzare , non vedo la stringa che tu citi
http://www.tuosito.it/pagina.php?val=%5Bvalore%5D
pagina .php e il nome della pagina che acquisisce il dato Valore è quello che passa l’arduino quando chiama la pagina ?
Coa vule dire “nella pagina prenderai il valore come: $_SERVER[‘valore’] e lo scrivi nel file”
Il file che la pagina scrive è un file di testo ?
Scusa ma in php sono zero sto cercando di fare questa cosa da solo ma credo di non avere conoscenze sufficienti.
sono riuscito a testare la pagian php che scive sul file txt, l’ho fatto in locale con wbserver e interprete php, ci lavoro un po sopra e ti faccio sapere, devo poi capire cosa scrivere nello sketch arduino per risciamare la pagina.
La pagina però non sovrascrive il valore ma continua ad aggiungerlo
Autore
Di solito si usa per realizzare dei data logger, siccome a te non interessa, puoi cambiare le opzioni di apertura del file in modo che si posizioni sempre al primo carattere e di conseguenza sovrascriva il valore.
Nella pagina del manuale dovrebbe esserci tutto dettagliato.
Autore
Ottimo Stefano!
Autore
Ciao Stefano,
non ti ho inviato la pagina del manuale in italiano?
Se leggi ti spiega esattamente cosa fanno i comandi e come si usano, purtroppo in programmazione non basta il semplice copia e incolla senza comprendere il significato dei comandi, come sai.
In merito a $_SERVER[‘valore’] ti restituisce il “valore” passato nella chiamata alla pagina.
La pagina è in inglese, comunque riesco a capire cosa c’è scritto l’inglese un po lo conosco, se c’è una versione in italiano sarebbe meglio.
Autore
Ciao Stefano,
si il manuale php esiste anche in italiano.
Ciao scusa se ti disturbo ho scritto uno sketch per l’arduino e sembra si connetta alla pagina php visualizzando il monitor seriale sembra che la connessione vada a buon fine, se arresto apache e l’interprete php compare errore di connessione.
però non riesco a capire la giusta sintassi della pagina php per fargli compilare il file txt.
Posso inserire qui lo sketch e il codice della pagina se puoi dagli un occhio e darmi qualche dritta ?
Grazie.
Autore
Ciao Stefano,
non puoi inserire lo sketch, come hai letto nelle regole.
Se riesci a fare la connessione e richiamare la pagina php passandole “?valore=…” dovresti vedere poi nei log del server se la chiamata va a buon fine o meno.
Quando la chiamata va a buon fine sei certo che il dato arrivi al server e puoi concentrarti solo sul Php o altro linguaggio da te scelto per ricevere il dato e scriverlo su un file.
Si apparentemente lo sketch si connette, al pc con il webserver attivo, devo capire se ho inserito i comandi giusti nello sketch per passare il dato alla pagina e se il php della pagina che lo riceve e corretto, non credo visto che non scrive nulla, non conoscendo il linguaggio è difficile, stasera ci lavoro sopra e vedo se riesco a ottenere qualche successo.
Ho trovato un esempio in rete che scrive in un database, ho scopiazzato un po quello omettendo la parte di scrittura nel database e provando a sostituirla con l’esempio del manuale che mi hai linkato, ma mi sa che sto sbagliando qualcosa.
Autore
Ciao Stefano,
se comprendi i comandi prima di usarli ti sarà più semplice, come consiglio a tutti, il manuale serve a questo.
Se vuoi verificare la chiamata che arriva al server controlla il log del webserver.
192.168.0.81 – – [05/May/2017:18:53:59 +0200] “Livello Acqua = 3.98 m GET /arduino/load.php?valore=3.98&localita=meda HTTP/1.1” 400 981 “-” “-”
sembra che il valore venga passato, lo so che devo comprendere i comandi, infatti sto leggendo il manuale, ma non tutto mi è chiaro, e se non hai nessuno che ti spiega a volte è un po più difficile comprendere soprattutto se sono cose che non hai mai fatto, quindi cerco di andare per tentativi se falliscono vuol dire che ho capito male e quindi devo ritornarci su.
Comunque grazie per le dritte.
Autore
Ciao Stefano,
errore 400 vedi pagina dell’rfc come da mia risposta.
access log
192.168.0.177 – – [06/May/2017:00:15:25 +0200] “Livello Acqua = 3.76 m GET /arduino/load.php?valore=3.76&localita=meda HTTP/1.1” 400 983 “-” “-”
error log
[Sat May 06 00:15:25.987521 2017] [core:error] [pid 9792:tid 1684] [client 192.168.0.177:1030] AH00126: Invalid URI in request Livello Acqua = 3.76 m GET /arduino/load.php?valore=3.76&localita=meda HTTP/1.1
non avevo guardato il log degli errori
Autore
Ciao Stefano,
anche senza questa specifica dell’error_log mi era chiaro il tipo di problema è scritto nel “400”
dopo qualche prova se scrivo questo indirizzo:
http://192.168.0.1/load.php/arduino/load.php?valore=3.84&localita=meda
La pagina php scrive i valori nel file di testo 3.84 meda
access log
192.168.0.177 – – [06/May/2017:01:42:32 +0200] “GET /arduino/load.php?valore=3.84&localita=meda” 404 1054 “-” “-”
error log
nessun errore
ma nonostante il monitor seriale di arduino mi conferma la corretta connessione e disconnessione dal server
Connessione…
Connesso
Distanza 0= 1.216
Distanza 1= 1.216
Distanza 2= 1.211
Distanza 3= 1.246
Distanza 4= 1.246
Distanza 5= 1.246
Distanza 6= 1.241
Distanza 7= 1.241
Distanza 8= 1.241
Distanza 9= 1.241
Distanza 10= 1.241
Distanza 11= 1.241
Distanza 12= 1.231
Distanza 13= 1.236
Distanza 14= 1.231
Distanza 15= 1.211
Distanza 16= 1.211
Distanza 17= 1.211
Distanza 18= 1.191
Distanza 19= 1.186
Media = 1.226
Disconnesso.
non viene scritto nulla sul file di testo.
Non riesco a capire dove sbaglio senzaltro è un errore nello sketch ?
Grazie.
Autore
Ciao Stefano,
perdonami l’essere diretto ma l’errore è grande come una casa e scritto chiaro nell’access log:
192.168.0.177 – – [06/May/2017:01:42:32 +0200] “GET /arduino/load.php?valore=3.84&localita=meda” 404 1054 “-” “-”
Il 404 indica quanto riportato nell’rfc2116-sec10 ( https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ) se lo ricerchi nella pagina ti spiega esattamente cosa significa.
Il fatto che sul monitor seriale non ti riporti alcun errore è dovuto ad uno sketch sbagliato che non scrive sul monitor seriale i dati di risposta del server altrimenti vedresti l’errore.
In unltima, ma non meno importante, hai notato che nell’esempio dell’url hai scritto: http://192.168.0.1/load.php/arduino/load.php?valore=3.84&localita=meda in cui compare 2 volte la load.php ? Probabilmente è un errore di copia e incolla ma il server php interpreta come pagina:
http://192.168.0.1/load.php
e come richiesta di parametri da passarle (GET):
/arduino/load.php?valore=3.84&localita=meda
difficile comprendere come potrebbe funzionare.
Ti invito a leggere qualche manuale di HTTP e Php per aver almeno chiaro come interpretare i log e comprendere come funzionano le connessioni http.
Ti sarà di certo più semplice realizzare i tuoi progetti.
Be tu hai perfettamente ragione, ma considera che non ho mai studiato ne http e nemmeno php, sto cercando di mettere insieme qualcosa, ma essendo completamente ignorante in materia e non conoscendo nessuno che lavora con queste cose e che quindi ti puo dare una mano spiegandoti bene come funzionano non è certo facile e ci vuole tempo, comunque grazie per le risposte.
Continuerò a lavorarci, e ad approfondire la cosa.
Autore
Ciao Stefano,
ti confiderò un segreto: neppure io ho studiato nessuna delle cose che leggi in questo blog, intendo a scuola, ma da autodidatta si può imparare molto.
Ecco perché ti ho invitato e spronato a leggere i manuali.
Mi sono riguardato bene quello che mi hai detto e ho dato un occhiata agli errori dei log, ho fatto le correzioni e ora funziona tutto, la pagina acquisisce i valori e li scrive nel file di testo.
Diciamo che anche se poco comincio ad avere le idee un po più chiare su come funziona la cosa.
l’ultimo log del server
192.168.0.177 – – [07/May/2017:15:15:59 +0200] “GET /load.php/?valore=3.73&localita=Livelloacquainmetri” 200 – “-” “-”
200 = L’azione è stata ricevuta con successo, compresa ed accettata. (Come da link che mi hai segnalato).
Grazie ancora per i suggerimenti.
Autore
Grande Stefano,
queste sono soddisfazioni, non tanto per me .. ma immagino .. sopratutto per te.
Ciao Mauro,
in questi giorni sto provando un Ethernet shield con Arduino Uno Rev3 ma lo shield Ethernet mi da dei problemi…
Ho caricato nello script il codice mac che si trova nella etichetta sullo shield, ho caricato un ip statico libero della mia rete (172.16.64.xxx), ho provato anche a caricare ip x gateway, netmask e dns, ho aggiunto il codice per visualizzare l’ip caricato sul serial monitor ma questo mi visualizza un ip completamente diverso tipo: “255.255.223.255” oppure “255.244.212.247” a seconda delle modifiche che faccio sul codice e non procede con lo script…
Ha qualche suggerimento?… non penso sia lo shield Ethernet guasto o la rete che mi blocca…
Autore
Ciao Elvio,
controlla che ciò che ti fai restituire dal monitor seriale sia la medesima impostazione inserita, ad esempio potrebbe essere l’ordine con cui richiami i metodi per assegnare l’Ip e per recuperarlo dalla libreria.
Inoltre prova con una rete semplice tra il tuo Pc e Arduino con cavo cross e indirizzi fissi.
Ciao Mauro,
Ti ringrazio per la veloce risposta, provo se funziona con una rete pc/Arduino, non ci avevo pensato…
Ti faccio sapere.
Ciao,
volevo sapere se il file txt era possibile salvarlo non direttamente su sd ma in una cartella su sd
Esempio
datalogger/file.txt
Autore
Ciao Daniele,
mi sembra fosse possibile, forse avrai solo qualche limite sulla lunghezza del nome attribuibile alla directory.
Ciao e grazie,
Vorrei un info come posso fare per controllare un led su arduino da una pagina salvata su sd?
oppure come faccio a visualizzare gli ingressi analogici di arduino su un altra pagina salvata su sd?
Grazzie in anticipo mi aiuterebbe moltissimo per un progetto molto importante.
Autore
Ciao Daniele,
quello che chiedi è spiegato in questo tutorial dettagliato ed in altri che trovi in questo blog.
[…] Tutorial: Arduino, Ethernet e pagine multiple su SD Card […]