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”