Serial comms w/ ESP8266 Buffer

Hi everyone,

Im making a project with an ESP8266, where I am trying to build out a state machine on my Mega. I have a few sensors, (temp, air quality), and an RTC. I'll build out more functionality once I can get it to communicate outside.

I am having an issue that I cant seem to resolve where the serial read returns about 60 chars, and its not enough to get what the response is from the ESP8266. hence, I get undesired behavior. I have searched on the forum for a solution, but I have not had any realistic success in finding my problem.

what I have tired:

  • I found a solution outlining increasing the size of the serial buffer in serialhardware.h, and I raised it to 256, and that did not help.

  • Ive read the Serial communication section on here several times over, but I could not make see how I am getting this wrong.

<there are a few delay()s in the code below, and they will come out when it works, its only so I can see what is happening on my serial monitor as it goes.>

the point of this up to now is to initialise the ESP8266 by cycling power, let it auto connect to my AP, I send it a request for the assigned IP and gateway addresses, and then store them in a variable.

I have not yet re-implemened the sensor code into it, and that will come later.

below, my code:

#pragma once
#include "IOT_board.h"

int state_SMESP = 0;
int state_prev_SMESP = 0;


void setup() {
  Serial.begin(115200); // start serial port to arduino
  Serial.println("\n\n\n\n\n\n\n\n\n\n                                Arduino is Ready...\n\n\n\n");
  Serial3.begin(115200);
  pinMode(ESPPower, OUTPUT);
  pinMode(airSens, INPUT);  // assign pin for air quality sensor
  rtc.begin();
  // The following lines can be uncommented to set the date and time
  //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
  Serial3.println("ATE0\r\n");
  Serial.println("                                Running...\n\n\n\n\n\n\n\n\n\n");
  digitalWrite(ESPPower, HIGH);
}
void loop() {
  if (Serial3.available()){
  Sd = messageHandler(); // get serial data off serial 3 buffer.
  }
  Serial.println(Sd);
  SMESP(); // call the esp8266 state machine.
  if (state_SMESP != state_prev_SMESP){ // check to see if the state has changed from last.
    Serial.print("State of machine is: ");
    Serial.println(state_SMESP);
      Serial.println(rtc.getTimeStr());
  }
  uTime = rtc.getUnixTime(rtc.getTime()); // grab the time from the RTC.
  fade.breathe(); // Fade led with a sine wave value.
}
void SMESP() { //State Machine ESP8266.
  state_prev_SMESP = state_SMESP;
  switch (state_SMESP) {

    case 0://reset
    
    state_SMESP = 1;
    break;

    case 1: // break power, and reset flags.
    Connect = false;
    GotIP = false;
    Ready = false;
    digitalWrite(ESPPower, LOW);
    delay(10);
    digitalWrite(ESPPower, HIGH);
    Serial3.print("ATE0\r\n");
    delay(200);
    state_SMESP = 2;
    break;
    
    case 2: // start esp8266 and get a connection with an IP Address.
    TOcms2 = millis();
    if ((TOcms2 - TOpms2) >= TOInterv){ //ten seconds

      TOpms2 = millis(); //initialise the case 4 timeout
      state_SMESP = 0;
      break;
    }
    if (Sd.indexOf(kwReady) >= 0){
      Ready = true;
      Serial.println(kwReady);
      delay(1000);
    }
    if (Sd.substring(0, kwConnect.length()) == kwConnect ){
      Serial.println(kwConnect + ",  Connected to " + ESPSSID + "...");
      Connect = true;      
    }
    if (Sd.substring(0, kwGotIP.length()) == kwGotIP ){
      Serial.println(kwGotIP + ". - Have IP Address...");
      GotIP = true;
    }
    if (Connect == true || GotIP == true){// for whatever reason, there are random carriage returns in this and its glitchy.
      state_SMESP = 3;
      delay(200);
    }
    TOpms4 = millis();
    break;
    
    case 3: // ask for the IP address and gateway.
    Serial.println("Sending CIPSTA?");
    Serial3.print("AT+CIPSTA?\r\n");
    delay(1000);
    state_SMESP = 4;
    break;

    case 4: //Show the IP Address and gateway.
    delay(10);
    TOcms4 = millis(); 
    Serial.print("Timer difference is:");
    Serial.println(TOcms4 - TOpms4);
    if ((TOcms4 - TOpms4) >= TOInterv){ //Eight seconds
      Serial.println("Timer Over-Run Timer Over-Run Timer Over-Run\nTimer Over-Run Timer Over-Run Timer Over-Run\nTimer Over-Run Timer Over-Run Timer Over-Run\nTimer Over-Run Timer Over-Run Timer Over-Run\nTimer Over-Run Timer Over-Run Timer Over-Run\n");
      TOpms4 = TOcms4;
      state_SMESP = 3;
      break;
    }
        //start and finish of the ip and gateway.
    if ((LocalIP) == ""){
      if(Sd.indexOf(kwIP) > 0){
      S1 = Sd.indexOf(kwIP);
      Serial.print("position of IP: ");
      Serial.println(S1);
      F1 = S1 + kwIP.length();
      Serial.print("position of end of IP: ");
      Serial.println(F1);
      qm1 = Sd.indexOf(qm);
      qm2 = Sd.indexOf(qm + 1);
      LocalIP = Sd.substring(qm1, qm2);
      Serial.println(Sd.substring(0));
    }else {
      Serial.println(Sd);
      Serial.println("IP not there.");
      state_SMESP = 3;
      break;
    }
    }
    if ((Gateway) == ""){ 
      Serial.println("Gateway is eqal to zero bytes...");
      if(Sd.indexOf(kwGW) > 0){
      S2 = Sd.indexOf(kwGW);
      Serial.print("Position of Gateway: ");
      Serial.println(S2);
      F2 = S2 + kwGW.length();
      F1 = S1 + kwIP.length();
      Serial.print("position of end of Gateway: ");
      Serial.println(F2);
      qm3 = Sd.indexOf(qm + 2);
      qm4 = Sd.indexOf(qm + 3);
      Gateway = Sd.substring(qm3, qm4);
    }else {
      Serial.println(Sd);
      Serial.println("Gateway not there.");
      state_SMESP = 3;
      break;
    }
    }
    
    if ( LocalIP != "" && Gateway != ""){
      state_SMESP = 5;
      break;
    }
     if (Sd == "" || "AT+CIPSTA?"){ // if Sd is empty just go around the loop
      Sd = "";
      break;
     }
    case 5:
    Serial.print("Local IP Adress is: ");
    Serial.println(LocalIP);
    Serial.print("Local Gateway is: ");
    Serial.println(Gateway);
    state_SMESP = 6;
    break;

    case 6:
    // as far as I have gotten at this point. 
    break;
}
}
String messageHandler() { // gets what is sitting on the serial port and parses it back to Sd().
  char c;
  String str = (""); // initialise a string variable for returning the message
  if (Serial3.available()) {
    while (Serial3.available()){
      c = (Serial3.read());
      str += String(c);
    }
  }
  return str;
}

The problem is I not getting the whole message back from the ESP8266. I send a "AT+CIPSTA?" command to the ESP8266;

I expect to get back code that is as follows:

AT+CIPSTA?

+CIPSTA:ip:"192.168.1.110"
+CIPSTA:gateway:"192.168.1.1"
+CIPSTA:netmask:"255.255.255.0"

OK

However I get back the following code:

AT+CIPSTA?

+CIPSTA:ip:"192.168.1.110"
+CIPSTA:gateway:"192.1

Thanks for your patience,

also, if anyone has any CC on my code, or perhaps some hints, I would love to hear from you.

the header file as follows:

#pragma once
#include "IOT_board_global.h"
#include <RFade.h>
#include <Arduino.h>
#include <stdio.h>
#include <Temp.h>
#include <DS3231.h>



//constructors:
Fade fade; // Fade led 13 class constructor. takes an optional pin number.
Temp temp;
DS3231 rtc(SDA, SCL);

and my global variables.h as follows:

#pragma once

// Global variables:
  //for the timer pulled from unix time on the RTC
unsigned long uTime;

// time out previous millis for case 2 and 4.
unsigned long TOpms2 = 0; 
unsigned long TOcms2;
unsigned long TOpms4 = 0; 
unsigned long TOcms4;
unsigned long TOInterv = 8000;

  //the air sensor:
int airQual;
float airSens= A1;

  //the temperature sensor:
float tempVal;

  //grabbing the serial data:
int ESPPower = 2;
String kwBusy = "busy p...";
String kwOK = "OK";
String kwDISC = "WIFI DISCONNECT";
String kwConnect = "WIFI CONNECTED";
String kwGotIP = "WIFI GOT IP";
String kwError = "ERROR";
String kwIP = "+CIPSTA:ip:";
String kwGW = "+CIPSTA:gateway:";
String kwReady = "ready";
String LocalIP = "";
String Gateway = "";

// the serial data.
String Sd;

// variables to grab the start and end of the ip address and gateway.
int S1;
int S2;
int F1;
int F2;

char qm = '"';
int qm1;
int qm2;
int qm3;
int qm4;


String ESPSSID = "********";
String ESPPassword = "*********";

// FLAGS
bool Connect = false;
bool GotIP = false;
bool Ready = false;

Step 3 is to get rid of the String class and use character arrays.

Step 4++ (a big step) would be to get rid of the Serial class and manages the USART independently.