Function doesn't return a right value

To begin with, I’m doing a mini project on the verification of RFID card using nodeMCU. I set up a database and a server to handle all the request from the client. The problem is, whenever I try to verify a valid card, the function that handle it keep returning a wrong value. To be more clear, here is my main loop:

void loop() {
  connectToHost();

  key = kpd.getKey();
  card = readCard();
  delay(200);

  //check for card status
  if(verifyCard(card)){
    Serial.println("Card is valid");
  }
  else{
    Serial.println("Invalid Card");
  }

  //check connection status
  if(WiFi.status() == WL_CONNECTION_LOST){
    connectToWiFi();
  }
}

The main loop call for this function:

boolean verifyCard(String uid){
  String url = "/ECafe/terminal_verify.php?uid=";
  url += uid;

  // This will send the request to the server
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
     
  unsigned long timeout = millis();
  
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
    }
    yield();
  }

  // Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
    //if string contains echo from php file
    if(line.indexOf("Valid")>0){
      return true;
    }else{
      return false;
    }
    yield();
  }
  Serial.println();
  Serial.println("Closing connection");
}

I intentionally put a valid card uid in the database just to test this function. Yet, it keep returning false. I’m sure that the response from server is “Valid”. I suspect that the function doesn’t even wait for the response from server and return a false value because the interval between the GET request is sent and the response is returned is too short. Is that because of the if…condition in the main loop? View attachment for the serial monitor output. Desperately need help on this.

evident.PNG

In verifyCard, you first wait for some data to arrive (that can be one byte)!. Next you start reading in while (client.available()) {. What happens if you did not receive the complete message yet? client.readStringUntil will time out, line.indexOf("Valid") will not give what you expect and you will return false.

I would start by printing the received data before testing for "Valid" after *client.readStringUntil('\r')*and see if you get the expected response.

Your code will probably also never get to the last part of verifyCard. If it does, you have another problem because you never return anything so the calling function will read rubbish which can be true or false depending on the state of your memory.

Ok. So putting if(line.indexOf("Valid")>0){} out of the while(client.available()){} will allow the client.readStringUntil('\r') to read the response until the end. I guess I didn't realize that silly mistake I made there.

You should not guess :wink:

And I doubt it's the solution to the problem. Maybe do a search for Robin2's updated Serial Input Basics thread and apply the principles demonstrated in there; they do not only apply to serial but to your situation as well and to file reading.

Thanks. Just when I want to fetch the data much faster and that forum help a lot.

Also posted at:

If you're going to do that then please be considerate enough to add links to the other places you cross posted. This will let us avoid wasting time due to duplicate effort and also help others who have the same questions and find your post to discover all the relevant information. When you post links please always use the chain links icon on the toolbar to make them clickable.