Salve a tutti, ho cominciato a sperimentare con l'ethernet shield e scopiazzando un po di codice ho creato un web server locale leggero e perfettamente funzionante, ora vorrei vomitare tutto in remoto.. Ho visto qualcosina googlando ma ci ho capito ben poco...
Qualcuno di voi di santa pazienza potrebbe spiegarmi bene come funziona (a livello molto basilare)?
Mi potete indicare come va modificato questo codice?
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ 20
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 20); // IP address, may need to change depending on network
EthernetServer server(80); // create a server at port 80
File webFile; // handle to files on SD card
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0; // index into HTTP_req buffer
void setup()
{
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
SD.begin(4);
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
}
void loop()
{
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// buffer first part of HTTP request in HTTP_req array (string)
// leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
if (req_index < (REQ_BUF_SZ - 1)) {
HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connnection: close");
client.println();
// open requested web page file
if (StrContains(HTTP_req, "GET / ")
|| StrContains(HTTP_req, "GET /index.htm")) {
webFile = SD.open("index.htm"); // open web page file
}
if (StrContains(HTTP_req, "GET /page2.htm")) {
webFile = SD.open("page2.htm"); // open web page file
}
if (StrContains(HTTP_req, "GET /page3.htm")) {
webFile = SD.open("page3.htm"); // open web page file
}
if (StrContains(HTTP_req, "GET /page4.htm")) {
webFile = SD.open("page4.htm"); // open web page file
}
// send web page to client
if (webFile) {
while(webFile.available()) {
client.write(webFile.read());
}
webFile.close();
}
// reset buffer index and all buffer elements to 0
req_index = 0;
StrClear(HTTP_req, REQ_BUF_SZ);
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
}
// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
for (int i = 0; i < length; i++) {
str[i] = 0;
}
}
// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
char found = 0;
char index = 0;
char len;
len = strlen(str);
if (strlen(sfind) > len) {
return 0;
}
while (index < len) {
if (str[index] == sfind[found]) {
found++;
if (strlen(sfind) == found) {
return 1;
}
}
else {
found = 0;
}
index++;
}
return 0;
}
Fare tutto da remoto penso intendi raggiungere il tuo webserver da internet, da un altra rete.
Non devi fare nulla sul codice, va bene così com'è se funziona da lan locale, devi solo avere un router, un ip statico (o un servizio dinamico DNS), configurare gli instradamenti forwarding con porte correttamente nel tuo router.
Ma non dicendo come è composta la tua rete locale e che apparati possiedi sarà dura dirti come fare, ogni rete ha le sue caratteristiche, è già una rottura per chi queste config le mastica tutti i giorni, figurati con le tue informazioni
che cosa hai alice-infostrada-pinco pallino adsl-fastweb fibra- fastweb adsl?
hai un router fornito dal gestore ?
lo hai comprato tu il router?
oltre a quello, in cascata ci sono altri apparati tipo altri router o switch?
sei in un appartamento?
sei in una rete di un aziendale?
Queste sono le info che servono per capire che tipo di rete hai :), alcuni servizi potresti già averli e non saperlo
Guarda come è combinata la rete non lo so perchè è un gestore privato che me la fornisce... nel mio paese no c'è linea e me la sparano con dei ponti wifi..... per quanto riguarda la mia linea locale :
linea che mi sparano 192.168.1.254------------A.P. bridge 192.168.1.10-----------------arduino 192.168.1.20
Spulcialdo un po su google e leggendo quello che mi hai linkato.... Ho capito!!!
allora l'importante è rendere accessibile arduino limitando le restrinzioni del router....DMZ?? o apertura porte.... verso l'indirizzo ip interno..... poi mi avvalgo del sevizio noip e faccio loggare arduino al sito facendo in modo che prenda in automatico l'ip pubblico assegnato....
Giusto?????
Ho trovato questo:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac ethernet
byte ip[] = { 192,168,1,190 }; //indirizzo locale dell'Arduino
byte server[] = {8,23,224,120}; //dynupdate.no-ip.com
//creo un client che punta al
//servizio dynupdate.no-ip.com sulla porta 80
Client client(server, 80);
void setup() {
//Avvio la connessione
Ethernet.begin(mac, ip);
//inizializzo la seriale
Serial.begin(9600);
//aspetto che il chip wiznet sia inizializzato
delay(1000);
Serial.println("Connessione in corso...");
//se la connessione avviene con successo
//invio la richiesta http
if (client.connect()) {
Serial.println("Connesso");
client.println("GET /nic/update?hostname=host.no-ip.com HTTP/1.0");
client.println("Host: dynupdate.no-ip.com");
client.println("Authorization: Basic aW86YW1vIGlsIHRhZWt3b25kbw==");
client.println("User-Agent: arduino_ethernet/1.0 info@gmail.com");
client.println();
}
else
{
//Problemi nella connessione
Serial.println("connessione fallita!");
}
}
void loop()
{
//restituisco il messaggio inviato dal servizio
if (client.available()) {
char c = client.read();
Serial.print(c);
}
//Quando il server si disconnette fermo il client
if (!client.connected()) {
Serial.println();
Serial.println("Disconessione");
client.stop();
//ciclo infinito
for(;;)
;
}
}
Traduzione di quello che dice @Brunello per @2aza:
Molti router ormai possono gestire in automatico questo ip pubblico assegnato da un servizio tipo no-ip
Purtroppo ogni router ha i suoi menu. E a volte i vari menu per i servizi che si possono configurare hanno nomi diversi (mi pare che su alcuni router il NAT venga chiamato DMZ).
2aza:
è un gestore privato che me la fornisce... me la sparano con dei ponti wifi.....
la linea che mi sparano 192.168.1.254------------A.P. bridge 192.168.1.10-----------------arduino 192.168.1.20
Acces point: digicom wave gate 150r
lui è un client che ha come indirizzo di uscita 192.168.1.10 verso il roter del gestore privato, le impostazioni non le deve fare nel suo digicom, non ha un ip pubblico, questo si trova nel router che trasmette a lui, le impostazioni vanno fatte la.
2aza:
quindi si puo fare??
Si se contatti l'amministratore di rete e spieghi la situazione, ti fai impostare i forward verso il tuo accespoint
Intanto grazie a tutti per la pazienza, mi state facendo capire molte cose utili.....
Vi spiego un po meglio la situazione....
Supponendo che io questo arduino lo voglio portare in giro per il mondo con me e quindi sfruttare diversi gestori (fastweb, telecomm ecc)...
Posso richiedere tramite arduino a un servizio tipo "mioip" il mio IP pubblico e di conseguenza creare da arduino un dns bypassando il router con un DMZ o quant'altro?
Non credo che tu possa implementare tutto il protocollo di DynamicDNS su Arduino, ma ... io vedo una soluzione moooolto più semplice che ti svincola da questi problemi ...
Ti compri un piccolo router WiFi che programmi per connettersi con il servizio di DynamicDNS e con il routing fisso verso il tuo Arduino ... quando poi sei in giro, alla rete NON connetti il tuo Arduino, ma il router che ti porti dietro.
Sarà lui ad aggiornare il servizio di IP e a ruotarti la connessione ...
Guglielmo grazie per la risposta... si è un ottima soluzione .... devo fare un po di ricerche e valutare...
Secondo me non è tanto impossibile creare ddns direttamente da arduino.... ma chi sono io per dire cosa è, e non è fattibile.... ora ci studio un po e vediamo cosa ne viene fuori.... intanto grazie mille a tutti.... se qualcuno altri consigli sono ben accettati.... vi tengo aggiornati negli sviluppi....
2aza:
... ma chi sono io per dire cosa è, e non è fattibile.... ora ci studio un po e vediamo cosa ne viene fuori....
... attento, qui "nessuno è chissà chi" e nessuno ha la pretesa di conoscere "la verità assoluta", quindi ... non sminuirti, sei uno di noi
Il mio dubbio è perché, se ben ricordo, alcuni provider di DynamicDNS richiedono HTTPS ovvero connessione sicura SSL che ... vedo dura mettere in piedi su Arduino
Se invece tu trovi una soluzione semplice ed un provider che accetta una connessione in chiaro ... ben venga, anzi, rendici partecipi che la cosa sicuramente interessa a moltissimi
Supponendo che io questo arduino lo voglio portare in giro per il mondo con me e quindi sfruttare diversi gestori (fastweb, telecomm ecc)...
Ogni volta troverai sempre il problema di impostare correttamente la rete per far si che il tuo apparato sia raggiungibile da qualsiasi parte del mondo.
Vuoi creare qualcosa commerciabile che dato in mano a un incopetente funzioni? che senso ha portarsi dietro arduino in giro per il mondo e collegarlo alla prima rete che trovi?
dicci dicci
a parte scherzi:
Non so cosa vuoi fare, però un altra soluzione potrebbe esserti utile creando una paginetta web su un server free o a pagamento, al massimo sono 30-60 euro l'anno (dipende da cosa chiedi), arduino trasmette al server i dati e tu li leggi collegandoti ad esempio a www.2aza.net, ripeto bisogna sempre vedere cosa vuoi fare, la frequenza dei dati che vuoi vedere, la banda che usi, il numero di database che chiedi su mysql, alcuni protocolli di comunicazione che non sono implementati nel free, ecc ecc
illuminazione!!! eureka!!!! datemi dieci minuti perchè ho disegnato su carta, e i miei disegni appartengono a un altra galassia (non di umana comprensione)....
Vai di paint!!!!