Can't stop While loop

Hello, for some reason I can not get the while loop to stop through a web interface I made. I am using an esp8266 01 and the software serial library. I want to control this led through a web interface to make it blink. Please help me. Here is my code:

#include <SoftwareSerial.h>                         //including the SoftwareSerial library will allow you to use the pin no. 2,3 as Rx, Tx.
SoftwareSerial esp8266(2, 3);                       //set the Rx ==> Pin 2; TX ==> Pin3.

#define serialCommunicationSpeed 9600               // <========= define a constant named "serialCommunicationSpeed" with a value 9600. it referes to the Software and hardware serial communication speed(baud rate).
#define DEBUG true                                  //make a constant named "DEBUG" and it's value true. we will use it later.

int redLED = 11;                                     //assign a variable named "redLED" with an integer value 11, it refers to the pin which the red LED is connected on.
int Blink = false;

void setup()

{
 pinMode(redLED, OUTPUT);                          //set the pin number 12 as an output pin.                    //set the pin number 11 as an output pin.

 digitalWrite(redLED, LOW);                        //turn the red LED off at the beginning of the program.                       //turn the blue LED on at the beginning of the program.

 Serial.begin(serialCommunicationSpeed);           //begin the Hardware serial communication (0, 1) at speed 9600.
 esp8266.begin(serialCommunicationSpeed);          //begin the software serial communication (2, 3) at speed 9600.

 InitWifiModule();                                 //call this user-defined function "InitWifiModule()" to initialize a communication between the ESP8266 and your access point (Home Router or even your mobile hotspot).
 //after finishing the initialization successfully, turn off the blue LED (just an indicator).
}

void loop()                                                         //our main program, some fun are about to start)
{

 if (esp8266.available())                                          //if there's any data received and stored in the serial receive buffer, go and excute the if-condition body. If not, dont excute the if-condition body at all.
 {
   if (esp8266.find("+IPD,"))                                      //search for the "+IPD," string in the incoming data. if it exists the ".find()" returns true and if not it returns false.
   {
     delay(1000);                                                  //wait 1 second to fill up the buffer with the data.
     int connectionId = esp8266.read() - 48;                       //Subtract 48 because the read() function returns the ASCII decimal value. And 0 (the first decimal number) starts at 48. We use it to convert from ASCI decimal value to a character value.
     esp8266.find("pin=");                                         //Advance the cursor to the "pin=" part in the request header to read the incoming bytes after the "pin=" part which is the pinNumer and it's state.
     int pinNumber = (esp8266.read() - 48) * 10;                   //read the first Byte from the Arduino input buffer(i.e. if the pin 12 then the 1st number is 1) then multiply this number by 10. So, the final value of the "pinNumber" variable will be 10.
     pinNumber = pinNumber + (esp8266.read() - 48);                //read the second Byte from the Arduino input buffer(i.e. if the pin number is 12 then the 2nd number is 2) then add this number to the first number. So, the final value of the "pinNumber" variable will be 12.
     int statusLed = (esp8266.read() - 48);                        //read the third byte from the Arduino input buffer. then save it inside the "statusLed" variable. At any case, it will be 1 or 0.

     digitalWrite(pinNumber, statusLed);
     if (pinNumber == 000) {
       Blink = true;
     } else {
       Blink = false;
     }
     while (Blink == true) {
       digitalWrite(redLED, HIGH);
       delay(500);
       digitalWrite(redLED, LOW);
       delay(500);
       if(pinNumber != 000){
         break;
       }
     }

     //then turn the LED at "pinNumber" on or off depending on the "statusLed" variable value.

     Serial.println(connectionId);                                 //print the "connectionId" value on the serial monitor for debugging purposes.
     Serial.print(pinNumber);                                      //print the "pinNumber" value on the serial monitor for debugging purposes.
     Serial.print("      ");                                       //print some spaces on the serial monitor to make it more readable.
     Serial.println(statusLed);                                    //print the "statusLed" value on the serial monitor for debugging purposes.

     String closeCommand = "AT+CIPCLOSE=";                         //close the TCP/IP connection.
     closeCommand += connectionId;                                 //append the "connectionId" value to the string.
     closeCommand += "\r\n";                                       //append the "\r\n" to the string. it simulates the keyboard enter press.
     sendData(closeCommand, 1000, DEBUG);                          //then send this command to the ESP8266 module to excute it.

   }
 }

}

/******************************************************************************************************************************************************************************************
 Name: sendData
 Description: this Function regulates how the AT Commands will ge sent to the ESP8266.

 Params: command - the AT Command to send
                 - timeout - the time to wait for a response
                 - debug - print to Serial window?(true = yes, false = no)

 Returns: The response from the esp8266 (if there is a reponse)
*/
String sendData(String command, const int timeout, boolean debug)
{
 String response = "";                                             //initialize a String variable named "response". we will use it later.

 esp8266.print(command);                                           //send the AT command to the esp8266 (from ARDUINO to ESP8266).
 long int time = millis();                                         //get the operating time at this specific moment and save it inside the "time" variable.
 while ( (time + timeout) > millis())                              //excute only whitin 1 second.
 {
   while (esp8266.available())                                     //is there any response came from the ESP8266 and saved in the Arduino input buffer?
   {
     char c = esp8266.read();                                      //if yes, read the next character from the input buffer and save it in the "response" String variable.
     response += c;                                                //append the next character to the response variabl. at the end we will get a string(array of characters) contains the response.
   }
 }
 if (debug)                                                        //if the "debug" variable value is TRUE, print the response on the Serial monitor.
 {
   Serial.print(response);
 }
 return response;                                                  //return the String response.
}



/******************************************************************************************************************************************************************************************
 Name: InitWifiModule
 Description: this Function gives the commands that we need to send to the sendData() function to send it.

 Params: Nothing.

 Returns: Nothing (void).
*/
void InitWifiModule()
{
 sendData("AT+RST\r\n", 2000, DEBUG);                                                  //reset the ESP8266 module.
 //delay(1000);
 sendData("AT+CWJAP=\"ip\",\"ip\"\r\n", 2000, DEBUG);        //connect to the WiFi network.
 delay (3000);
 sendData("AT+CWMODE=1\r\n", 1500, DEBUG);                                             //set the ESP8266 WiFi mode to station mode.
 delay (1500);
 sendData("AT+CIFSR\r\n", 1500, DEBUG);                                                //Show IP Address, and the MAC Address.
 delay (1500);
 sendData("AT+CIPMUX=1\r\n", 1500, DEBUG);                                             //Multiple conections.
 delay (1500);
 sendData("AT+CIPSERVER=1,80\r\n", 1500, DEBUG);                                       //start the communication at port 80, port 80 used to communicate with the web servers through the http requests.
}

Firstly, please post your code in code tags. These are the </> in the edit menu. You can edit your post to change this. Without these brackets the code does not format properly and emoticons and other strange artefacts can appear in the code.

Secondly, note that numbers in C/C++ that start with 0 are treated as octal numbers. So while it does not matter with your 000, a comparison to 016 would not be comparing to 16 decimal but 16 octal. You should just use 0 (or 16 in my example).

To address your question. The exit from the while loop is when Blink != true and you also have a statement to break when pinNumber != 000. Neither of these will change during the running of the while loop, so it does not exit. You are also not looking at the Wifi interface during the while loop so there is no way to tell the loop to stop anyway. To be clear, the loop just blinks the LED and nothing else is running.

What are you expecting to happen?

Some caveats

Remove the delay(1000). You should never use delay() in loop().

Read only one character at a time. Do not expect to read more than one character once available() is true. Use an FSM to parse the input. Never expect to read a complete line.

Do not write -48. Write -'0'.

Get rid of the while(blink == true) loop. Never put long loops inside loop(). Use millis() and non-blocking logic to do blinking

NEVER write == true or == false for a condition. EVER! It makes no sense anyway. The result of == is a boolean. But "blink" is already a boolean, and does not need to be compared to ANYTHING to get a boolean value. This is especially true in C/C++, where only FALSE has a defined value, and "true" is any value that is "not-FALSE". "true" is not necessarily == true! This is a horrible practice, and you need to stop doing it.

Now consider the loop:

  if (pinNumber == 000) {
        Blink = true;
      } else {
        Blink = false;
      }
      while (Blink == true) {
        digitalWrite(redLED, HIGH);
        delay(500);
        digitalWrite(redLED, LOW);
        delay(500);
        if(pinNumber != 000){
          break;
        }
      }

If the pin number is 0, (000 is octal 0, which is just silly), blink is set to true. If it is not 0, blink is set to false. So note that the pin number as we execute the loop is already 0. The only way we stop the loop is if the pin number is not 0, but there is nothing in the loop that can change the pin number, so the loop never stops!

So first, get rid of the blink loop.

uint32_t BlinkStartTime = 0;
static const uint32_t BlinkTime = 500;
bool BlinkOn = false;
bool Blinking = false;
static const byte redLED = 11;

void loop()
   {
     if(esp8266.available()
       {
         ...
         Blinking = pinNumber == 0;
         BlinkStartTime = millis();
         BlinkOn = true;
        }

     if(Blinking)
        {
          if(millis() - BlinkStartTime > BlinkTime)
             {
               BlinkOn = !BlinkOn;
               BlinkStartTime = millis();
              }
           digitalWrite(redLED, BlinkOn ? HIGH : LOW);
          }
       else
           digitalWrite(redLED, LOW);
        ...

This is off the top of my head, and may need some tweaking, but it is closer to being right than what you have. It doesn't solve the text input problem, but that is going to take more of a rewrite than I have time for right now.

Please edit your post to add code tags, as described in "How to use the forum".

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Tom... :slight_smile:

Blink and pinNumber never change in this loop therefore it is an infinite loop.

      while (Blink == true) {
        digitalWrite(redLED, HIGH);
        delay(500);
        digitalWrite(redLED, LOW);
        delay(500);
        if (pinNumber != 000) {
          break;
        }
      }

Thank you guys for responding to my post. I imported flounder's code and it didn't work as intended. When I would press the LED ON button in the interface, it would turn on and turn off right away. When I would press the LED off button it would, well turn the led off. When I would press the LED Blink button, it would turn on and stay on until I would press the LED off button. The good news is that the arduino is still able to receive messages from the esp. Also, i want to point out that I am a beginner when it comes to programming. ty

Post your code as it looks now.

I am a beginner when it comes to programming

All the more reason to see your code.

Here is my new code:

#include <SoftwareSerial.h>                         //including the SoftwareSerial library will allow you to use the pin no. 2,3 as Rx, Tx.
SoftwareSerial esp8266(2, 3);                       //set the Rx ==> Pin 2; TX ==> Pin3.

#define serialCommunicationSpeed 9600               // <========= define a constant named "serialCommunicationSpeed" with a value 9600. it referes to the Software and hardware serial communication speed(baud rate).
#define DEBUG true                                  //make a constant named "DEBUG" and it's value true. we will use it later.

uint32_t BlinkStartTime = 0;
static const uint32_t BlinkTime = 500;
bool BlinkOn = false;
bool Blinking = false;
static const byte redLED = 11;

void setup()

{
  pinMode(redLED, OUTPUT);                          //set the pin number 12 as an output pin.                    //set the pin number 11 as an output pin.

  digitalWrite(redLED, LOW);                        //turn the red LED off at the beginning of the program.                       //turn the blue LED on at the beginning of the program.

  Serial.begin(serialCommunicationSpeed);           //begin the Hardware serial communication (0, 1) at speed 9600.
  esp8266.begin(serialCommunicationSpeed);          //begin the software serial communication (2, 3) at speed 9600.

  InitWifiModule();                                 //call this user-defined function "InitWifiModule()" to initialize a communication between the ESP8266 and your access point (Home Router or even your mobile hotspot).
  //after finishing the initialization successfully, turn off the blue LED (just an indicator).
}

void loop()                                                         //our main program, some fun are about to start)
{

  if (esp8266.available())                                          //if there's any data received and stored in the serial receive buffer, go and excute the if-condition body. If not, dont excute the if-condition body at all.
  {
    if (esp8266.find("+IPD,"))                                      //search for the "+IPD," string in the incoming data. if it exists the ".find()" returns true and if not it returns false.
    {
      delay(1000);                                                  //wait 1 second to fill up the buffer with the data.
      int connectionId = esp8266.read() - 48;                       //Subtract 48 because the read() function returns the ASCII decimal value. And 0 (the first decimal number) starts at 48. We use it to convert from ASCI decimal value to a character value.
      esp8266.find("pin=");                                         //Advance the cursor to the "pin=" part in the request header to read the incoming bytes after the "pin=" part which is the pinNumer and it's state.
      int pinNumber = (esp8266.read() - 48) * 10;                   //read the first Byte from the Arduino input buffer(i.e. if the pin 12 then the 1st number is 1) then multiply this number by 10. So, the final value of the "pinNumber" variable will be 10.
      pinNumber = pinNumber + (esp8266.read() - 48);                //read the second Byte from the Arduino input buffer(i.e. if the pin number is 12 then the 2nd number is 2) then add this number to the first number. So, the final value of the "pinNumber" variable will be 12.
      int statusLed = (esp8266.read() - 48);                        //read the third byte from the Arduino input buffer. then save it inside the "statusLed" variable. At any case, it will be 1 or 0.

      digitalWrite(pinNumber, statusLed);

      //then turn the LED at "pinNumber" on or off depending on the "statusLed" variable value.

      Serial.println(connectionId);                                 //print the "connectionId" value on the serial monitor for debugging purposes.
      Serial.print(pinNumber);                                      //print the "pinNumber" value on the serial monitor for debugging purposes.
      Serial.print("      ");                                       //print some spaces on the serial monitor to make it more readable.
      Serial.println(statusLed);                                    //print the "statusLed" value on the serial monitor for debugging purposes.

      String closeCommand = "AT+CIPCLOSE=";                         //close the TCP/IP connection.
      closeCommand += connectionId;                                 //append the "connectionId" value to the string.
      closeCommand += "\r\n";                                       //append the "\r\n" to the string. it simulates the keyboard enter press.
      sendData(closeCommand, 1000, DEBUG);

      Blinking = pinNumber == 000;
      BlinkStartTime = millis();
      BlinkOn = true;
      if (Blinking)
      {
        if (millis() - BlinkStartTime > BlinkTime)
        {
          BlinkOn = !BlinkOn;
          BlinkStartTime = millis();
        }
        digitalWrite(redLED, BlinkOn ? HIGH : LOW);
      }
      else
        digitalWrite(redLED, LOW);
    }
  }
}

/******************************************************************************************************************************************************************************************
  Name: sendData
  Description: this Function regulates how the AT Commands will ge sent to the ESP8266.

  Params: command - the AT Command to send
                  - timeout - the time to wait for a response
                  - debug - print to Serial window?(true = yes, false = no)

  Returns: The response from the esp8266 (if there is a reponse)
*/
String sendData(String command, const int timeout, boolean debug)
{
  String response = "";                                             //initialize a String variable named "response". we will use it later.

  esp8266.print(command);                                           //send the AT command to the esp8266 (from ARDUINO to ESP8266).
  long int time = millis();                                         //get the operating time at this specific moment and save it inside the "time" variable.
  while ( (time + timeout) > millis())                              //excute only whitin 1 second.
  {
    while (esp8266.available())                                     //is there any response came from the ESP8266 and saved in the Arduino input buffer?
    {
      char c = esp8266.read();                                      //if yes, read the next character from the input buffer and save it in the "response" String variable.
      response += c;                                                //append the next character to the response variabl. at the end we will get a string(array of characters) contains the response.
    }
  }
  if (debug)                                                        //if the "debug" variable value is TRUE, print the response on the Serial monitor.
  {
    Serial.print(response);
  }
  return response;                                                  //return the String response.
}



/******************************************************************************************************************************************************************************************
  Name: InitWifiModule
  Description: this Function gives the commands that we need to send to the sendData() function to send it.

  Params: Nothing.

  Returns: Nothing (void).
*/
void InitWifiModule()
{
  sendData("AT+RST\r\n", 2000, DEBUG);                                                  //reset the ESP8266 module.
  //delay(1000);
  sendData("AT+CWJAP=\"ip\",\"ip\"\r\n", 2000, DEBUG);        //connect to the WiFi network.
  delay (3000);
  sendData("AT+CWMODE=1\r\n", 1500, DEBUG);                                             //set the ESP8266 WiFi mode to station mode.
  delay (1500);
  sendData("AT+CIFSR\r\n", 1500, DEBUG);                                                //Show IP Address, and the MAC Address.
  delay (1500);
  sendData("AT+CIPMUX=1\r\n", 1500, DEBUG);                                             //Multiple conections.
  delay (1500);
  sendData("AT+CIPSERVER=1,80\r\n", 1500, DEBUG);                                       //start the communication at port 80, port 80 used to communicate with the web servers through the http requests.
}

The AT command set was never intended to be used for an actual application interface, it is really only good for testing and maintenance. You're much better off programming the ESP directly using the wifi library that is native to it. That would actually be easier for a beginner, too.

AT == "Ancient Technology"
I've never seen someone use the ESP8266-01 to put an Arduino on the web. I'm sure it's been done, but, why? Upi can program the ESP8266 using the Arduino IDE, so why do you need both?

I tries using the esp8266 library before but for some it kept saying that the serial port _ was not connected and connection timed out. I am still not able to fix it.