Stopping a function with HTTP Request

This sketch controls 3 LED lights, like a stop light. Each button on a web page can turn the 3 LEDs on/off.

There is a blink function that blinks all of the LEDS in order. This function does work but I'd like to be able to stop it with another HTTP request. It turns on with http://192.168.1.230/Blink/on and I want it to turn off with http://192.168.1.230/Blink/off but I can't figure out how to get it to take another HTTP request to turn it off. It won't take another HTTP until the Blink function completes 5 cycles (BlinkMax)

The function to cycle through the LEDS is called Blink().
DO TO THE LENGTH I'M ONLY SHOWING THE MAIN LOOP AND THE FUNCTION BLINK I NEED TO STOP.

void Blink() {
    // loop through pin array
    blink:

    if (BlinkCnt < BlinkMax) { 
      for (int thisChan = 0; thisChan < NoChannels; thisChan++) {
        // turn the pin on:
        digitalWrite(Channels[thisChan], HIGH);
        Serial.println(Channels[thisChan]);
        Serial.println("");
        delay(timer);
        // turn the pin off:
        digitalWrite(Channels[thisChan], LOW);

      }//for
      BlinkCnt ++;
      //Blink();
      goto blink;
    }//if
        BlinkState = "off";
        ChanAState = "off";
        ChanBState = "off";
        ChanCState = "off";

    
    Serial.println("Blink Done.");
    
  }//blink
  
void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    //Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        //Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // turns the GPIOs on and off
            if (header.indexOf("GET /A/on") >= 0) {
              Serial.println("Channel A on");
              ChanAState = "on";
              digitalWrite(ChanA, HIGH);
            } else if (header.indexOf("GET /A/off") >= 0) {
              Serial.println("Channel A off");
              ChanAState = "off";
              digitalWrite(ChanA, LOW);
            } else if (header.indexOf("GET /B/on") >= 0) {
              Serial.println("Channel B on");
              ChanBState = "on";
              digitalWrite(ChanB, HIGH);
            } else if (header.indexOf("GET /B/off") >= 0) {
              Serial.println("Channel B off");
              ChanBState = "off";
              digitalWrite(ChanB, LOW);            
            }  else if (header.indexOf("GET /Blink/on") >= 0) {
              Serial.println("Blink on");
              BlinkState = "on";  
              BlinkCnt =0;
              //Blink();
            } else if (header.indexOf("GET /Blink/off") >= 0) {
              Serial.println("Blink off");
              BlinkState = "off";
              BlinkCnt = BlinkMax;
            }
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<meta http-equiv=\"refresh\" content=\"5 ;url=http://192.168.1.230\" >");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color 
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #1bc16e; border-radius: 5px;border: none; color: white; padding: 5px 5px; width:90px;"); //on color
            client.println("text-decoration: none; font-size: 20px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #ff0000; border-radius: 5px; padding: 5px 5px; width:90px;}"); //off color
            client.println(".button3 {background-color: #0b63ef; border-radius: 5px; padding: 5px 5px; width:90px;}</style></head>"); // color
          
            // Web Page Heading
            client.println("<body><h2>Traffic Light</h2>");

            
            if (WiFi.status() == WL_CONNECTED) {

            } else {
            client.println(APip);
            }
            //client.println(WiFi.localIP());
            client.println("</p>");

            client.println("<table align=\"center\" border=\"1\" cellpadding=\"5\" cellspacing=\"0\"><tr bgcolor=\"99ccff\"><th width=\"100px\">Channel</th><th width=\"100px\">Status</th></tr> ");
            
            // Display current state, and ON/OFF buttons for BLINK 
            client.println("<tr><td>");
            client.println("Blink All");
            client.println("</td><td>");

            if (BlinkState=="on") {
              client.println("<a href=\"/Blink/off\"><button class=\"button\">ON</button></a>");
            } else {
              client.println("<a href=\"/Blink/on\"><button class=\"button button2\">OFF</button></a>");
            } 
              client.println("</td</tr>");


            
            // Display current state, and ON/OFF buttons for Channel A  
            client.println("<tr><td>");

            client.println("Channel A");
            client.println("</td><td>");
            
            // If the ChanAState is off, it displays the Off button       
            if (ChanAState=="on") {
              client.println("<a href=\"/A/off\"><button class=\"button\">ON</button></a>");
            } else {
              client.println("<a href=\"/A/on\"><button class=\"button button2\">OFF</button></a>");
            } 
              client.println("</td</tr>");

            // Display current state, and ON/OFF buttons for Channel B  
            client.println("<tr><td>");
            client.println("Channel B");
            client.println("</td><td>");
            // If the ChanBState is off, it displays the Off button       
            if (ChanBState=="on") {
              client.println("<a href=\"/B/off\"><button class=\"button\">ON</button></a>");
            } else {
              client.println("<a href=\"/B/on\"><button class=\"button button2\">OFF</button></a>");
            } 
              client.println("</td</tr>");
              
            // Display current state, and ON/OFF buttons for Channel C 
            client.println("<tr><td>");
            client.println("Channel C");
            client.println("</td><td>");
            // If the ChanCState is off, it displays the Off button       
            if (ChanCState=="on") {
              client.println("<a href=\"/C/off\"><button class=\"button\">ON</button></a>");
            } else {
              client.println("<a href=\"/C/on\"><button class=\"button button2\">OFF</button></a>");
            }
            client.println("</td</tr>");

            client.println("</td</tr>");
            client.println("</table>");
            client.println("</body></html>");

            //turn on blink
            if (BlinkState == "on") {
                Blink();
              
            } else {
              //stop blink
              BlinkCnt = BlinkMax;
            }
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;

          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }

    
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    //Serial.println("Client disconnected.");
    Serial.println("");
  }
}

You'll need to study timing with millis()

There is also a good tutorial, blink without delay() on the forum. When I'm at a desktop tomorrow I could direct you to it if you have not yet found it.

You need to make all your functions non blocking so that yor server code can execute while your lights are blinking.

ok, I get timing with mills()

I found the example of a blink without using delay().

Thanks for the tip. I'll see where this takes me.

I set my main program aside for a minute so that I can get my LEDs to blink the way I want. These are going to blink in order like a traffic light. GREEN-YELLOW-RED

Here is what I came up with using Millis(). This sequences the LEDs how I want.

//set pins for the 3 leds
const byte redLED = 4 ;
const byte yellowLED = 0 ;
const byte greenLED = 2 ;

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 2000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(redLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
}

void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

   
    ///if nothing is on set red on to start
    if (!digitalRead(redLED) && !digitalRead(yellowLED)&& !digitalRead(greenLED)) {
        digitalWrite (redLED, HIGH ) ;
    } else if(digitalRead(redLED)) {
      //turn red off green on
        digitalWrite (redLED, LOW ) ;
        digitalWrite (greenLED, HIGH ) ;
        digitalWrite (yellowLED, LOW ) ;  
    } else if(digitalRead(greenLED)) {
        digitalWrite (redLED, LOW ) ;
        digitalWrite (greenLED, LOW ) ;
        digitalWrite (yellowLED, HIGH ) ;
    } else if(digitalRead(yellowLED)) {
        digitalWrite (redLED, HIGH ) ;
        digitalWrite (greenLED, LOW ) ;
        digitalWrite (yellowLED, LOW ) ;
    }

  }//end if currentMillis
}//end loop

Edit: Read next post. This code tries to read a pin that has been set as an output. This is going to cause problems. Other than this you seem to be on the right track.

The logic to change the color of the light, is just the timing in which you want each color to be on. So digitalWrite the green light on from 0-3 seconds, then turn it off and write the yellow light on from 3-5 seconds, then turn it off and write the red light on from 5-8 seconds.

If you need more elaborate logic, make a state variable to keep track of which light is on and which lights are off (if need be). Then you can update the state variable through whatever input you need later. My guess is you do not want to be reading the pin output data to switch through to the next light. If you do need to do this, you could probably use another pin as input to read your output pins, but you should already know whether you've written to the pin so it seems like a waste of hardware.

MotoGp:
...
//set pins for the 3 leds
const byte redLED = 4 ;
const byte yellowLED = 0 ;
const byte greenLED = 2 ;

unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 2000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(redLED, OUTPUT);
pinMode(yellowLED, OUTPUT);
pinMode(greenLED, OUTPUT);
}

void loop() {

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

///if nothing is on set red on to start
if (!digitalRead(redLED) && !digitalRead(yellowLED)&& !digitalRead(greenLED)) {
digitalWrite (redLED, HIGH ) ;
} else if(digitalRead(redLED)) {
//turn red off green on
digitalWrite (redLED, LOW ) ;
digitalWrite (greenLED, HIGH ) ;
digitalWrite (yellowLED, LOW ) ;
} else if(digitalRead(greenLED)) {
digitalWrite (redLED, LOW ) ;
digitalWrite (greenLED, LOW ) ;
digitalWrite (yellowLED, HIGH ) ;
} else if(digitalRead(yellowLED)) {
digitalWrite (redLED, HIGH ) ;
digitalWrite (greenLED, LOW ) ;
digitalWrite (yellowLED, LOW ) ;
}

}//end if currentMillis
}//end loop