Tag Archives: save data to cloud

Arduino – Communicate With Server – Part 2 – Server Code for Saving Data

This article shows the server side code for a server which is gathering or sending data by polling method to an Arduino device.

This method or code is putting less load on the server (compared to socket) but data transmission is slower than socket.

<?php
date_default_timezone_set("Asia/Kolkata");
$conn = mysql_connect("localhost","root","**********");
if(!$conn)
{
    echo "Error: failed to connect DB Server";
    die();
}

if(!mysql_select_db("database_name",$conn))
{
    echo "Error: failed to connect DB";
    die();
}
$action = intval(strip_tags($_GET['action']));

if($action == 1)
{
    $temp = floatval(strip_tags($_GET['temp']));
    $paH = floatval(strip_tags($_GET['paH']));
    $paM = floatval(strip_tags($_GET['paM']));
    
    mysql_query("insert into weather (temperature, paH, paM, time) values(".$temp.",".$paH.",".$paM.",".time().")");
    //mysql_query("update led_status set led_1 = ".$led_1.", led_2 = ".$led_2);
    
    echo "success";
}
else
    if($action == 2)
    {
        $output = "";
        $result = mysql_query("select * from led_status");
        $rows = mysql_fetch_array($result);
        if($rows['led_1'] == 1)
        {
           $output = "led_1=1|";    
        }
        else
        {
           $output = "led_1=0|";    
        }
        
        if($rows['led_2'] == 1)
        {
           $output .= "led_2=1";    
        }
        else
        {
           $output .= "led_2=0";    
        }
        echo $output;
    }
    mysql_close($conn);
?>

 

The else part ( if($action == 2) ) output from the above will be

HTTP/1.1 200 OK
Date: Sun, 14 Feb 2016 20:33:16 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Content-Length: 15
Connection: close
Content-Type: text/html

led_1=0|led_2=1

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)