decrease data send failures

HI,

I’m begginer in arduino programming. I have the code below, and the idea is to send the information to the server every minute, however, I’m having several errors in getting the correct HTTP response.
the response is not always complete, and I search for the string SEND OK to continue
I’ve tried the following ways, and I get the same result
tmpResp = esp8266.readString();
tmpResp = esp8266.readStringUntil(’\r’);

I’ve tried put some delay too.

My code

boolean waitAndEcho(unsigned long t, String s) {
  String buffer = "";
  unsigned long start = millis();
  unsigned long last = 0;
  unsigned int n = s.length();
  bool ret = false;
  delay(200);
  do {
    if (esp8266.available()) {
      buffer += (char)esp8266.read();
      last = millis();
      if (buffer.length() >= n) {
        if (buffer.substring(buffer.length() - (n)).equals(s)) {
          //if (buffer.indexOf(s)) {
          ret = true;
          break;
        }
      }
    }
  } while (millis() < start + t);

  buffer.replace("\r", "\\r");
  buffer.replace("\n", "\\n");

  if (vDebug == true) {
    Serial.println(String(ret ? "+" : "-") + "(" + String(last - start) + "/" + String(t) + "):" + buffer);
  }

  return ret;
}
while (!sendData(vLed, vValorDb));
bool sendData(byte vLed, float vValorDb) {

  Serial.println(F("Enviando dados"));

  String values = "idd=[D]&idl=[L]&ide=[E]&vdb=[DB]&vref=[RE]";
  values.replace("[D]", String(vDisp));
  values.replace("[L]", String(vLed));
  values.replace("[E]", String(vIdEmpresa));
  values.replace("[DB]", String(vValorDb));
  values.replace("[RE]", String(vDbMax));


  String postString = "POST /receptor/som HTTP/1.1\r\n"
                      "Host: [S]\r\n"
                      "Content-Type: application/x-www-form-urlencoded\r\n"
                      "Content-Length: [L]\r\n"
                      "Accept: */*\r\n"
                      //"User-Agent: Arduino/1.0\r\n"
                      "User-Agent: [D]/1.0\r\n"
                      "Connection: close\r\n\r\n"
                      "[V]\r\n\r\n";

  postString.replace("[L]", String(values.length()));
  postString.replace("[V]", values);
  postString.replace("[S]", vServer);
  postString.replace("[D]", String(vDisp));

  //Serial.println("Send post" + postString);

  esp8266.println("AT+CIPMUX=1");
  if (waitAndEcho(3000, "OK\r\n")) {
    esp8266.println("AT+CIPSTART=4,\"TCP\",\"" + vServer + "\"," + vServerPort);
    if (waitAndEcho(5000, "OK\r\n")) {
      esp8266.println("AT+CIPSEND=4," + String(postString.length()));
      if (waitAndEcho(5000, ">")) {
        esp8266.print(postString);
        delay(500);
        String tmpResp;
        if (esp8266.available()) {
          while (esp8266.available()) {
            tmpResp = esp8266.readString();
            delay(1);
          }
        }
        //Serial.println(tmpResp);
        //Serial.println("Resp Send"+ tmpResp);
        if (tmpResp.indexOf("SEND OK") > 0) {
          return true;
        }
      }
    }
  }
  Serial.println(F("Falha no envio da informacao"));
  return false;
}

i´m using arduino uno + esp8266 and <AltSoftSerial.h>.

the baud rates

Serial.begin(115200);
while (!Serial); // wait for Arduino Serial Monitor to open

esp8266.begin(9600);

tks.

It is not exactly clear to me what you are doing exactly from your description, but the code looks like you are trying to process a http request?

If that is the case then try the following loop structure.

It is from WiFiEsp library that I am using, so you will need to change the identifiers to match those that your library uses…to get it to compile.

void loop()
{
  // listen for incoming clients
  WiFiEspClient client = server.available();
  if (client) {
    Serial.println("New client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          Serial.println("Sending response");
          
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(
            "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html\r\n"
            "Connection: close\r\n"  // the connection will be closed after completion of the response
            "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
            "\r\n");
          client.print("<!DOCTYPE HTML>\r\n");
          client.print("<html>\r\n");
          client.print("<h1>Hello World!</h1>\r\n");
          client.print("Requests received: ");
          client.print(++reqCount);
          client.print("
\r\n");
          client.print("Analog input A0: ");
          client.print(analogRead(0));
          client.print("
\r\n");
          client.print("</html>\r\n");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(10);

    // close the connection:
    client.stop();
    Serial.println("Client disconnected");
  }
}

boylesg:
It is not exactly clear to me what you are doing exactly from your description, but the code looks like you are trying to process a http request?

If that is the case then try the following loop structure.

It is from WiFiEsp library that I am using, so you will need to change the identifiers to match those that your library uses…to get it to compile.

Unless the library you are using has a similar http server example, in which case the loop structure probably is much the same as this one.

Just modify the copied loop structure to meet your needs, one line at a time, until you figure out which of your modifications is ‘breaking’ functionality.

void loop()

{
  // listen for incoming clients
  WiFiEspClient client = server.available();
  if (client) {
    Serial.println(“New client”);
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you’ve gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == ‘\n’ && currentLineIsBlank) {
          Serial.println(“Sending response”);
         
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(
            “HTTP/1.1 200 OK\r\n”
            “Content-Type: text/html\r\n”
            “Connection: close\r\n”  // the connection will be closed after completion of the response
            “Refresh: 20\r\n”        // refresh the page automatically every 20 sec
            “\r\n”);
          client.print("\r\n");
          client.print("\r\n");
          client.print(“

Hello World!

\r\n”);
          client.print(“Requests received: “);
          client.print(++reqCount);
          client.print(”
\r\n”);
          client.print(“Analog input A0: “);
          client.print(analogRead(0));
          client.print(”
\r\n”);
          client.print("\r\n");
          break;
        }
        if (c == ‘\n’) {
          // you’re starting a new line
          currentLineIsBlank = true;
        }
        else if (c != ‘\r’) {
          // you’ve gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(10);

// close the connection:
    client.stop();
    Serial.println(“Client disconnected”);
  }
}

If you want the web page, as viewed in your web browser, to automatically refresh with the current arduino data then it is "Refresh: 20\r\n" in your http response (from the Arduino to the web browser) that does it. In this example it is refresh every 20 seconds.

The web browser will automatically send a new http request to your arduino every 20 seconds.

boylesg,

I need to send the information read once per minute. the image I sent is an example of how I am receiving the information, and the delay.

My problem is to read the response of the post, because I get the information incomplete, and I do not receive the string "SEND OK" which causes my code to continue, because of this the sending of data stays in constant loop until it works.

        String tmpResp;
        if (esp8266.available()) {
          while (esp8266.available()) {
            tmpResp = esp8266.readString();
            delay(1);
          }
        }
        //Serial.println(tmpResp);
        //Serial.println("Resp Send"+ tmpResp);
        if (tmpResp.indexOf("SEND OK") > 0) {
          return true;
        }

If there is no data available nano-seconds after you send the request, what will be in tmpResp? Any answer other than "I haven't a clue" is WRONG. So, get a clue. Initialize tmpResp.

Also, note that there are TWO functions, connected() and available(), that have to both be true before you read any data AND that have to BOTH be false before you know that you have read ALL of the data.

hi PaulS,

i´m using just a arduino nano + esp8266, wtihout any lib. so i don´t have the method connected().

i think that is my problem, but i don´t know how to check if is connected before read the data.

#include <SoftwareSerial.h>
SoftwareSerial esp8266(8, 9);

tks