Arduino – Communicate With Server – Part 1 – Arduino code

The below code send some data (temperature and pressure here) to a server and reads back some data from server. The send part works every 5 minutes and the read part works every 5 seconds. This code works by polling method.

All delays might have room for optimization

#include <SFE_BMP180.h> //from sparkfun 
#include <Wire.h>
#include <SoftwareSerial.h>

#define _SS_MAX_RX_BUFF 512 // RX buffer size //Default is 64

SoftwareSerial esp8266(2,3);

String inputBuffer = "";
boolean stringComplete = false;
int inputBufferIndex;

int led1Pin = 9;
int led2Pin = 10;

byte led1Status, led2Status;

String data1 = ""; 
String data2 = "";
String data3 = "";
String data4 = "";
String data5 = "";

unsigned long startTimeDataCapture = 0;
unsigned long lastDataSent = 0;

SFE_BMP180 pressure;

char status;
double T,P,temp,paH,paM;


void setup() {
  // put your setup code here, to run once:
  
  inputBuffer.reserve(1024); //to be optimized
  
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  
  pressure.begin();
  
  
  //Serial.begin(19200);

  esp8266.begin(9600);
  esp8266.println("AT");  delay(100);
  esp8266.println("AT+UART_CUR=4800,8,1,0,0"); //set the Baud rate 
  esp8266.flush(); delay(100);
  while(esp8266.available())
  {
      //Serial.write(esp8266.read());
      esp8266.read();  //clear the buffer
      delay(80);
  }
  esp8266.end();

  esp8266.begin(4800);
  esp8266.println("AT"); delay(100);
  
  esp8266.println("AT+CIPMUX=1"); delay(100);
  esp8266.println("AT+CWMODE=1"); delay(100); 
  esp8266.println("AT+CWJAP="TP-LINK_POCKET_3020_304764","password""); esp8266.flush();  delay(1000);  
  
  while(esp8266.available())
  {
      //Serial.write(esp8266.read());
      esp8266.read(); //clear the buffer
      delay(80);
  }
    
  delay(5000);
}


void loop() {

  while(esp8266.available())
  {
      //Serial.write(esp8266.read());
      esp8266.read();
      delay(10);
  }

  inputBuffer = "";
  stringComplete = false;
  
  /***** Read the LED status for sending to server  -- will be implemented later */
  if(digitalRead(led1Pin) == HIGH)
  {
    led1Status = 1;
  }
  else
  {
    led1Status = 0;
  }

  if(digitalRead(led2Pin) == HIGH)
  {
    led2Status = 1;
  }
  else
  {
    led2Status = 0;
  }
  
  status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Function returns 1 if successful, 0 if failure.

    status = pressure.getTemperature(T);
    if (status != 0)
    {
      temp = T;

      
      // Start a pressure measurement
      status = pressure.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);


        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.

        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          paM = P;
          paH = P*0.0295333727;
        }
        else
        {
          paM = -1;
          paH = -1;
        }
      }
      else
      {
          paM = -1;
          paH = -1;
      }
    }
    else
    {
      temp = -1;
    }
  }
  else
  {
    temp = -1;
  }

   
   //send the data to server
  
  if(millis() - lastDataSent > 300000) //send data every 5 minutes 
  {
      lastDataSent = millis();
      data1 = "GET /webservice.php?action=1&temp="+String(temp)+"&paM="+String(paM)+"&paH="+String(paH)+" HTTP/1.1";
  }
  else
  {
      data1 = "GET /webservice.php?action=2 HTTP/1.1";
  }
  //Serial.println(data1);
  data2 = "Host: xxx.xxx.xxx.xxx";
  data3 = "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
  data4 = "Accept: text/html";
  data5 = "Connection: close";
  //Serial.println(data1.length()+data2.length()+data3.length()+data4.length()+data5.length());
  
  esp8266.println("AT+CIPSTART=4,"TCP","xxx.xxx.xxx.xxx",80");  delay(1000); 
   while(esp8266.available())
  {
      //Serial.write(esp8266.read());
      esp8266.read();
      delay(10);
  }
  esp8266.println("AT+CIPSEND=4,"+String(data1.length()+data2.length()+data3.length()+data4.length()+data5.length()+12)); // the 12 here is related to the data being sent below. Each dataline is sent using println (required to sent) which adds a \r\n after every line. \r and \n makes 2 chars. So for every data sent using println 2 count is increased in the total data length paramter of AT+CIPSEND
  delay(1000);
  while(esp8266.available())
  {
      //Serial.write(esp8266.read());
      esp8266.read();
      delay(10);
  }
  
  
  esp8266.println(data1); delay(1);
  esp8266.println(data2); delay(1);
  esp8266.println(data3); delay(1);
  esp8266.println(data4); delay(1);
  esp8266.println(data5); delay(1);
  esp8266.println();  delay(1); esp8266.flush();

  startTimeDataCapture = millis();
  while(1)
  {
    if(esp8266.available())
      inputBuffer += (char)esp8266.read();
      
    if(inputBuffer.indexOf("CLOSED")> 0 || millis() - startTimeDataCapture > 10000) //The server sends a close after a successful transmission. In case that didn't come (net failure, server failure whatever) then don't wait more than 20 seconds
    {
      stringComplete = true;
      //Serial.println(inputBuffer);
      //delay(1);
      break;
    }
  }

  //check if data came from server
  if(stringComplete)
  {
    inputBufferIndex = inputBuffer.indexOf("led_1=");
    if(inputBufferIndex > -1)
      led1Status = (int)(inputBuffer[inputBufferIndex+6]-'0');  // int conversion required else it was being considered as string by the codes
          
    inputBufferIndex = inputBuffer.indexOf("led_2=");
    if(inputBufferIndex > -1)
      led2Status = (int)(inputBuffer[inputBufferIndex+6]-'0');

    if(led1Status == 1)
    {
      led1Status = 1;
    }
    else
       if(led1Status == 0)
        {
          led1Status = 0;
        }
    
    if(led2Status == 1)
    {
      led2Status = 1;
    }
    else
       if(led2Status == 0)
        {
          led2Status = 0;
        }
  
    digitalWrite(led1Pin,led1Status);
    digitalWrite(led2Pin,led2Status);

    stringComplete = false;
    inputBuffer = "";
  }  
  else
  {
    esp8266.println("AT+CIPCLOSE=4"); // if for any reason  the server didn't reply properly, then close the connection
  }
  delay(5000); // wait 5 secs before making next server call
}

In future revision will implement exception handling (e.g – if the wi-fi is not found then go to sleep and try after certain intervals till connection is established, and only after connection is established move to the next step)

One thought on “Arduino – Communicate With Server – Part 1 – Arduino code

Leave a Reply