ethernet shield web server

lo so ci sono tonnellate di post sull'argomento, e ne ho spulciati molti, non tutti ovviamente, ma non ho trovato alcune cose....

  1. con lo sketch WebServer degli esempi, sono riuscito a far stampare sul browser del pc il valore dato da un LM35, mi sono letto e riletto il codice e ho capito come funzionano le cose, ma non riesco a capire come inviare dati dal client al server (che è arduino)....per esempio utilizzando un browser mi connetto all'indirizzo ip assegnato ad arduino e leggo quello che lui invia ai client, ma se voglio accendere un led, come faccio a inviargli dei dati? per esempio nel mio sketch se il char che riceve è uguale a '1' accende il led, se è uguale a '0' lo spegne, niente di più semplice, ma come faccio a dirgli '1' o '0'???

  2. un link per imparare le cose basilari di html per arduino così magari riesco a disegnare bottoni o altro

  3. l'ethernet shield mi occupa i pin 10,11,12 e 13 giusto? quindi non li posso utilizzare....mentre per quelli analogici? sono liberi tutti?

grazie

uppo per solidarietà :smiley:
ma non posso ancora darti consigli perkè rischio di incasinarti ancora di più!

  1. per inviare info al server devi fare un FORM html, dai uno sguardo a qualche guida base di html, lo impari in 5 minuti :slight_smile:
    Poi analizzi la richiesta get o post del browser (in base a quella che hai usato) e scoprirai che è abbastanza semplice estrarre i dati (sempre che le librerie non lo facciano da sole!)

  2. html.it, ci sono tantissime guide, ovviamente anche per l'html... te ne basta una base e il blocco note, non incasinarti con programmini precotti, prima fai funzionare le cose

  3. direi di sì, ma ci vuole conferma, mai usato l'eth shield :slight_smile:

grazie per la solidarietà XD
e grazie per le risposte, pensavo che l'html centrasse qualcosa con tutta sta storia....mi tocca rispolverarlo, ma mi ricordo che non era difficile....grazie ancora, magari se qualcuno ha altri consigli sono be accetti

#include <String.h>
#include <SPI.h>
#include <Ethernet.h>
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Indirizzo MAC
byte ip[] = { 192, 168, 1, 2 }; // ip in lan
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
Server server(80); //porta server

String readString; //string
boolean flag1 = false; //Inizializzo lo stato del led

void setup(){
Ethernet.begin(mac, ip, subnet);
pinMode(2, OUTPUT);
Serial.begin(9600);
}
 
void loop(){
Client client = server.available();
if (client) {
  boolean currentLineIsBlank = true;
  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
        readString.concat(c);
      if (c == '\n' && currentLineIsBlank) {
         Serial.print(readString);

if(readString.indexOf("Led=1") > 0) {
digitalWrite(2, HIGH); // Accendi Led
flag1 = true;
}

if(readString.indexOf("Led=01") > 0) {
digitalWrite(2, LOW); // Spegni Led
flag1 = false;
}

// INIZIO DICHIARAZIONE PAGINA HTML
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println();
        client.println("Led");
        client.println("<span>STATO: </span>");
		if (flag1) {
              client.println("<span style='color:green'>ON</span>");
            }
            else
            {
              client.println("<span style='color:red'>OFF</span>");
          }

//comando ON OFF
client.println("<a href='/?Led=1>ON |OFF");

client.println("</body></html>");

        //Resetto "String" per la prossima lettura
        readString="";
        //Fermo il client
        client.stop();
 
        } 
    } 
  } 
} 
}

Se dal client invii http://192.168.1.2/?Led=1 accendi il led, se mandi http://192.168.1.2/?Led=01 lo spegni..
La parte importante te l'ho segnata in rosso.

Ovviamente al posto di ?Led=1 e ?Led=01 puoi mettere qualunque cosa. Se la stringa coincide allora arduino legge il comando ed esegue..

Questo è un altro modo di fare quello che ti ha detto lesto :smiley:

grande! ho trovato quell'esempio su google e si capisce bene cosa sta facendo! infatti mi sto leggendo anche una guida di html e credo di aver capito!!! grazie a tutti, se mi vengono altri dubbi scrivo ancora...

EDIT:la funziona 'stringa.indexOf(attributo)' ritorna l'indice del primo carattere della stringa passata come parametro???

ok mi sono trovato cosa fa quel metodo, perfect!
però ora devo scaricarmi la classe String.h, dove la trovo???

è già dentro l'ide di arduino! è una delle classi ufficiali

mi dava errore, allora l'ho trovata su internet e l'ho aggiunta, ma compilando mi diceva che esisteva già la classe WString.h, alla fine allora l'ho inclusa ed ora è tutto a posto....
ora ho altri problemi:

  1. praticamente se clicco sul link per accendere il led, il quale invia con la GET '?led=1' il led non si accende
  2. se clicco sul link per spegnere il led, la scritta che indica lo stato del led non viene commutata in 'OFF' al primo clic ma solo se ci clicco una seconda volta....
    sta che il led non riesco a farlo accendere XD

ecco il codice:

#include <SPI.h>
#include <Ethernet.h>
#include <WString.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3A, 0xA3 };
byte ip[] = { 192,168,0,151 };

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
Server server(80);

int analogChannel = 5; //pin analogico dell LM35
int ledpin = 8;
float tempC = 0;  //temperatura in gradi celsius
String readstring;  //stringa per la lettura dei dati del client
byte ledstatus = 0;  //stato del led

void setup()
{
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  pinMode(analogChannel, INPUT); //input dell' LM35
  Serial.begin(9600);
}

void loop()
{
  //leggiamo la temperatura
  tempC = (analogRead(analogChannel) * 4.88 * 100)/1024;
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        readstring.concat(c);    //aggiunge c alla stringa;
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          Serial.println(readstring);
          if(readstring.indexOf("led=1") > 0){
            digitalWrite(ledpin,HIGH);
            ledstatus = 1;
          }else{
            digitalWrite(ledpin,LOW);
            ledstatus = 0;
          }
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          //Creazione pagina web
          client.println("<html><head>");
          
          client.println("<title>Domotic-Arduino</title>");
          
          client.println("</head>");
          client.println("<body bgcolor=""black"" text=""white"">");
          
          client.println("<h1 align=""center"">Domotic-Home</h1><hr />");
          client.println("
");
          client.print("Temperatura interna : ");
          client.print((int)tempC);
          client.println(" C");
          client.println("

");
          client.println("<h3><a href="""">Aggiorna Sensore</a></h3><hr />");
          client.println("<br /");
          client.print("Comandi LED su pin ");
          client.println(ledpin);
          client.println("
");
          client.print("Stato LED :");
          if(ledstatus){
            client.println("<font color=""green""> ON</font>");
          }else{
            client.println("<font color=""red""> OFF</font>");
          }
          client.println("
");
          client.println("<h2><a href=""/?led=1"">ACCENDI</a> | <a href=""/?led=0"">SPEGNI</></h2>");
          
          client.println("</body></html>");
          
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(100);
    readstring = "";
    // close the connection:
    client.stop();
  }
}

inoltre quello che ricevo quando clicco su ACCENDI per accendere il led il browser invia ciò:

GET /?led=1 HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
Referer: http://192.168.0.151/
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

GET /favicon.ico HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
Accept: /
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

quindi la stringa 'led=1' c'è e dovrebbe trovarla nella funzione indexOf() boh

fai una bella cosa, riscaricati l'ultima versione dell'IDE.
la classe String deve funzionare senza inclusioni perchè viene inclusa automaticamente.
Attualmente sta succedendo qualcosa che non dovrebbe succedere.

Comunque il problema è probabilmente questo:
nella prima get accende il led, poi parte la seconda get che richiede il file di icona, che però non soddisfando if(readstring.indexOf("led=1") > 0){ spegne il led.
Poi nei prossimi reload il file viene considerato già caricato, e quindi non dà problemi (dipende se e quanto il browser salva l'immagine in cache)

Per evitare il problema il codice di spegnimento led lo mettin in un ulteriore if: if(readstring.indexOf("led=0") > 0){ :smiley:

poi sinceramente non ho capito il problema 1, ma magari è dipeso da questo?

e la seconda GET non si può evitare? o fermarla?
comunque con i 2 if separati logicamente è giusto, però devo trovare un altro modo per gestire la visualizzazione dello stato del led perchè devo cliccare 2 volte su ACCENDI per farlo cambiare....poi ci ragiono, però adesso volevo almeno accende il led che non si accende ancora

no, mi sa che è la richiesta dell'iconcina che visualizza a fianco dell'url.. ci devi convivere (come è giusto che sia! imparare a gestire gli errori sempre e comunque! perchè come diceva il mio prof di info, il programma lo fate voi ma lo userà la segretarietta stupida, che è peggio di mille hacker *senza offesa per le segretarie, soprattutto se con belle gambe, numeri di telefono in privato pls :smiley: *)

quindi ora il led si accende, giusto? è solo nell'HTML che è errato lo stato... strano.

ahahhaahha grande

no comunque il led non si accende ancora....

ok, allora stampa la stringa (cosa che già fai se non erro) e anche il risultato della indexOf
vado a farmi il cafferino della sera :slight_smile:

anch'io mi sono appena preso il the serale :wink:

anyway, appena accedo alla pagina ricevo ciò (lo stato led è su OFF, quindi giusto):

stringa: GET / HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3


indexOf(led=1): -1
indexOf(led=0): -1
stringa: GET /favicon.ico HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3


indexOf(led=1): -1
indexOf(led=0): -1

Quando clicco su Accendi (lo stato del led diventa ON, quindi giusto):

stringa: GET /?led=1 HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
Referer: http://192.168.0.151/
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3


indexOf(led=1): 6
indexOf(led=0): -1
stringa: GET /favicon.ico HTTP/1.1
Host: 192.168.0.151
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3


indexOf(led=1): -1
indexOf(led=0): -1

quindi funziona il codice, ma c'è sta seconda GET che rompe, per aggirarla ho pensato: se metto una variabile che mi dice in quale delle 2 get sono e faccio un controllo nell'if in modo che accendo il led solo nella prima get...

EDIT: ma mi è venuto il dubbio una volta che il pin è HIGH, anche se la funzione ritorna -1 non dovrebbe passare a LOW, e dovrebbe rimanere HIGH...cavolo, controllo il circuito va che non vorrei aver fatto una papera XD

cavde:
EDIT: ma mi è venuto il dubbio una volta che il pin è HIGH, anche se la funzione ritorna -1 non dovrebbe passare a LOW, e dovrebbe rimanere HIGH...

esattamente, ce l'hai messo apposta :slight_smile:

cavde:
cavolo, controllo il circuito va che non vorrei aver fatto una papera XD

pin -> resistenza -> anodo led -- catodo led -> GND

Polarizzazione di un LED

Solitamente il terminale più lungo di un led (diametro package 3 mm, 5 mm o superiori) è l'anodo (+) e quello più corto è il catodo (-).

Per polarizzare correttamente un LED possiamo usufruire inoltre di una caratteristica particolare del package: se si guarda infatti il led dall'alto, si può notare come la parte laterale del package non sia regolare ma squadrata da un lato: questa "squadratura" identifica il catodo (-). Nel caso dei led 3 mm, si rende necessario l'uso di un tester in quanto tale "segno" (se presente) non è quasi visibile.

Se si utilizza un tester, dopo aver selezionato la scala di resistenza con fattore 1 (X1), se si pone il puntale positivo sull'anodo e il puntale negativo sul catodo, il tester segnerà un valore di resistenza dell'ordine di qualche centinaio di ohm, nel caso il tester fosse un modello analogico con pila di alimentazione a 3 volt, se il led è efficiente, essendo polarizzato direttamente, il piccolo flusso di corrente che lo attraversa lo farà accendere, invertendo i puntali, invece, il tester non dovrà segnare alcuna continuità.

nono il circuito è giusto! se no mi sarei dovuto fustigare per 3 ore....

comunque ho notato che se clicco su ACCENDI ottengo quello di prima e se poi clicco su SPEGNI, invece la indexOf(led=1) ritorna 98, e per led=0 ritorna 6 (giusto)....ma perchè quel 98????
e comunque sto benedetto led non vuole accendersi....ma mi sa che rimando a domani e vado a dormire se no sclero....
grazie mille per il supporto!!!!

azz readstring="";
non funziona bene dove l'hai messa(o forse non funziona proprio, c'era una discussione in corso sulla cosa)... risolvi semplicemente dichiarando readstring NON globale, ma subito prima del while:

boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

diventa

boolean currentLineIsBlank = true;
    String readstring;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

e elimini la dichiarazione globale di String readstring;

edit: HO CAPITO!!!! NON HAI DICHIARATO IL PINMODE() SUL PIN DEL LED COME OUTPUT!!!! ARGHHHH :grin:

grandeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.....io invece mi vado a tirare 10 mazzate.....belin che idiota!!!

adesso si che si accende sto povero led......grazie

però c'è ancora una cosa che non mi quadra, se accendo, poi spengo e poi riaccendo, il led non si accende e neanche lo stato va su ON, per accendere il led, dopo la prima volta devo cliccare 2 volte....perchè la indexOf(led=1) ritorna 98 e la led=0 ritorna 6 quindi si rispegne subito....

EDIT: aggiornamento, se uso il cell, con Opera Mobile mi collego alla pagina e funziona tutto perfettamente, on e off, on e off, senza problemi....magari è chrome che agisce in modo diverso....

EDIT2: se vuoi il mio indirizzo così mi vieni a saccare di botte te lo do pure....ahahahah

molto strano, posta l'output quando succede questo macello...
e tetti una Serial.println();
nei due if:

  • if (c == '\n') {

*else if (c != '\r') {

e quando chiudi la connessione.
*client.stop();

Mi sa che crome tenta lo stesso di usare HTML/1.1, e quindi invia 2 richieste di fila senza chiudere la connessione. Bisogna gestire l'eccezione :slight_smile: