String Parsing - What am I messing up?

I have an input box on my web interface that gives me this in the serial monitor.
GET /?LEDWHITE=100&submit=Send+White+LED+Level HTTP/1.1

I want to parse the number out of the string. I tried:

  Serial.println(readString);
  int pos1 = readString.indexOf('=');
  int pos2 = readString.indexOf('&');
  newString = readString.substring(pos1 + 1, pos2);
  Serial.print("newString is: ");
  Serial.println(newString);

I get nothing? When I print the variable I literally get no value.
This code was lifted from an example I found online so I have no idea what I messed up.

It's impossible to tell from the snippet you posted, but did you remember a Serial.begin() ?

Sorry I will post the entire code.

#include <ESP8266WiFi.h>
#include <time.h>

// Wifi Settings
const char* ssid = "PrettyFlyForAWifi";
const char* password = "reidbuck";
WiFiServer server(80);

// Time Settings
int timezone = 3;
int dst = 0;

// LED Settings
int blueLedPin = 5;
int blueLedOn = 4;
int blueLevel = 1000;

int whiteLedPin = 0;
int whiteLedOn = 2;
int whiteLevel = 1000;

String readString, newString, whiteString;



void setup() {
  pinMode(blueLedPin, OUTPUT);
  pinMode(blueLedOn, OUTPUT);
  pinMode(whiteLedPin, OUTPUT);
  pinMode(whiteLedOn, OUTPUT);
  Serial.begin(115200);
  delay(10);


  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  // Time Config
  configTime(3 * 1200, 0, "pool.ntp.org");
  Serial.println("\nWaiting for time");
  while (!time(nullptr)) {
    Serial.print(".");
    delay(1000);
  }

  // Turn off LEDS ON BOOT

  digitalWrite(blueLedOn, LOW);
  digitalWrite(whiteLedOn, LOW);
}

void loop() {

  // Get time
  time_t now = time(nullptr);
  Serial.println(ctime(&now));
  delay(1000);

  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while (!client.available()) {
    delay(1);
  }



  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  //  LED Control
  int value = LOW;


  if (request.indexOf("/blueLED=ON") != -1)  {
    digitalWrite(blueLedOn, HIGH);
    analogWrite(blueLedPin, blueLevel);
    value = HIGH;
  }
  if (request.indexOf("/blueLED=OFF") != -1)  {
    digitalWrite(blueLedOn, LOW);
    value = LOW;
  }

  if (request.indexOf("/whiteLED=ON") != -1)  {
    digitalWrite(whiteLedOn, HIGH);
    analogWrite(whiteLedPin, blueLevel);
    value = HIGH;
  }
  if (request.indexOf("/whiteLED=OFF") != -1)  {
    digitalWrite(whiteLedOn, LOW);
    value = LOW;
  }

  // New Bit
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();

  client.println("<HTML>");
  client.println("<HEAD>");
  client.println("<TITLE>LED Control Module</TITLE>");
  client.println("</HEAD>");
  client.println("<BODY>");

  client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

  client.println("Set LED LEVELS: <INPUT TYPE=TEXT NAME='LEDWHITE' VALUE='' SIZE='25' MAXLENGTH='50'>
");

  client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Send White LED Level'>");

  client.println("</FORM>");

  client.println("
");


  // Blues
  client.print("The Time is now : ");
  client.print(ctime(&now));
  client.print("Blue Leds are now: ");

  if (value == HIGH) {
    client.print("On");
  } else {
    client.print("Off");
  }
  client.println("

");
  client.println("<a href=\"/blueLED=ON\"\"><button>Turn Blue Leds On </button></a>");
  client.println("<a href=\"/blueLED=OFF\"\"><button>Turn Blue Leds Off </button></a>
");
  client.println("</html>");

  // Whites

  client.print("White Leds are now: ");

  if (value == HIGH) {
    client.print("On");
  } else {
    client.print("Off");
  }
  client.println("

");
  client.println("<a href=\"/whiteLED=ON\"\"><button>Turn White Leds On </button></a>");
  client.println("<a href=\"/whiteLED=OFF\"\"><button>Turn White Leds Off </button></a>
");
  client.println("</html>");

  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");

  //read char by char HTTP request
  Serial.println(readString);
  int pos1 = readString.indexOf('=');
  int pos2 = readString.indexOf('&');
  newString = readString.substring(pos1 + 1, pos2);
  Serial.print("newString is: ");
  Serial.println(newString);
}

Where do you ever assign a value to readString?

You know I don't think I do. Thanks! As I say it was a copy from a demo code I found, then again I dont see where they did either...

Here is there code

//zoomkat 6-13-15
//get submit box 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 or use a '
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//Powering a servo from the arduino usually *DOES NOT WORK*.

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 
//int n; //value to write to servo

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(84); //server port

String readString, newString;

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

void setup(){

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("server text box servo test"); // 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.print(readString); //see what was captured

          //now output HTML data header

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>HTML form GET example</H1>");

          client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

          client.println("Set servo position: <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'>
");

          client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Send servo position'>");

          client.println("</FORM>");

          client.println("
");

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

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

          /////////////////////
          if (readString.length() >0) {
            //Serial.println(readString); //prints string to serial port out
            int pos1 = readString.indexOf('=');
            int pos2 = readString.indexOf('&');
            newString = readString.substring(pos1+1, pos2);
            Serial.print("newString is: ");
            Serial.println(newString);
            int n = newString.toInt();
            Serial.print("The value sent is: ");
            Serial.println(n);
            readString=""; //clears variable for new input    
            newString=""; //clears variable for new input
            // auto select appropriate value
            if(n >= 500)
            {
              Serial.print("writing Microseconds: ");
              Serial.println(n);
              myservo.writeMicroseconds(n);
              Serial.println();
            }
            else
            {   
              Serial.print("writing Angle: ");
              Serial.println(n);
              myservo.write(n); 
              Serial.println();
            }
          }           
        }
      }
    }
  }
}

You know I don't think I do.

I know that you don't.

dont see where they did either...

          //store characters to string
          readString += c;

You added another String, request, where you store the data. You never add data to readString, and you don't parse request. I see no reason to have two Strings. That's two too many.

I guess as I could see the string in the serial monitor I figured I had...

Two being too many has confused me though. Surely I need one string?

How would you go about this problem. I want an input box on the web interface, you add a number as a percentage and I can then make that the brightness of the LED in question. Its got messy and hacky thus far :frowning:

Surely I need one string?

Exactly. You need one string and zero Strings.

String and string are completely different things.

Actually, you may not even need a string. You know what character marks the start of the value. When you see that marker, set some variable to 0 and set a flag that indicates that "recording" is happening. Read the next character. If "recording", and the character is not the "stop recording" character, multiply the variable you set to 0 by 10 and add the new character as a digit. If the character IS the "stop recording" character, stop recording.

bool recording = false;
int brightnessVal;
char startMarker = '=';
char endMarker = '&';
while(client.connected())
{
   while(client.available() > 0)
   {
      char c = client.read();
      if(c == startMarker)
      {
         recording = true;
         brightnessVal = 0;
      }
      else if(c == endMarker)
      {
         recording = false;
      }
      else
      {
         if(recording)
         {
            if(isdigit(c))
            {
               brightnessVal *= 10;
               brightnessVal += c - '0';
             }
             else
                recording = false;
         }
      }
   }
}

The isdigit() test makes sure that the S in Send, after the 2nd equal sign doesn't mess up brightnessVal (and that the 1.1 at the end don't result in brightness being 10011).

I am sorry I dont it :frowning:

I understand that were looking for the start point and starting to "record" then on the end point stopping "recording" but I dont get how the variable brightnessVal gets set during this recording...

thegasman2000:
I am sorry I dont it :frowning:

I understand that were looking for the start point and starting to "record" then on the end point stopping "recording" but I dont get how the variable brightnessVal gets set during this recording...

In your example:

GET /?LEDWHITE=100&submit=Send+White+LED+Level HTTP/1.1

c will be 'G' first. That's not the start marker, so recording doesn't happen.
c will then be 'E'. That's not the start marker, so recording doesn't happen.
c will then be 'T'. That's not the start marker, so recording doesn't happen.
c will then be ' '. That's not the start marker, so recording doesn't happen.
c will then be '/'. That's not the start marker, so recording doesn't happen.
c will then be '?'. That's not the start marker, so recording doesn't happen.

Eventually, c gets to be '=', so recording happens, and brightnessVal is set to 0.

c will then be '1', which is not the start marker, is not the end marker, and is a digit. So, brightnessVal is multiplied by 10, becoming 0, and '1' - '0' is added. Since '1' - '0' is 1, brightnessVal is now 1.

c will then be '0', which is not the start marker, is not the end marker, and is a digit. So, brightnessVal is multiplied by 10, becoming 10, and '0' - '0' is added. Since '0' - '0' is 0, brightnessVal is now 10.

c will then be '0', which is not the start marker, is not the end marker, and is a digit. So, brightnessVal is multiplied by 10, becoming 100, and '0' - '0' is added. Since '0' - '0' is 0, brightnessVal is now 100.

c will then be '&', which is not the start marker but is the end marker, so recording stops, and brightnessVal is complete.

Ok so I have added this and tested it and I am not seeing the "breakpoint" I added " Serial.println("RECORDING White Level is = ");"

#include <ESP8266WiFi.h>
#include <time.h>

// Wifi Settings
const char* ssid = "PrettyFlyForAWifi";
const char* password = "reidbuck";
WiFiServer server(80);

// Time Settings
int timezone = 3;
int dst = 0;

// LED Settings
int blueLedPin = 5;
int blueLedOn = 4;
int blueLevel = 1000;

int whiteLedPin = 0;
int whiteLedOn = 2;
int whiteLevel = 100;

bool recording = false;
int brightnessVal;
char startMarker = '=';
char endMarker = '&';



void setup() {
  pinMode(blueLedPin, OUTPUT);
  pinMode(blueLedOn, OUTPUT);
  pinMode(whiteLedPin, OUTPUT);
  pinMode(whiteLedOn, OUTPUT);
  Serial.begin(115200);
  delay(10);


  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  // Time Config
  configTime(3 * 1200, 0, "pool.ntp.org");
  Serial.println("\nWaiting for time");
  while (!time(nullptr)) {
    Serial.print(".");
    delay(1000);
  }

  // Turn off LEDS ON BOOT

  digitalWrite(blueLedOn, LOW);
  digitalWrite(whiteLedOn, LOW);
}

void loop() {

  // Get time
  time_t now = time(nullptr);
  Serial.println(ctime(&now));
  delay(1000);

  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  //  LED Control
  int value = LOW;


  if (request.indexOf("/blueLED=ON") != -1)  {
    digitalWrite(blueLedOn, HIGH);
    analogWrite(blueLedPin, blueLevel);
    value = HIGH;
  }
  if (request.indexOf("/blueLED=OFF") != -1)  {
    digitalWrite(blueLedOn, LOW);
    value = LOW;
  }

  if (request.indexOf("/whiteLED=ON") != -1)  {
    digitalWrite(whiteLedOn, HIGH);
    analogWrite(whiteLedPin, blueLevel);
    value = HIGH;
  }
  if (request.indexOf("/whiteLED=OFF") != -1)  {
    digitalWrite(whiteLedOn, LOW);
    value = LOW;
  }

  // New Bit
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();

  client.println("<HTML>");
  client.println("<HEAD>");
  client.println("<TITLE>LED Control Module</TITLE>");
  client.println("</HEAD>");
  client.println("<BODY>");

  client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

  client.println("Set LED LEVELS: <INPUT TYPE=TEXT NAME='LEDWHITE' VALUE='' SIZE='25' MAXLENGTH='50'>
");

  client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Send White LED Level'>");

  client.println("</FORM>");

  client.println("
");


  // Blues
  client.print("The Time is now : ");
  client.print(ctime(&now));
  client.print("Blue Leds are now: ");

  if (blueLedPin == HIGH) {
    client.print("On");
  } else {
    client.print("Off");
  }
  client.println("

");
  client.println("<a href=\"/blueLED=ON\"\"><button>Turn Blue Leds On </button></a>");
  client.println("<a href=\"/blueLED=OFF\"\"><button>Turn Blue Leds Off </button></a>
");
  client.println("</html>");

  // Whites

  client.print("White Leds are now: ");

  if (whiteLedPin == HIGH) {
    client.print("On");
  } else {
    client.print("Off");
  }
  client.println("

");
  client.println("<a href=\"/whiteLED=ON\"\"><button>Turn White Leds On </button></a>");
  client.println("<a href=\"/whiteLED=OFF\"\"><button>Turn White Leds Off </button></a>
");
  client.println("</html>");

  delay(1);


  while (client.available() > 0)
  {
    char c = client.read();
    if (c == startMarker)
    {
      recording = true;
      whiteLevel = 0;
    }
    else if (c == endMarker)
    {
      recording = false;
    }
    else
    {
      if (recording) {
        if (isdigit(c)) {
          whiteLevel *= 10;
          whiteLevel += c - '0';
          Serial.println("RECORDING White Level is = ");
          Serial.print(whiteLevel);

        }
        else
          recording = false;
      }
    }
  }

  analogWrite(whiteLedPin, whiteLevel);
  analogWrite(blueLedPin, blueLevel);

  Serial.println("Client disonnected");
  Serial.println("");


}

I suspect I have put code in the wrong places and orders... Thanks

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

This is where you would put the code I posted. There is no reason to save the client request in a String when all you want is the value between the = and the &.

If you want other stuff, then parse request, not readString.

Instead of the

if(isdigit(c))
            {
               brightnessVal *= 10;
               brightnessVal += c - '0';
             }

could I just get the next 3 digits after the starting value?

could I just get the next 3 digits after the starting value?

You can do what you want.