Funzione GET x prendere valori dall'url di una pagina HTML

Ciao Ragazzi,
ho nella SD di arduino un file index.htm.
Quando clicco nel pulsante salva della pagina htm, mi riporta nell'url tutti i parametri precedentemente impostati nella pagina stessa.
Tramite arduino dovrei andare a prendere questi dati nell'url della pagina html.
Come posso fare??
Negli esempi in internet ho visto che si usano server, ma questo non è un sito internet, è una pagina html nella SD

Grazie mille ragazzi
Confido in voi!!!!

Guarda io ho fatto cosi..... ti posto quello che devi scrivere nel file HTM e quello che devi scrivere nello sketch per recuperare i parametri.

su Htm
su sketch es

if (query.indexOf("accendi37") > 0) {
            digitalWrite(37,HIGH);}

spero ti sia di aiuto.

ah scusa naturalmente devi avere in tutti i punti la stessa numerazione....

scusa query.indexof cosa fa???? ....mi daresti un po' più di codice che non riesco a capire??? grazie mille

query.indexOf non fa altro che recuperare la stringa che tu invii dal url...
Ovvero mettiamo che l'indirizzo della tua macchina sia http://192.168.2.179/?accendi5=ON l'ultima parte dopo il punto interrogativo verrà elaborata e prelevata da query.indexOf che accenderà il tuo led o altro

Ho capito.....così però posso lavorarare solo con un paramentro per volta, oppure madare n parametri nell'url???
Cioè ti spiego....
quando schiacci SALVA, nel mio Url dovrei mandare più parametri in un sol colpo, e dovrei prenderli tutti tramite arduino.
Questo si può fare con il metodo sopra descritto??

sausim:
Ho capito.....così però posso lavorarare solo con un paramentro per volta, oppure madare n parametri nell'url???
Cioè ti spiego....
quando schiacci SALVA, nel mio Url dovrei mandare più parametri in un sol colpo, e dovrei prenderli tutti tramite arduino.
Questo si può fare con il metodo sopra descritto??

La cosa più logica per avere una quantità alta di dati nella get sarebbe mandare per es:
http://192.168.2.179/?122,145,163,blabla,40,12,5,184,74,245,140,215,19 e farne poi lo split della ',' il tutto te lo ritroverai in una array
split[0] ci sarà 122
split[1] ci sarà 145
split[2] ci sarà 163
split[3] ci sarà blabla
...
...
split[12] ci sarà 19

la ',' è solo un simbolo usato come separatore, se servono numeri con la ',' si possono usare altri simboli a piacere ad es # o @ ecc

Es: http://192.168.2.179/?122,14#145,45#163,74#blabla#40#12#5#184#74#245#140#215#19

hai qualche codice per prenderci spunto???

si ma con get non hai solo 255 caratteri a disposizione da mandare?

si ma mi bastano.......mi puoi mandare l'esempio???

davideanubi:
si ma con get non hai solo 255 caratteri a disposizione da mandare?

nell'esempio sono meno di 60 char

non ho un esempio fatto su uno sketch, io lo split lo uso dalla parte client sul jquery-javascript con 8 byte vedo lo status di 70 pin, al massimo rispedisco verso il server 1 byte che ne gestisce 8 alla volta per mia comodità, ma nessuno mi impedisce di mandarne di più, perchè dovrei mandarne di più? la paginetta web serve per la visualizzazione in realtime di quello che accade nel server, al massimo quando premo un tastino ne devo attivare uno mica 10 o 20.

se vuoi controllare 8 pin in uno solo byte tramite http usa la manipolazione dei registri.
inviando per es: http://192.168.2.179/?255 posso assegnare il valore 255 al PORTD e accenderli tutti ... valore 0 spegnerli tutti oppure valori intermedi che accendono e spengono dei led secondo logica binaria.

dipende tutto da cosa uno vuole fare e scegliere la strada migliore e meno complessa, anche con indexof puoi gestire più chiavi contenute nella stessa stringa get, puoi mettere anche dei simboli differenti che ne delimitano le parti
es http://192.168.2.179/?255@blabla#125*540§ e usare questi simboli @#*§ come separatori.

Ripeto, se non si sa quale deve essere il risultato non si può dare una risposta adeguata, i metodi sono illimitati nel trattare le stringhe si costruiscono si spediscono e si smontano

Se cerchi come usare lo split .... google "arduino split"

ciao

Con tinywebserver è possibile prendere l'url e poi lavorarlo????

sausim:
Con tinywebserver è possibile prendere l'url e poi lavorarlo????

si, ma non lo fa solo quello

eccoti un esempio base presente anche nele cartelle dell'ide, ti ho aggiunto 2 pulsanti giusto per farti vedere il risultato dell'url sul serial.print

/*
  Web Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 */

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2, 177);

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

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
   String pacchetto;
    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();
        pacchetto += (char)c;
        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
        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("Connection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          //client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");          
          }
          client.println("</html>");
          client.print("<input type=\"button\" style=\"width:120px; height:80px\" value=\"On\" onclick =\" location.href='/?on_2'\">");
         client.print("<input type=\"button\" style=\"width:120px; height:80px\" value=\"Off\" onclick =\" location.href='/?off_2'\">");  
          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;
        }
      }
    }
pacchetto="";
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

if (client.available()) {
char c = client.read();
non si limita a leggere solo off_2 ma è un pacchtto con molte informazioni

  • Tipo di richiesta GET,POST,PUT, ecc
  • user-agent descrive il client che fa la richiesta, come vedi mi sono connesso con un windows nt6.1, windows a 64bit e il browser è Firefox
  • accept ti descrive il content-type text/html
  • language decodifiche ecc ecc
  • se aggiungessimo i popup di autenticazione, qui dentro ci sarebbero anche le chiavi a base64 dell' username and passw

risultato nel serial dopo la pressione del tasto da browser

server is at 192.168.2.177
new client
GET /?on_2 HTTP/1.1 >>>>>> GET attuale
Host: 192.168.2.177
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.2.177/?off_2 >>> GET precedente
Connection: keep-alive

client disconnected

sausim:
scusa query.indexof cosa fa???? ....mi daresti un po' più di codice che non riesco a capire??? grazie mille

La richiesta arriva sottoforma di caratteri seriali, uno alla volta e la riga "pacchetto += (char)c;" ha il compito di salvare tutti i char in un unica stringa. Questa stringa "pacchetto" come vedi è lunga e occupa molti byte mettendo a rischio la ram, andrebbe lavorata un po meglio e salvare solo il necessario, un altro accorgimento è quella di non dichiararla pubblica

"indexof" cerca in tutta la stringa il pezzo che tu vuoi vedere se esiste....
Se è contenuto all'interno della stringa ti restutisce la posizione inziale
Se non esiste la sequenza esatta ti restituisce -1

stringa = "ciao mondo e ciao universo";
int posizione = stringa.indexOf("mondo"); // cerchiamo mondo
il risultato sarà
5 quinto carattere dalla pos iniziale

se cerchi "ciao" essendocene 2 ti restituisce la posiz solo del primo

vedi:
indexOf
Substring
string.length()
LastIndexOf

Ultima cosa: se non vuoi vedere sulla barra degli indirizzi "http://192.168.2.177/?off_2" nell' html costruisci un form con metodo POST

con la libreria Tinywebserver che mi carica anche le immagini della mia pagina html,come posso fare a prendere l'url???

Questo è il mio url iniziale:
192.168.0.12/index.htm

Questo è il mio url quando clicco nel pulsante SALVA:
http://192.168.0.12/index.htm?addr1=1&addr3=2&addr3=5&addr4=7

Io mi dovrei prendere i seguenti valori appunto con Tinywebserver:
addr1=1
addr1=3
addr1=4
addr1=7

Grazie mille

Perchè usi la tiny che è pesante come lib per poi fare quello che fa un semplice esempio webserver. La tinywebserver non è stata pensata con questo criterio, lo fa tramite ajax metodo POST

la funzione che invia il dato potrebbe essere tipo questa

 function send() 
 {
    $.ajax({
      type: "POST",
	    data: "addr1=1&addr3=2&addr3=5&addr4=7",
	    dataType: "text",
	    cache: false,
	    url: "/SEND",
	    success: function(r){ },
	    error: function() {  }
	   });
};

nello sketch ti ritrovi comunque nella stessa situazione identica che ho postato sopra cercare questa stringa "addr1=1&addr3=2&addr3=5&addr4=7" nel pacchetto

if (client.available()) {
        char c = client.read();
        pacchetto += (char)c;
        Serial.write(c);
        ...
        ...

usi la tiny perchè carica i file da SD?
ti basta aggiungere poche righe per inviare la pagina htm agli esempi webserver dentro l'IDE

 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("Connection: close");
                    client.println();
                    //------------------invia pagina index.htm------------------------------------
                    webFile = SD.open("index.htm");       
                    if (webFile) {
                        while(webFile.available()) {
                            client.write(webFile.read()); 
                        }
                        webFile.close();
                    //-------------------------------------------------------------------------------
                    }
                    break;
                }            
                if (c == '\n') {  
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {    
                    currentLineIsBlank = false;
                }
            } 
        }
        delay(1);     
        client.stop();
    } 
}

Scusa ma non riesco proprio a prendere i dati..anche perche sono nuovo in arduino.
ti allego il file html.
quello che devo fare è questo:
quando scrivo l'indirizzo ip nel mio browser, impostato di default in arduino,il programma mi carica il file html che si trova nella mia SD.
Quando clicco su SALVA, arduino mi riporta tutti i parametri con i valori assegnati nell'url. io li devo prendere e salvarli nella eeprom.

Ti allego il file html in modo tale che mi puoi aiutare meglio.
Ti allego anche le immagini che la pagina html deve caricare...considera che ho fatto delle prove, e tinywebserver è l'unica libreria che sia riuscita a caricarmi le immagini.

Grazie mille

down_45.gif

index.htm (3.8 KB)

down_03.jpg

Manca il file javascript file.js che fa da tramite tra html e arduino se hai visto l'esempio tiny l'avrai notato

ciao

il file .js dovrebbe servire per fare appunto la comunicazione tra arduino e html....io non devo comunicare con l'html, cioè non devo aggiornare la pagine o i valori dell' html...io ho già tutto dentro l'SD e nel browser...con arduino devo fare solo la get per prendere l'url, ma non ho esempi con tinywebserver.

Ho capito che non vuoi uno scambio continuo, ma la tinywebserver lavora su questi riconoscimenti

 {"/", TinyWebServer::GET, &index_handler },
  {"/SEND", TinyWebServer::POST, &blink_led_handler },
  {"/ledstatus" "*", TinyWebServer::GET, &led_status_handler },
  {"/" "*", TinyWebServer::GET, &file_handler },
  {NULL},
};

qualsiasi cosa metti di diverso da questi prefissi viene interpretato come errore a parte questo {"/" "*" che lo interpreta come nome del file, se esiste te lo manda altrimenti da errore es: 192.168.0.12/pippo.txt te lo visualizza sulla pag html

devi usare la funzione
boolean blink_led_handler(TinyWebServer& web_server) {
che riceve i dati dal client, per mandarglieli dovresti usare sul js che ho scritto qualche post indietro

 function send() 
 {
    $.ajax({
      type: "POST",
	    data: "addr1=1&addr3=2&addr3=5&addr4=7",
	    dataType: "text",
	    cache: false,
	    url: "/SEND",
	    success: function(r){ },
	    error: function() {  }
	   });
};

funzione collegata al pulsante "salva" che invia i dati contenuti nei campi <input .....

se tu invii http://192.168.0.12/index.htm?addr1=1&addr3=2&addr3=5&addr4=7 la tiny ti butta fuori, non lo riconosce
puoi mettere lo sketch che hai modificato del tiny?

// -*- c++ -*-
//
// Copyright 2010 Ovidiu Predescu <ovidiu@gmail.com>
// Date: June 2010
// Updated: 08-JAN-2012 for Arduno IDE 1.0 by <Hardcore@hardcoreforensics.com>
//

#include <pins_arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Flash.h>
#include <SD.h>
#include <TinyWebServer.h>

/****************VALUES YOU CHANGE*************/
// pin 4 is the SPI select pin for the SDcard
const int SD_CS = 4;

// pin 10 is the SPI select pin for the Ethernet
const int ETHER_CS = 10;

// Don't forget to modify the IP to an available one on your home network
byte ip[] = { 192, 168, 0, 12 };
/*********************************************/

static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

boolean file_handler(TinyWebServer& web_server);
boolean index_handler(TinyWebServer& web_server);
boolean read_url_param(TinyWebServer& web_server);//sauro

TinyWebServer::PathHandler handlers[] = {
  // Work around Arduino's IDE preprocessor bug in handling /* inside
  // strings.
  //
  // `put_handler' is defined in TinyWebServer
  {"/", TinyWebServer::GET, &index_handler },
  {"/upload/" "*", TinyWebServer::PUT, &TinyWebPutHandler::put_handler },
  {"/" "*", TinyWebServer::GET, &file_handler },
  {"/index.htm?" "*", TinyWebServer::GET, &read_url_param },//sauro
  {NULL},
};

const char* headers[] = {
  "Content-Length",
  NULL
};

TinyWebServer web = TinyWebServer(handlers, headers);

boolean has_filesystem = true;
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;


//_________________________________________________________________________________________________________________________________________________________________________
void send_file_name(TinyWebServer& web_server, const char* filename) {
Serial.print ("1");
  if (!filename) {
    web_server.send_error_code(404);
    web_server << F("Could not parse URL");
  } else {
    TinyWebServer::MimeType mime_type
      = TinyWebServer::get_mime_type_from_filename(filename);
    web_server.send_error_code(200);
    web_server.send_content_type(mime_type);
    web_server.end_headers();
    if (file.open(&root, filename, O_READ)) {
      Serial << F("Read file "); Serial.println(filename);
      web_server.send_file(file);
      file.close();
    } else {
      web_server << F("Could not find file: ") << filename << "\n";
    }
  }
}

//__________________________________________________________________________________________________________________________________________________________________________
boolean file_handler(TinyWebServer& web_server) {
Serial.print ("2");
  char* filename = TinyWebServer::get_file_from_path(web_server.get_path());
  send_file_name(web_server, filename);
  free(filename);
  return true;
}

//__________________________________________________________________________________________________________________________________________________________________________
boolean index_handler(TinyWebServer& web_server) {
Serial.print ("3");
  send_file_name(web_server, "INDEX.HTM");
  return true;
}

//__________________________________________________________________________________________________________________________________________________________________________
void file_uploader_handler(TinyWebServer& web_server,
			   TinyWebPutHandler::PutAction action,
			   char* buffer, int size) {
  
  static uint32_t start_time;
  static uint32_t total_size;

Serial.print ("4");
  switch (action) {
  case TinyWebPutHandler::START:
    start_time = millis();
    total_size = 0;
    if (!file.isOpen()) {
      // File is not opened, create it. First obtain the desired name
      // from the request path.
      char* fname = web_server.get_file_from_path(web_server.get_path());
      if (fname) {
	Serial << F("Creating ") << fname << "\n";
	file.open(&root, fname, O_CREAT | O_WRITE | O_TRUNC);
	free(fname);
      }
    }
    break;

  case TinyWebPutHandler::WRITE:
    if (file.isOpen()) {
      file.write(buffer, size);
      total_size += size;
    }
    break;

  case TinyWebPutHandler::END:
    file.sync();
    Serial << F("Wrote ") << file.fileSize() << F(" bytes in ")
	   << millis() - start_time << F(" millis (received ")
           << total_size << F(" bytes)\n");
    file.close();
  }
}




//_________________________________________________________________________________________________________________________________________________________________________
void setup() {
  Serial.begin(9600);
  Serial << F("Free RAM: ") << FreeRam() << "\n";
  
  pinMode(SS_PIN, OUTPUT);	// set the SS pin as an output
                                // (necessary to keep the board as
                                // master and not SPI slave)
  digitalWrite(SS_PIN, HIGH);   // and ensure SS is high

  // Ensure we are in a consistent state after power-up or a reset
  // button These pins are standard for the Arduino w5100 Rev 3
  // ethernet board They may need to be re-jigged for different boards
  pinMode(ETHER_CS, OUTPUT);	// Set the CS pin as an output
  digitalWrite(ETHER_CS, HIGH);	// Turn off the W5100 chip! (wait for
                                // configuration)
  pinMode(SD_CS, OUTPUT);	// Set the SDcard CS pin as an output
  digitalWrite(SD_CS, HIGH);	// Turn off the SD card! (wait for
                                // configuration)

  // initialize the SD card.
  Serial.println("Setting up SD card...\n");
  // pass over the speed and Chip select for the SD card
  if (!card.init(SPI_FULL_SPEED, SD_CS)) {
    Serial.println("card failed\n");
    has_filesystem = false;
  }
  // initialize a FAT volume.
  if (!volume.init(&card)) {
    Serial.println("vol.init failed!\n");
    has_filesystem = false;
  }
  if (!root.openRoot(&volume)) {
    Serial.println("openRoot failed");
    has_filesystem = false;
  }

  if (has_filesystem) {
    // Assign our function to `upload_handler_fn'.
    TinyWebPutHandler::put_handler_fn = file_uploader_handler;
  }


  // Initialize the Ethernet.
  Serial.println("Setting up the Ethernet card...\n");
  Ethernet.begin(mac, ip);

  // Start the web server.
  Serial.println("Web server starting...\n");
  web.begin();


  Serial.println("Ready to accept HTTP requests.\n");
}

 
//_________________________________________________________________________________________________________________________________________________________________________
void loop() {
  if (has_filesystem) {
    web.process();
  }
}

per favore includi il codice usando gli appositi tag, grazie