[RISOLTO]GET Request e Relè

Salve a tutti ragazzi, sono nuovo nel forum e già ho postato nel sezioni dei nuovi iscritti. Mi auguro di non aver sbagliato sezione, in caso scusatemi.

Detto ciò, ho due domande da esporvi.

1)Ho acquistato una ethernet shield e quando interrogo il web server arduino, vorrei passargli dei parametri mediante la variabile GET. Es : http://192.168.1.80/?prova=ciao&prova2=work. Vorrei leggere i parametri ciao e work, e non so se è possibile e in caso come fare con C.

2)Il relè comunica il suo stato ad arduino? Ovvero, è possibile mediante sketch vedere se è settato in HIGH o LOW?

Grazie dell'attenzione

xAstyle:
Salve a tutti ragazzi, sono nuovo nel forum e già ho postato nel sezioni dei nuovi iscritti. Mi auguro di non aver sbagliato sezione, in caso scusatemi.

Detto ciò, ho due domande da esporvi.

1)Ho acquistato una ethernet shield e quando interrogo il web server arduino, vorrei passargli dei parametri mediante la variabile GET. Es : http://192.168.1.80/?prova=ciao&prova2=work. Vorrei leggere i parametri ciao e work, e non so se è possibile e in caso come fare con C.

2)Il relè comunica il suo stato ad arduino? Ovvero, è possibile mediante sketch vedere se è settato in HIGH o LOW?

Grazie dell'attenzione

Ciao!!! Certo che lo puoi fare.
Immagino che stai usando l'esempio webserver.
Comunque tu sai che nell'header la stringa GET inizia subito dopo il punto di domanda e termina appena incontra lo spazio (andando avanti incontro HTTP ecc...).
Questa è la funzione che mi son fatto io per leggere la stringa GET. La chiamo non appena EthernetClient client = server.available() restituisce 1. passandogli la variabile client.

bool success = readRequest(client);

Per la variabile dataGet ho previsto un buffer di 80 caratteri, ma perchè la stringa che prevedo di ricevere è lunghetta. Nel tuo caso ne bastano molti meno. Nel caso che metti come esempio 22.

bool readRequest(EthernetClient &client){
  int i = 0;
  //Serial.println(client.available());
  //Controllo che il client sia connesso
  while (client.connected()){
    if (client.available()){
    char c = client.read();
    //controllo che sia iniziata la stringa GET
    if (c == '?'){
      //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
      for(i=0; i<80; i++){
        c = client.read();
        if(c!=32){
          dataGet[i] = c;
          //Serial.print(dataGet[i]);
        }else{
          dataGet[i] = '\0';
          break;
          }
      }
      while(client.available()){
          client.read(); 
      }
    return true;
    }
    } 
  }
  return false; 
}

Una volta che ho tutta la stringa GET nella variabile dataGet la gestisco con strtok_r (non con strtok perchè hai due divisori da controllare, uno è l'uguale, l'altro la e commerciale). Mentre per verificare a cosa corrisponda la variabile passata utilizzo strcmp.
Buona serata!!!

Per il secondo quesito cerco che puoi verificare lo stato del relè, creando una variabile stato che vai cambiare da high a low ogni volta che fai il digitalwrite per modificare lo stato del relè. Quando vuoi sapere lo stato basta che vai a vedere com'è settata.

Lollo82:
Per il secondo quesito cerco che puoi verificare lo stato del relè, creando una variabile stato che vai cambiare da high a low ogni volta che fai il digitalwrite per modificare lo stato del relè. Quando vuoi sapere lo stato basta che vai a vedere com'è settata.

ancora prima con digitalRead(pin) che ti dice se il pin in questione è HIGH o LOW

... però se il programma l'hai scritto tu... devi sapere in che stato è il pin :wink:

Il rele non comunica il suo stato anzi sei tu che devi tramite il pin Channel dirgli apriti o chiudi.
Se posso un esempio di ottimizzazione senza usare diverse variabili potresti usare una cosa simile per cambiare stato e leggerlo

Int status = 0;
Void loop()
{
   Digitalwrite(pin_usato, status);
   Serial.println(status);
   Status ^= 1;
   Digitalwrite(pin_usato, status);
   Serial.println(status);
}

Spero ti sia utile a me è servito ed ho scoperto L uso di ^=
Puoi usare certamente HIGH o LOW all interno della funzione ma se ti serve saper lo stato attuale secondo me una cosa del genere è la migliore!!!

xAstyle:
2)Il relè comunica il suo stato ad arduino? Ovvero, è possibile mediante sketch vedere se è settato in HIGH o LOW?

Se veramente ti serve conoscere lo stato del relè, devi prendere un relè con uno scambio in più così da poter avere un segnale di feedback sul suo stato.

Guglielmo

Grazie a tutti per i vostri commenti, mi hanno fatto capire alcune cose.

Lollo82:
Ciao!!! Certo che lo puoi fare.
Immagino che stai usando l'esempio webserver.
Comunque tu sai che nell'header la stringa GET inizia subito dopo il punto di domanda e termina appena incontra lo spazio (andando avanti incontro HTTP ecc...).
Questa è la funzione che mi son fatto io per leggere la stringa GET. La chiamo non appena EthernetClient client = server.available() restituisce 1. passandogli la variabile client.

bool success = readRequest(client);

Per la variabile dataGet ho previsto un buffer di 80 caratteri, ma perchè la stringa che prevedo di ricevere è lunghetta. Nel tuo caso ne bastano molti meno. Nel caso che metti come esempio 22.

bool readRequest(EthernetClient &client){

int i = 0;
 //Serial.println(client.available());
 //Controllo che il client sia connesso
 while (client.connected()){
   if (client.available()){
   char c = client.read();
   //controllo che sia iniziata la stringa GET
   if (c == '?'){
     //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
     for(i=0; i<80; i++){
       c = client.read();
       if(c!=32){
         dataGet[i] = c;
         //Serial.print(dataGet[i]);
       }else{
         dataGet[i] = '\0';
         break;
         }
     }
     while(client.available()){
         client.read();
     }
   return true;
   }
   }
 }
 return false;
}




Una volta che ho tutta la stringa GET nella variabile dataGet la gestisco con strtok_r (non con strtok perchè hai due divisori da controllare, uno è l'uguale, l'altro la e commerciale). Mentre per verificare a cosa corrisponda la variabile passata utilizzo strcmp.
Buona serata!!!

Per il secondo quesito cerco che puoi verificare lo stato del relè, creando una variabile stato che vai cambiare da high a low ogni volta che fai il digitalwrite per modificare lo stato del relè. Quando vuoi sapere lo stato basta che vai a vedere com'è settata.

Grazie per la semplice soluzione al quesito numero 1, appena avrò più tempo a disposizione proverò il codice e in caso di successo, pubblicherò in questo post lo sketch completo in caso possa servire a qualcuno con il mio stesso problema.

Patrick_M:
ancora prima con digitalRead(pin) che ti dice se il pin in questione è HIGH o LOW

... però se il programma l'hai scritto tu... devi sapere in che stato è il pin :wink:

Hai ragione, il problema è che devo collegare un sensore PIR, quindi appena lui vedrà del movimento dovrà mandare in HIGH o LOW il relè. Se con questa funzione riesco a vedere lo stato del relè, arduino "saprà" se esso è abilitato o meno e quindi mandare lo status del relè opposto a quello ottenuto.

ma non sarà il pir per conto suo ad azionare il rele, presumo che il pir sia attaccato ad arduino e quindi quando il pir rileva un movimento alza (o abbassa) un pin di arduino che a sua volta a fronte di questo ingresso attiverà o meno il rele.... quindi arduino (il tuo programma) sa sempre in che condizione è il rele (alto o basso)

Patrick_M:
ma non sarà il pir per conto suo ad azionare il rele, presumo che il pir sia attaccato ad arduino e quindi quando il pir rileva un movimento alza (o abbassa) un pin di arduino che a sua volta a fronte di questo ingresso attiverà o meno il rele.... quindi arduino (il tuo programma) sa sempre in che condizione è il rele (alto o basso)

credo che non sia esatto. Il pir è collegato ad arduino e il relè altrettanto. Quando esso rileva un movimento, io dovrò mandare in high o low il pin del relè, quindi se non so il suo stato non potrò per esempio: spegnere quando la luce è accesa, accenderla quando essa è spenta.

... ma dato che sei TU che comandi il relè ... ti salverai in una variabile il suo stato, così lo saprai sempre :smiley:

Guglielmo

gpb01:
... ma dato che sei TU che comandi il relè ... ti salverai in una variabile il suo stato, così lo saprai sempre :smiley:

Guglielmo

oppure come ti scrivevo più sopra interroghi il pin al quale è attaccato il rele
con digitalRead(pinRele)

ma in ogni caso:
quando il sensore rileva un movimento il tuo scopo è accendere la luce
(che rimarrà accesa per un certo tempo... o fino a quando il pir ti dice che non c'è più movimento)

quindi quando il pir segnala tu accendi la luce, se era gia accesa non succede nulla in quanto il rele è gia eccitato, se era spenta si accenderà

al contrario, scaduto il tempo o quando il pir non segnala più
spegni la luce, se era gia spenta non succede nulla e se era accesa si spegnerà...

Lollo82:
Ciao!!! Certo che lo puoi fare.
Immagino che stai usando l'esempio webserver.
Comunque tu sai che nell'header la stringa GET inizia subito dopo il punto di domanda e termina appena incontra lo spazio (andando avanti incontro HTTP ecc...).
Questa è la funzione che mi son fatto io per leggere la stringa GET. La chiamo non appena EthernetClient client = server.available() restituisce 1. passandogli la variabile client.

bool success = readRequest(client);

Per la variabile dataGet ho previsto un buffer di 80 caratteri, ma perchè la stringa che prevedo di ricevere è lunghetta. Nel tuo caso ne bastano molti meno. Nel caso che metti come esempio 22.

bool readRequest(EthernetClient &client){

int i = 0;
  //Serial.println(client.available());
  //Controllo che il client sia connesso
  while (client.connected()){
    if (client.available()){
    char c = client.read();
    //controllo che sia iniziata la stringa GET
    if (c == '?'){
      //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
      for(i=0; i<80; i++){
        c = client.read();
        if(c!=32){
          dataGet[i] = c;
          //Serial.print(dataGet[i]);
        }else{
          dataGet[i] = '\0';
          break;
          }
      }
      while(client.available()){
          client.read();
      }
    return true;
    }
    }
  }
  return false;
}




Una volta che ho tutta la stringa GET nella variabile dataGet la gestisco con strtok_r (non con strtok perchè hai due divisori da controllare, uno è l'uguale, l'altro la e commerciale). Mentre per verificare a cosa corrisponda la variabile passata utilizzo strcmp.
Buona serata!!!

Per il secondo quesito cerco che puoi verificare lo stato del relè, creando una variabile stato che vai cambiare da high a low ogni volta che fai il digitalwrite per modificare lo stato del relè. Quando vuoi sapere lo stato basta che vai a vedere com'è settata.

Ho provato la funzione da te scritta, con lo sketch webserver predefinito con scopo di farmi stampare la variabile success, ma il programma andava in crash. Allora l'ho un po' modificato per renderlo ancora più semplice, ma quando interrogo arduino non riceve nessuna risposta.
Posto qua il pezzo di codice

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  bool success = readRequest(client);
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // 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
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<body>");
          // output the value of each analog input pin
            client.print(success);
            client.println("</body>");
          client.println("</html>");
          break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}
bool readRequest(EthernetClient &client){
  int i = 0;
  //Serial.println(client.available());
  //Controllo che il client sia connesso
  while (client.connected()){
    if (client.available()){
    char c = client.read();
    //controllo che sia iniziata la stringa GET
    if (c == '?'){
      //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
      for(i=0; i<80; i++){
        c = client.read();
        if(c!=32){
          dataGet[i] = c;
          //Serial.print(dataGet[i]);
        }else{
          dataGet[i] = '\0';
          break;
          }
      }
      while(client.available()){
          client.read(); 
      }
    return true;
    }
    } 
  }
  return false; 
}

Puoi postare l’errore che ti dava? Hai dichiarato la variabile chat dataget[30] ???

Lollo82:
Puoi postare l’errore che ti dava? Hai dichiarato la variabile chat dataget[30] ???

Sisi, l'ho impostata a 22. Lo sketch non presenta alcun errore, però quando interrogo arduino da browser non ricevo alcuna risposta html (la pagina ovviamente non viene caricata). Es: quando si interroga un host che non riesce a gestire la richiesta

Quando sono a casa dò un’occhiata a quello che hai postato. Guardato alla svelta non mi convince.

Ciao!!! Prova questo codice.
Da correggere con i tuoi parametri di connessione.

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

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0xB2, 0x22
};

EthernetServer server(80);
//ho messo un buffer di 30 per avere della tolleranza sulla lunghezza della stringa. A 22
//non ci sarebbe stato il carattere terminatore '\0'
char dataGet[30];  
bool readRequest(EthernetClient &client){
  int i = 0;
  //Serial.println(client.available());
  //Controllo che il client sia connesso
  while (client.connected()){
    if (client.available()){
    char c = client.read();
    //controllo che sia iniziata la stringa GET
    if (c == '?'){
      //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
      for(i=0; i<80; i++){
        c = client.read();
        if(c!=32){
          dataGet[i] = c;
          //Serial.print(dataGet[i]);
        }else{
          dataGet[i] = '\0';
          break;
          }
      }
      while(client.available()){
          client.read(); 
      }
    return true;
    }
    } 
  }
  return false; 
}

void writeResponse(EthernetClient &client){
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");
  client.println();
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
}

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  //Attendo la richiesta del client
  if (client) {
    Serial.println(F("Nuovo client"));
    bool success = readRequest(client);
    Serial.print(F("Richiesta eseguita"));
    //Se la richiesta viene correttamente processata scrivo il responso
    if (success){
      writeResponse(client);
  }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println(F("client disconnected"));
    Serial.println(dataGet);
  }
}

Lollo82:
Ciao!!! Prova questo codice.
Da correggere con i tuoi parametri di connessione.

#include <SPI.h>

#include <Ethernet.h>

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0xB2, 0x22
};

EthernetServer server(80);
//ho messo un buffer di 30 per avere della tolleranza sulla lunghezza della stringa. A 22
//non ci sarebbe stato il carattere terminatore '\0'
char dataGet[30]; 
bool readRequest(EthernetClient &client){
  int i = 0;
  //Serial.println(client.available());
  //Controllo che il client sia connesso
  while (client.connected()){
    if (client.available()){
    char c = client.read();
    //controllo che sia iniziata la stringa GET
    if (c == '?'){
      //Fino a che non incontro lo spazio che termina la query GET aggiungo i caratteri a dataGet
      for(i=0; i<80; i++){
        c = client.read();
        if(c!=32){
          dataGet[i] = c;
          //Serial.print(dataGet[i]);
        }else{
          dataGet[i] = '\0';
          break;
          }
      }
      while(client.available()){
          client.read();
      }
    return true;
    }
    }
  }
  return false;
}

void writeResponse(EthernetClient &client){
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");
  client.println();
  client.println("");
  client.println("");
}

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  //Attendo la richiesta del client
  if (client) {
    Serial.println(F("Nuovo client"));
    bool success = readRequest(client);
    Serial.print(F("Richiesta eseguita"));
    //Se la richiesta viene correttamente processata scrivo il responso
    if (success){
      writeResponse(client);
  }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println(F("client disconnected"));
    Serial.println(dataGet);
  }
}

grazie mille. Il codice eccetto qualche piccolo errore, funziona correttamente e adesso ne sto modellando uno per le mie esigenze.
Grazie a tutti per le risposte.

Bene son contento che puoi procedere. Figurati, ci mancherebbe altro.