Setup timer without use delay or while function to break the loop of server

Hello guys. I’m trying to develop my first arduino project which is like a bartender to mix liquid together. I’m trying to use ethernet shield to host a web server so I can control arduino through the web.

I used several pumps to mix liquids together. To control the running time of the pumps I used delay() and while loop. But when I add web server code into the main loop() I found delay() and while loop they all break the main loop(), and turning down the webserver.

I was wondering if there is a way I can still control the running time of the pumps but not to break the webserver.

void loop() {
 EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read();
                // read 1 byte (character) from client
                HTTP_req += c;
                //HTTP_req = HTTP_req.substring(0,40);// save the HTTP request 1 char at a time
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                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();
                    // send web page
                    client.println("<!DOCTYPE html>");
                    client.println("<html>");
                    client.println("<body>");
                    client.println("");
                    client.println("<h1>MD Bot Interface</h1>");
                    client.println("");
                    client.println("<form method=\"get\">");
                    client.println("  <p>Please select a drink:</p>");
                    client.println(" <input type=\"radio\" id=\"mt\" name=\"tea\" value=\"1\">");
                    client.println("  <label for=\"male\">MilkTea</label>");
                    client.println("  <input type=\"radio\" id=\"bsl\" name=\"tea\" value=\"2\">");
                    client.println("  <label for=\"bsl\">Brown sugar latte</label>");
                    client.println("  <input type=\"radio\" id=\"p/g\" name=\"tea\" value=\"3\">");
                    client.println("  <label for=\"p/g\">Peach/Grape</label>");
                    client.println("  <input type=\"radio\" id=\"ft/of\" name=\"tea\" value=\"4\">");
                    client.println("  <label for=\"ft/of\">Fruit Tea/Orange Fantacy</label>");
                    client.println("  <input type=\"radio\" id=\"gf\" name=\"tea\" value=\"5\">");
                    client.println("  <label for=\"gf\">Grape fruit fantacy</label>");
                    client.println("  <input type=\"radio\" id=\"cwpo\" name=\"tea\" value=\"6\">");
                    client.println("  <label for=\"cwpo\">Cheese White Peach Oolong</label>");
                    client.println("  <input type=\"radio\" id=\"cgt\" name=\"tea\" value=\"7\">");
                    client.println("  <label for=\"cgt\">Chesse Green Tea</label>");
                    client.println(" ");
                    client.println("");
                    client.println("  
  ");
                    client.println("");
                    client.println("  <p>Please select your sugar level:</p>");
                    client.println("  <input type=\"radio\" id=\"s100\" name=\"sugar\" value=\"100\">");
                    client.println("  <label for=\"s100\">100%</label>");
                    client.println("  <input type=\"radio\" id=\"s75\" name=\"sugar\" value=\"75\">");
                    client.println("  <label for=\"s75\">75%</label> ");
                    client.println("  <input type=\"radio\" id=\"s50\" name=\"sugar\" value=\"50\">");
                    client.println("  <label for=\"s50\">50%</label>");
                    client.println("  <input type=\"radio\" id=\"s25\" name=\"sugar\" value=\"25\">");
                    client.println("  <label for=\"s50\">25%</label>");
                    client.println("");
                    client.println("  
");
                    client.println("");
                    client.println("  <p>Please select your ice level:</p>");
                    client.println("  <input type=\"radio\" id=\"i100\" name=\"ice\" value=\"100\">");
                    client.println("  <label for=\"i100\">100%</label>");
                    client.println("  <input type=\"radio\" id=\"i75\" name=\"ice\" value=\"75\">");
                    client.println("  <label for=\"i75\">75%</label> ");
                    client.println("  <input type=\"radio\" id=\"i50\" name=\"ice\" value=\"50\">");
                    client.println("  <label for=\"i50\">50%</label>");
                    client.println("  <input type=\"radio\" id=\"i25\" name=\"ice\" value=\"25\">");
                    client.println("  <label for=\"i25\">25%</label>");
                    client.println("  <input type=\"radio\" id=\"i0\" name=\"ice\" value=\"0\">");
                    client.println("  <label for=\"i0\">0%</label>");
                    client.println("  ");
                    client.println("  
");
                    client.println("  
");
                    client.println("");
                    client.println("  <input type=\"submit\" value=\"Submit\">");
                    client.println("</form>");
                    client.println("");
                    client.println("</body>");
                    client.println("</html>");


                    //File myFile;
                      
                      Serial.println("Removing data.txt...");
                      SD.remove("data.txt");
                    
                      myFile = SD.open("data.txt", FILE_WRITE);
                      
                      // if the file opened okay, write to it:
                      if (myFile) {
                        Serial.print("Writing to test.txt...");
                        myFile.println(HTTP_req);
                      // close the file:
                        myFile.close();
                        Serial.println("done.");
                      } else {
                        // if the file didn't open, print an error:
                        Serial.println("error opening test.txt");
                      }
                    

                    

                    HTTP_req = "";    // finished with request, empty string
                    break;
                    
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection

        
    } // end if (client)

String read_data()
{

  char data;
  String s;
  File myFile;
  
  myFile = SD.open("data.txt");
  
  if (myFile) {
    
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      data = myFile.read();
      s += data;
      
      //Serial.write(data);
    }
    // close the file:
    myFile.close();
    return s;
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening data.txt");
  }
} //end read_data

}

void recipe(int buttonstate)
{

    switch (buttonstate)
    {
        case 0: //MT_I100_S100
            pump_select(smt);
            timer(400/v_smt);
            pump_close(smt);
        

        
    }// end switch(buttonstate)
}//end recipe()

void timer(int time)
{
  long timer_start = millis();
  while (millis() - timer_start <= time)
  {
    
  }//end while
} //end timer

I made some modifications on the code. I don’t use while loop and delay, instead of, I use if statement to do the timer.

void pump_control(int pump, int vol)
{
  pump_select(pump);
  int time = vol/v_select(pump);
  long timer_start = millis();

  if (millis() - timer_start >= time)
  {
    pump_close(pump);
  }//end if
} //end pump_control

void recipe(int buttonstate)
{
//    Serial.println("Removing data.txt...");
//    SD.remove("data.txt");
//    
    switch (buttonstate)
    {
        
        // to shorter the post I deleted the other switch cases
        case 59: //PG_I100_S25
            pump_control(gt, 265);
            pump_control(yellow, 30);
            pump_control(sugar, 15);
            


    }// end switch(buttonstate)
}//end recipe()

int get_button_state(int t, int i, int s)
  {      
    if ((t == 1) && (i == 100) && (s == 100)) return 0;
    if ((t == 1) && (i == 100) && (s == 75)) return 1;
    if ((t == 1) && (i == 100) && (s == 50)) return 2;
    if ((t == 1) && (i == 100) && (s == 25)) return 3;
    

    return 9999;
            
  }
void loop() 
{
  //the webserver code deleted here. you can check it from the root post.

  aaa = read_data().substring(0,40);
    
    int t = tea_select_web();
    int s = sugar_select_web();
    int i = ice_select_web();

   int button_state = get_button_state(t, i, s);

   Serial.println(button_state); //everything is working good till this line
   

   recipe(button_state); /// if I add the recipe function the server is stucked
}

From the code above, if I add the recipe function then the webserver stucked. I read a tutorial says I need to use if statement instead of delay or while loop in order to avoid break the program. But I followed it, and the webserver is still stucked. Could anyone help me out. I do appreciate your help. Please help me.

Please post your complete sketch. Snippets are rarely useful since nobody but you can see all of it.

While you are preparing to post the whole program have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R