Reading a URI

Im working with the arduino uno and ethernet shield W5100.

Im trying to find some code which will read a URL and put that into three custom variables.

When I call the url 192.168.1.102?var1=100&var2=101&var3=102 the serial monitor returns GET /?var1=100&var2=101&var3=102 HTTP/1.1 for the following code:

Serial.println(readString.indexOf("?"))

What I want to do is read the values of the variable in the URI and put it in three different variables. How can I do this?

When I call the url 192.168.1.102?var1=100&var2=101&var3=102 the serial monitor returns GET /?var1=100&var2=101&var3=102 HTTP/1.1 for the following code:

No, it doesn't. The indexOf() function returns an int. "GET /?var1=100&var2=101&var3=102 HTTP/1.1" is not an int.

Post all of your code.

You're right, after shuffling around that line of code its returning "5" so now I'm more baffled than before. It is returning the line I quoted, but I was being a bit dopey as its in a If statement.

Heres the full code, sorry if its a bit messy.

//zoomkat 12-8-11
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port

Servo servo1;  // create servo object to control a servo 
Servo servo2;  // create servo object to control a servo 

String readString; 

//////////////////////

void setup(){
  servo1.attach(7);  // attaches the servo on pin 7 to the servo object 
  servo2.attach(8);  // attaches the servo on pin 8 to the servo object 
  pinMode(9, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server LED test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println();  
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Location Clock 0.1.1</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Location Clock 0.1.1</H1>");
          
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>"); 
          client.println("<a href=\"/?off#the#wall\" target=\"inlineframe\">OFF</a>"); 

          //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
          client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


            

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            Serial.println("[begin URI]");
            Serial.println(readString.indexOf("?"));
            Serial.println("[end URI]");
            
            digitalWrite(9, HIGH);    // set pin 9 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(9, LOW);    // set pin 9 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

When you enter a URL in a browser, the browser software converts the URL to a GET request. That is where the "GET /?var1=100&var2=101&var3=102 HTTP/1.1" is coming from.

The call to indexOf() is missing from this code, but what it does is find the position of the ? in "GET /?var1=100&var2=101&var3=102 HTTP/1.1". 0 is G, 1 is E, etc., so the ? is in position 5.

You could create a substring of the rest of the data in readString, or you could locate the & that ends the first name=value token. Create a substring that contains just the first name=value token.

Then, you can separate the name=value token into name and value tokens, and them convert the value token to a number, using atoi(). Store that number somewhere based on the name token.

Thank you PaulS, you've solved a problem I was unaware of, and substring was the solution to the rest of it.

I've used substring to read in the segments from the GET request of 192.168.1.102?user=123456789&pass=123456789&servo1=123&servo2=456&servo3=789, the segment of code reads:

            Serial.println("[begin URI]");
            Serial.println(readString); //print to serial monitor for debuging 
            Serial.println("[end URI]");
            Serial.println("[begin servo positions]");
            Serial.println("servo1: " + readString.substring(43,46));
            Serial.println("servo2: " + readString.substring(54,57));
            Serial.println("servo3: " + readString.substring(65,68));
            Serial.println("[end servo positions]");

Which displays in the serial monitor as:

[begin URI]
GET /?user=123456789&pass=123456789&servo1=123&servo2=456&servo3=789 HTTP/1.1

[end URI]
[begin servo positions]
servo1: 123
servo2: 456
servo3: 789
[end servo positions]

Thank you again.
My full code now reads:

//zoomkat 12-8-11
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port

Servo servo1;  // create servo object to control a servo 
Servo servo2;  // create servo object to control a servo 

String readString; 

//////////////////////

void setup(){
  servo1.attach(7);  // attaches the servo on pin 7 to the servo object 
  servo2.attach(8);  // attaches the servo on pin 8 to the servo object 
  pinMode(9, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server LED test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println();  
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Location Clock 0.1.1</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Location Clock 0.1.1</H1>");
          
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>"); 
          client.println("<a href=\"/?off#the#wall\" target=\"inlineframe\">OFF</a>"); 

          //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
          client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

            Serial.println("[begin URI]");
            Serial.println(readString); //print to serial monitor for debuging 
            Serial.println("[end URI]");
            Serial.println("[begin servo positions]");
            Serial.println("servo1: " + readString.substring(43,46));
            Serial.println("servo2: " + readString.substring(54,57));
            Serial.println("servo3: " + readString.substring(65,68));
            Serial.println("[end servo positions]");
            

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {

            
            digitalWrite(9, HIGH);    // set pin 9 high
            Serial.println("Led On");
          }
          
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(9, LOW);    // set pin 9 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

The below link has info on some string operations that can be used in various ways to get information from the string. Below is some simple serial monitor code that can be used for parse testing using the serial monitor.

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(2);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);
////do parse testing here



//////
    readString="";
  } 
}