Sending a JSON Object to the cloud, each second and each 5 minutes

My project is a Home Monitoring system, I collect different sensor information using an Arduino One (plus Ethernet Shield), the sketch, :

  1. Reads the sensor
  2. build a JSON object
  3. Each sample rate POST the JSON to an external server

I am measuring two kind of variables, with different sampling rates (1 second and 5 minutes)

  • Parameters related to my home electrical supply (Voltage and Ampere sensors)
  • Parameters related to Environmental parameters (Temperature, Humidity, Luminosity)

My sketch is based on the usual ones HTTP clients like Thingspeak / Pachube. My problem is that I can not deal well with two different sampling rates, my sketch never runs the condition to make the HTTPPost of variables each 5 minutes, although it runs the 1 second sampling. It seems that the connection is always opened and the if statement is not fullfilled, client.connected() is always true, unfortunately all the Ethernet library documentation is not very deep.

My Sketch:

#include <Ethernet.h>
#include <SPI.h>
#include <dht.h>    

// Variables Globales
const unsigned long Tiempo_UpdateELEC = 1 * 1000; // 1 Sg POST (Volt, Amp, Pot, Energ)
const unsigned long Tiempo_UpdateTH = 5 * 60 * 1000; // 5 min  POST (Temp. y Humedad)
const float Pot2Ener = 1 / (60 * 60); // Pot (W) x 1Sg (Muestreo) x 1 h/3600Sg

const int VoltPin = A0; 
int sensorVolt = 0; // Voltaje Integer (0-1023)
float valueVolt = 0.0; // Voltaje VacRMS (0-450V)   
char Volt[7];       // Formato 123.45 V

const int AmpPin = A1;   
int sensorAmp = 0 ; // Amperaje Integer (0-1023)
float valueAmp = 0.0; // Amperios (0-25A) 
char Amp[6];        // Formato 12.34 A

float valuekW = 0.0; // kW = Volt (450V) x Amp (25A) = 11250 kW
char kW[9];   // Formato 12,345.7 kW

float valuekWh = 0.0; // kWh = Pot (kW) x T (1Sg) = 11.250 kWs = 3.125 kWh
char kWh[7];   // Formato 1.2345 kWh

// DHT11 Library
dht DHT;
#define DHT11_PIN 5

EthernetClient client;

long int lastElecPOSTTime = 0;    // millis() ultimo POST Voltios y Amperios
long int lastTHPostTime = 0;      // millis() ultimo POST Temperatura y Humedad
long int lastConnectionTime = 0;  // millis() ultima conexion POST
boolean lastConnected = false; // Hubo conexion el tic anterior?
int failedCounter = 0;        // Nº veces falla conexion para RESET tarjeta Ethernet

void setup() {
  // 1. Inicializacin de PINs Digitales
  //pinMode(ledPin, OUTPUT);
    
  // 2. Setup Serial
  Serial.begin(115200);
  Serial.println(F("--------------------- SETUP -------------------"));
  Serial.println(F("--- 1. SETUP: Inicializacion Serial completada ---"));

  // 3. Setup Ethernet Stack
  startEthernet();
  Serial.println(F("------------------ FIN SETUP ------------------"));
}

void loop () {
  // 1. Lectura e Impresión datos RED ETHERNET
  if (client.available()) 
  {
     char c=client.read();
     Serial.print(c);
  }
  
  if (!client.connected() && lastConnected) {
     Serial.println(F("...Desconectado de Red Ethernet"));
     client.stop();
  }
  
  // 3. HTTP POST www.server.com:8086/db/ , de Volt/Amp/Pot/Ener
  
  if (!client.connected() && ((millis() - lastElecPOSTTime) > Tiempo_UpdateELEC))
  {
    sensorVolt = analogRead(VoltPin);
    valueVolt = (float(sensorVolt) / 1023.0 ) * 450.0; // Rango Sensor 0-450V
    dtostrf(valueVolt, 5, 2, Volt);  // Float -> char [7]

    sensorAmp = analogRead(AmpPin);
    valueAmp = (float(sensorAmp) / 1023.0 ) * 25.0 ;  // Rango Sensor 0-25A
    dtostrf(valueAmp, 2, 2, Amp);    // Float -> char [6]

    valuekW = valueAmp * valueVolt;       // Rango Calculo: 0 - 11.250kW
    dtostrf(valuekW, 5, 1, kW);     // Float -> char [9]
  
    valuekWh = valuekW * Pot2Ener;     // Rango Calculo: 0 - 3.125kW
    dtostrf(valuekWh, 4, 3, kWh);     // Float -> char [7]
  
    // JSON Object compatible InfluxDB:
    // data =  [{ "name":"P2M1","   (Nombre Serie: Planta 2, Mesa 1)
    //            "columns":[ "Vac","Iac","Wac","Whac"],
    //            "points": [[ 123.45, 12.34, 12,3456.7, 1,234 ]] }];
    char data[110] = "[{"
                     "\"name\":\"P2M1_Elec\","
                     "\"columns\":[\"Vac\","
                                  "\"Iac\","
                                  "\"Wac\","
                                  "\"Whac\"],"
                     "\"points\":[[" ;
                          strcat(data, Volt);
                          strcat(data, ",");
                          strcat(data, Amp);
                          strcat(data, ",");
                          strcat(data, kW);
                          strcat(data, ",");
                          strcat(data, kWh);
                          strcat(data, "]] }]");

    updateHTTPPOST(data);
    lastElecPOSTTime = millis();
  }
   
  // 4. HTTP POST www.server.com:8086/db/, de Temp. y Hum
  
  if (!client.connected() && ((millis() - lastTHPostTime) > Tiempo_UpdateTH))
  {
    // I CAN NOT NEVER ENTER IN THIS IF CONDITION !!!!!!!!!!!
    // JSON Object compatible InfluxDB:
    // data =  [{ "name":"P2M1","   (Nombre Serie: Planta 2, Mesa 1)
    //            "columns":[ "T","H",],
    //            "points": [[ 12.3, 12 ]] }];
 
    int chk = DHT.read11(DHT11_PIN);
    float temp = DHT.temperature;
    float hum = DHT.humidity;
    char Temperatura[6], Humedad[6];
                
    char data[110] = "[{"
                     "\"name\":\"P2M1_Elec\","
                     "\"columns\":[\"T\","
                                  "\"H\"],"
                     "\"points\":[[" ;
                     // strcat(data, Temp);
                     // strcat(data, ",");
                     // strcat(data, Hum);
                     // strcat(data, "]] }]");
                         
    switch (chk)
    {
      case DHTLIB_OK:              
                dtostrf(temp, 4, 2, Temperatura);
                dtostrf(hum, 4, 2, Humedad);
                strcat(data, Temperatura);
                strcat(data, ",");
                strcat(data, Humedad);
                strcat(data, "]] }]");   
 break;

      default: 
               strcat(data, "DHTErr");
               strcat(data, ",");
               strcat(data, "DHTErr");
               strcat(data, "]] }]");
       break;
      }
   
    updateHTTPPOST(data);   
    lastTHPostTime = millis();
  }
    
  // 5. Resetear conexion si > 3 fallos de conexion
  if (failedCounter > 3) {
    failedCounter = 0;
    startEthernet();
  } 

  lastConnected = client.connected();
} 
 
// FUNCION:startEthernet() //
void startEthernet()
{
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  client.stop();
  Serial.println(F("--- 2. SETUP: startethernet(): Conectando red Ethernet ..."));
  delay(1000);
   
  if (Ethernet.begin(mac) == 0) {
    Serial.println(F("--- 2. SETUP: startethernet(): Fallo Configuracion Ethernet ---"));
  }
  else{
    Serial.print(F("--- 2. SETUP: startethernet(): Conexion DHCP, IP: ")); 
    Serial.print(Ethernet.localIP());
  }
}


//   FUNCION: HTTPpost()   //
void updateHTTPPOST(String POSTdata)
{
  
  if (client.connect("server.com", 8086)) // Conexion a Servidor
  {
    Serial.println("--------------START POST-------------------------");
    // HTTP POST Headers
    client.print(F("POST /db/Test_Casa/series?u=root&p=XXXXXX HTTP/1.1\n"));  
    client.println(F("Host: server.com"));  
    client.print(F("User-Agent: Arduino/1.0\n"));  
    client.print(F("Connection: Close\n")); 
    client.print(F("Content-Type: application/x-www-form-urlencoded\n"));  
    client.print(F("Content-Length: "));
    client.print(POSTdata.length());
    client.print(F("\n\n"));   
          
    // HTTP POST Body
    client.print(POSTdata);
          Serial.print(POSTdata);
    
    lastConnectionTime = millis();

    // Chequeo POST con exito
    if (client.connected()) 
    { 
      Serial.println(F("----------------FIN POST-------------------------"));
      failedCounter=0;
       
    } else {
      failedCounter++;
      Serial.println(F("Conexion con Servidor perdida"));
      Serial.println(String(failedCounter));
    }
    
  } 
    else  
  {
     failedCounter++;
     Serial.println(F("No puedo Conectarme a Servidor"));
     Serial.print(F("Conexion perdida Num. "));
     Serial.println(String(failedCounter));
     lastConnectionTime = millis();
  }
}

might not be this but try

client.print(F("Connection: close\n")); (small close, not Close)

This might be why the connection is not being closed by the server.

If this doesnt fix it, try using a new client for every connection

void updateHTTPPOST(String POSTdata)
{
  EthernetClient client;
  ...//send data
  client.stop();
}

You can then remove all your client.connected() checks

Thank you very much!, after one week pondering about this, your suggestion did it!

HTTP Headers are really a picky issue!!, I just changed the header, from:

Connection: Close

to:

Connection: close

And I can now see all the messages flowing at different sampling rate. I don get any message lost like before.

Awesome! Yeah HTTP requests are always a nightmare. Glad it's fixed anyway