Salve e grazie a tutti che potranno aiutarmi
esperimento fatto con arduino mega e ethernet shield W5100 con scheda sd
avevo trovato un vecchio topic che dichiarava di aver trovato la soluzione per caricare velocemente le pagine web da sd per evitare il caricamento lento ma non funziona,
di seguito posto lo sketch
......
byte buf[64];
......
if (myFile){
byte c = 0;
while (myFile.available()){
buf[c++] = myFile.read();
if(c > 63){
client.write(buf, 64);
c = 0;
}
if(c > 0) client.write(buf, c);
myFile.close();
}
}
Controllato svista memorabile
Grazie, posto lo sketch funzionante
myFile = SD.open("luci3.txt"); //trasmette parte di pagina web
if (myFile){
int c = 0;
while (myFile.available()){
buf[c++] = myFile.read();
if(c > 63){
client.write(buf,64);
c = 0;
}
}
if(c > 0) client.write(buf,c);
myFile.close();
}
Mi sapete spiegare perchè se lo metto nel void loop() funziona,
ma visto che lo devo fare girare 6 volte, usando un void di richiamo non funziona
provato e riprovato, un - client.write - da - void - esterno dal - void loop() - non lo esegue
all'interno del void loop()
carica --- cose strane (solo per me)
il programma entra in void web()
legge tutto, infatti in Serial.print si legge tutto il file,
ma se client.write si trova nel void web() non riesce a inviare,
se sposti tutto all'interno del void loop() funziona
darbac:
c'è un motivo particolare perchè l'array buf è di 64??
Infatti secondo me la dimensione del buffer è troppo piccola. In questo modo spezzetti l'invio dello stream http in tantissimi pacchetti di piccola dimensione.
Con ESP8266 ad esempio ho fatto alcuni esperimenti e il limite è circa 2/3Kb, con esp32 puoi arrivare anche a 4Kb o più.
Io proverei ad aumentare tipo 512 o 1024 byte e vedi come va.
P.S. Le variabili usate (buf[] e c) mettile tutte in locale
di seguito ti metto lo sketch completo del web server.
c'è un modo per eliminare tutti gli if(), ho provato con switch, ma non riesco a farlo girare.
per il resto è client.write() che messo fuori dal loop() non mi manda nulla
codice inviato come file perchè il forum mi dice massimo 9000 caratteri
l'ultimo pezzo di tabella delle temperature è da ultimare, funziona tutto bene,
tranne che per quel void web(), e se si possono eliminare un po' di if
grazie
La funzione web che hai definito non ha senso perché l'oggetto client che hai dichiarato globale non sa a chi deve inviare quei dati.
Se guardi nel loop() infatti, trovi l'istruzione EthernetClient client = server.available(); In questo caso client è locale ed è l'oggetto ritornato dal server quando ad esempio un browser si collega.
Per farla funzionare come vorresti tu puoi fare ad esempio cosi:
void web(EthernetClient* client ){
myFile = SD.open("visione.txt");
if (myFile){
int c = 0;
while (myFile.available()){
buf[c++] = myFile.read();
if(c > 63){
client->write(buf,64);
c = 0;
Serial.write(buf,64);
}
}
if(c > 0) client->write(buf,c);
myFile.close();
}
}
E quindi quando ti serve la chiami passandogli il puntatore a client, ma quello locale ovviamente (quello globale è inutile, puoi eliminarlo)
web(&client);
Per il resto, perdona la franchezza, ma il problema non sono solo la sbrodolata di if consecutivi, ma l'approccio con cui elabori le richieste del client e prepari la risposta.
Prima di mettersi li a buttar giù righe e righe di codice, è bene sempre fermarsi un secondo e pensare "qual'è il modo più efficiente per fare questa cosa?".
Se la richiesta del client la fai in modo più strutturato ad esempio tipo /?type=TM&number=1&sub=A ti basta fare UNA sola funzione di parsing che ti ricava tutti i parametri necessari dalla stringa passata con il browser (ci sono alcuni esempi proprio qui sul forum sul come).
Stessa cosa per la risposta caricata dalla SD: ripeti sempre lo stesso codice cambiando solo il nome del file.
La funzione web() potrebbe prendere come parametro anche il nome del file ad esempio. La scrivi 1 volta sola, la usi ogni volta che ti serve.
cotestatnt:
E quindi quando ti serve la chiami passandogli il puntatore a client, ma quello locale ovviamente (quello globale è inutile, puoi eliminarlo)
Si, oppure, più semplicemente, può lasciare quello globale ed evitare di ridefinirlo ossia togliendo "EthernetClient" da riga 65 del suo codice:
...
TR[com] = 0;
}
//EthernetClient client = server.available();
client = server.available(); // Uso la variabile globale
if (client) {
...
Per il resto, concordo con tutte le considerazioni di cotestatnt.
Grazie per la dritta del void web(); funziona alla perfezione
per gli if() ci sto lavorando ma la vedo dura,
problemino la pagina visione temperature fa un refresch per tenere aggiornata la temperatura
qundi se entra un secondo client e il primo rimane connesso, gli sballa sempre la pagina.
sarebbe abbastanza se si può, che l'ultimo client abbia la priorità sul precedente o lo scolleghi
Grazie mille arrivare ai vostri livelli sarebbe un sogno
darbac:
problemino la pagina visione temperature fa un refresh
Approfondisci come fare delle chiamate AJAX direttamente da una pagina web (Javascript) e dimentica il refresh temporizzato della pagina, è roba preistorica e non porta mai a risultati decenti.
A maggior ragione considerando che le pagine html le puoi caricare da SD e che quindi te le puoi sviluppare con tutta calma anche con un piccolo webserver che gira sul PC volendo e trasferirle quando sei soddisfatto.
Se cerchi tipo "arduino ajax webserver" viene fuori molta roba, questo ad esempio mi sembra un buon tutorial dettagliato (e spiega un minimo anche la parte HTML, che poi è il nocciolo della questione).
Salve e grazie a chi mi dato spunto per capire e migliorare lo sketch
trovata anche la soluzione per eliminare tutti gli - if() -
per comando da web, di seguito la modifica
grazie
if (readString.indexOf("SCH") > 0){
byte da = (readString.indexOf("SCH")+3);
byte a = (readString.indexOf("COM"));
String scheda = readString.substring(da, a);
tx[1] = scheda.toInt();
da = (readString.indexOf("COM")+3);
a = (readString.indexOf("$"));
String comando = readString.substring(da, a);
tx[2] = comando.toInt();
}
Con questo troncone di sketch, estraggo delle sottostringhe, le converto in numero e le assegno all'array di trasmissione
Un paio di note...
indexOf() quando non trova nulla restituisce -1 e non 0.
Hai scelto una sintassi "strana", mi spiego:
quando fai una richiesta GET al tuo webserver il modo "corretto" per passare dei parametri è usare la sintassi ?param1=value1¶m2=value2¶m3=value3 etc etc
Ad esempio se nella tua pagina web inserisci una form HTML ovvero la classica finestra di inserimento dati + invio, il browser comporrà la query usando quella sintassi.
Ad esempio questo pezzettino di HTML, quando clicchi sul pulsante "submit" farà in automatico una chiamata all'indirizzo /sendContact?fname=John&lname=Doe
compilando in automatico le coppie di parametro/valore da passare.
<html>
<body>
<h2>HTML Forms</h2>
<form action="/sendContact">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname" value="John">
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname" value="Doe">
<input type="submit" value="Submit">
</form>
<p>If you click the "Submit" button, the form-data will be sent to a page called "/sendContact".</p>
</body>
</html>