Chat freely about anything...

User avatar
By picstart
#33550 Spiffs is a file system and const myarray[] is an addressable array. Both have value but both are very different.
The spiffs snippet for a BMP180 data storage3 and later retrieval via a web page is interesting .....is there a way to get the complete code?
User avatar
By Atlantis
#33564 I would like to write my own code to parse commands incoming through UART interface. It looks like default AT library from SDK initializes entire set of commands after at_init(). I do not need all of them, I do nit want all of them. :) I am not even sure if I am going to use AT+CMD format.

On AVR I usually use a parser, which is going through array of structures. Every structure consists of character string and pointer to function. If string matches received command, given function is executed through pointer.

I know it is possible to store it all inside of RAM, if there won't be too many commands. I just don't want. I'd rather prefer to preserve a little bit more of RAM, to prepare space for further development.

So. Is it possible to operate on such const data structure, without using RAM.
User avatar
By GengusKahn
#33588
picstart wrote:Spiffs is a file system and const myarray[] is an addressable array. Both have value but both are very different.
The spiffs snippet for a BMP180 data storage3 and later retrieval via a web page is interesting .....is there a way to get the complete code?



Hi there, the Code is a modified version of Stephan Thesens WLAN Logger using an array which I have left in but commented out to see the difference....I have also removed some of my user interaction for obvious reasons.....
I have disabled any serial as I have a few LCD's and this lets me use the gpio's...(SDCARD ).....
This is the main sketch, I am in the process of moving and adding but feel free...This requires the NTP Files and the "Arduino Webgauge" this is a 15KB file containg the gauge, I can post this complete on the github.....
Code: Select all/*---------------------------------------------------
                 _____
                </\|/\>
          _-_-_-_ *|* _-_-_-_
         -_-_-_-_-\@/-_-_-_-_-
         
HTTP 1.1 Temperature & Humidity Webserver for ESP8266
for ESP8266 adapted in the Arduino IDE

Espressif SDK Functionality in the form of a dignostics page

Server Layout

http://ipaddress/diag                    SDK Functionality
                /monitor                 Google Gauges 2 DHT11
                /graphic                 Google Line Chart - 2 DHT11, BMP Temp, Vcc
                /graphic2                Google Line Chart - BMP180
                /table                   Datalog Table
                /yfireset                Reset the WiFi Connection
                /srestart                Reboot the system(ESP must be cold booted, this will fail directly after uploading a sketch)
                /pressure                Pressure Gauge from BMP180
                /                        Web to LCD
Credits to Stefan Thesen and The Guy's at .......http://www.ESP8266.com
With the use of http://espressif.com/new-sdk-release

The ESP8266 Arduino Reference http://arduino.esp8266.com/versions/1.6.5-1160-gef26c5f/doc/reference.html

With this release and a 1MByte Flash with 512KB SPIFFS can hold 3328 records of 120 bytes long Approx. 390KB

Set up an account at http://smtp2go.com
Encrypt your Password & Username using https://www.base64encode.org/

This evolution is the product of the Environment Monitor......
environmental.monitor.log@gmail.com

See a feed from 2 DHT11's on twitter at http://twitter.com/DDTMonitor

This will read various sensors and send an Email at a time or Sensor Condition
With the Data from the Sensors presented via Web Gauges, Graphs & Tables.....

Setup = 2 * DHT11 + BMP180 and an ESP8266-07 with 1MB Flash

There are various pins used to load boot code so if you change pins and it does not boot this is WHY!!

I2C  GPios 4 & 5
DHT  GPio  14 & 16


__________________________________________________________________________________________________
......Use 5v to 3v Level Shifters as 5V devices like PIR and HC-SR04 can damage your device.......
--------------------------------------------------------------------------------------------------
 ___/'¬_         /\
{_-_ ^  \_______//
     /           \
     \ _  _____  /
     || ||     |||
     || ||     ||| 
---------------------------------------------------*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "time_ntp.h"
#include "FS.h"
#include "DHT.h"
#include <Wire.h>
#include <SFE_BMP180.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display
SFE_BMP180 pressure;
// WiFi connection
const char* ssid = "ssid";
const char* password = "password";
String toaddres = "RCPT To: <Valid Email>";                 // Where your Last 24Hr Log has to be emailed To.......Time set below....
String frmaddrs = "MAIL From: <email setup with SMTP2GO>";  // Where your Log has to be emailed From.......
String b64Usernm = "username";                              // B64 Encrypted smtp2go Username
String b64Passwd = "password";                              // B64 Encrypted smtp2go Password
String lastdata;
String lastpres;
String DsTable;  //Discarded parts if the Strings......
String tmtxt1;   //Strings from the Web....
String tmtxt2;
boolean got_text = false;   //Print the Text to LCD if true......
boolean barom = false;
double baseline; // baseline pressure
// ntp timestamp
unsigned long ulSecs2000_timer=0;
//place holders
unsigned long lc=0;
int done=0;
// storage for Measurements; keep some mem free; allocate remainder
#define KEEP_MEM_FREE 21576
#define MEAS_SPAN_H 24
unsigned long ulMeasCount=0;                         // values already measured
unsigned long ulNoMeasValues=0;                      // size of array
unsigned long ulMeasDelta_ms;                        // distance to next meas time
unsigned long ulNextMeas_ms;                         // next meas time
unsigned long *pulTime;                              // array for time points of measurements stored in SRAM
float pfTemp,pfHum,pfTemp1,pfHum1,pfVcC;      // array for Environment/System measurements stored in SPIFFS
unsigned long ulReqcount;       // how often has a valid page been requested
unsigned long ulReconncount;    // how often did we connect to WiFi
unsigned long Dfsize;
// Create an instance of the server on Port 80-89 = Sensor 1 - 10
WiFiServer server(80);
WiFiClient client;
char popyahoo[] = "smtpcorp.com";  // set email service
int port = 2525;
////////////////////////////////////
// DHT21 / AMS2301 / DHT11 /DHT22 //
////////////////////////////////////
#define DHTPIN 14
#define DHTPIN1 16
ADC_MODE(ADC_VCC);
// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
// Declare each sensor
DHT dht(DHTPIN, DHTTYPE,12);
DHT dht1(DHTPIN1, DHTTYPE,13);
// needed to avoid link error on ram check
extern "C"
{
#include "user_interface.h"
}
void wsysreset()
{
  //Perform challenge to user before getting here to reboot !!!
  //Make an attempt to send mail or other backup of log files then reboot
    ESP.restart();
}
/////////////////////
// the setup routine
/////////////////////
void setup()
{
  dht.begin();
  dht1.begin();
  // setup globals
  ulReqcount=0;
  ulReconncount=0;
  pinMode(0, INPUT);  //Use the Flash Button.........
  // initialize the lcd
  lcd.init();
  lcd.backlight();
  // initialize the SPIFFS
  if (!SPIFFS.begin()) {
       lcd.print("SPIFFSinitFailed");
       while(1);
       }
  // clear any old data....
  if (SPIFFS.exists("/humidlog.old")){ SPIFFS.remove("/humidlog.old");} 
  if (SPIFFS.exists("/humidlog.CSV")){ SPIFFS.rename("/humidlog.CSV", "/humidlog.old");}
       if (pressure.begin())
       {
       }
       else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.

    lcd.print("BMP180 init fail");
    while(1); // Pause forever.
  }
   baseline = getPressure();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Sensor Init Done");   
  // inital connect
  WiFi.mode(WIFI_STA);
  WiFiStart();
  server.begin();
  // allocate ram for data storage
  uint32_t free=system_get_free_heap_size() - KEEP_MEM_FREE;
  ulNoMeasValues = free / (sizeof(unsigned long));  // array for time
  pulTime = new unsigned long[ulNoMeasValues];
/*  pfTemp = new float[ulNoMeasValues];  // Now Stored in SPIFFS File.............
  pfHum = new float[ulNoMeasValues];
  pfTemp1 = new float[ulNoMeasValues];
  pfHum1 = new float[ulNoMeasValues];
  pfVcC = new float[ulNoMeasValues];
  pfBMPT = new float[ulNoMeasValues];   
  pfBMP = new float[ulNoMeasValues];
 */
  if (pulTime==NULL)
  {
    ulNoMeasValues=0;
        lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Error in memory");
  }
  else
  {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set storage for ");
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Data Points ");
  lcd.print(ulNoMeasValues);
    float fMeasDelta_sec = MEAS_SPAN_H*3350./ulNoMeasValues;
    ulMeasDelta_ms = ( (unsigned long)(fMeasDelta_sec+0.5) ) * 1000;  // round to full sec
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Sample Every");
  lcd.setCursor(0, 1);
  lcd.print(ulMeasDelta_ms/1000);
  lcd.print(" Seconds");
  ulNextMeas_ms = millis()+ulMeasDelta_ms;
  }
}
///////////////////
// (re-)start WiFi
///////////////////
void WiFiStart()
{
  ulReconncount++;
 
  // Connect to WiFi network
  lcd.clear();
  lcd.print("Connecting to ");
  lcd.setCursor(0, 1);
  lcd.print(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    lcd.print(".");
  }
  lcd.clear();
  lcd.print("WiFi connected");
 
  // Start the server
  lcd.setCursor(0, 1);
  server.begin();
  lcd.print("Server started");
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Network Started ");
  // Print the IP address       
  lcd.setCursor(0, 1);
  lcd.print("IP= "); 
  lcd.print(WiFi.localIP());
  ///////////////////////////////
  // connect to NTP and get time
  ///////////////////////////////
  ulSecs2000_timer=getNTPTimestamp();
  lcd.clear();
  lcd.setCursor(8,0);
  lcd.print(epoch_to_string(ulSecs2000_timer).c_str());
  ulSecs2000_timer -= millis()/1000;  // keep distance to millis() counter
}
double getPressure()
{
  char status;
  double T,P,p0,a;

  // You must first get a temperature measurement to perform a pressure reading.
 
  // Start a temperature measurement:
  // If request is successful, the number of ms to wait is returned.
  // If request is unsuccessful, 0 is returned.

  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.
    // Use '&T' to provide the address of T to the function.
    // Function returns 1 if successful, 0 if failure.

    status = pressure.getTemperature(T);
    if (status != 0)
    {
      // Start a pressure measurement:
      // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
      // If request is successful, the number of ms to wait is returned.
      // If request is unsuccessful, 0 is returned.

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

        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Use '&P' to provide the address of P.
        // 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)
        {
          return(P);
        }
        else lcd.print("ror retrieving P");
      }
      else lcd.print("error starting P");
    }
    else lcd.print("ror retrieving T");
  }
  else lcd.print("error starting T");
}
/////////////////////////////////////
// make html table for measured data
/////////////////////////////////////
unsigned long MakeTable (WiFiClient *pclient, bool bStream)
{
  unsigned long ulLength=0;
 
  // here we build a big table.
  // we cannot store this in a string as this will blow the memory   
  // thus we count first to get the number of bytes and later on
  // we stream this out
  if (ulMeasCount==0)
  {
    String sTable = "No data available yet.<BR>";
    if (bStream)
    {
      pclient->print(sTable);
    }
    ulLength+=sTable.length();
  }
  else
  {
    unsigned long ulEnd;
    if (ulMeasCount>ulNoMeasValues)
    {
      ulEnd=ulMeasCount-ulNoMeasValues;
    }
    else
    {
      ulEnd=ulMeasCount;
    }
   File logF = SPIFFS.open("/humidlog.CSV", "r");
    if (!logF) {
      lcd.clear();
      lcd.print("rOr humidlog.CSV");
      while(1);
    }
    String sTable;
    String DsTable="";
    sTable = "<table style=\"width:100%\"><tr><th>Time / GMT</th><th>Int Temperature &deg;C</th><th>Int Humidity &#037;</th><th>Ext Temperature &deg;C</th><th>Ext Humidity &#037;</th><th>System Vcc</th><th>BMP Temp</th><th>Pressure MilliBar</th></tr>";
    sTable += "<style>table, th, td {border: 2px solid black; border-collapse: collapse;} th, td {padding: 5px;} th {text-align: left;}</style>";
    for (unsigned long li=0;li<ulEnd;li++)
    {
      unsigned long ulIndex=(li)%ulNoMeasValues;
      sTable += "<tr><td>";
      sTable += epoch_to_string(pulTime[ulIndex]).c_str();
      sTable += "</td><td>";
     DsTable = logF.readStringUntil('[');
      sTable += logF.readStringUntil(',');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(',');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(',');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(',');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(',');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(']');
      sTable += "</td><td>";
      sTable += logF.readStringUntil(',');     
      sTable += "</td></tr>";

      // play out in chunks of 1k
      if(sTable.length()>1024)
      {
        if(bStream)
        {
          pclient->print(sTable);
          //pclient->write(sTable.c_str(),sTable.length());
        }
        ulLength+=sTable.length();
        sTable="";
      }
    }
   
    // remaining chunk
    sTable+="</table>";
    ulLength+=sTable.length();
    if(bStream)
    {
      pclient->print(sTable);
      //pclient->write(sTable.c_str(),sTable.length());
    }   
  }
 
  return(ulLength);
}


////////////////////////////////////////////////////
// make google chart object table for measured data
////////////////////////////////////////////////////
unsigned long MakeList (WiFiClient *pclient, bool bStream)
{
  unsigned long ulLength=0;
 
  // here we build a big list.
  // we cannot store this in a string as this will blow the memory   
  // thus we count first to get the number of bytes and later on
  // we stream this out
  if (ulMeasCount>0)
  {
    unsigned long ulBegin;
    if (ulMeasCount>ulNoMeasValues)
    {
      ulBegin=ulMeasCount-ulNoMeasValues;
    }
    else
    {
      ulBegin=0;
    }
   File logF = SPIFFS.open("/humidlog.CSV", "r");
    if (!logF) {
      lcd.clear();
      lcd.print("rOr humidlog.CSV");
      while(1);
    }
    String sTable="";
    String DsTable="";
    for (unsigned long li=ulBegin;li<ulMeasCount;li++)
    {
      // result shall be ['18:24:08 - 21.5.2015',21.10,49.00],
      unsigned long ulIndex=li%ulNoMeasValues;
      sTable += "['";
      sTable += epoch_to_string(pulTime[ulIndex]).c_str();
      sTable += "',";
     DsTable = logF.readStringUntil('[');
  if (barom == true){
      DsTable += logF.readStringUntil(']');// Pressure Measurements are a different Scale......hence simple separation....   
      sTable += logF.readStringUntil(',');
      }
 else{
      sTable += logF.readStringUntil(']');// Pressure Measurements are a different Scale......hence simple separation....   
      }
      sTable += "],\n";
       
      // play out in chunks of 1k
      if(sTable.length()>1024)
      {
        if(bStream)
        {
          pclient->print(sTable);
          //pclient->write(sTable.c_str(),sTable.length());
        }
        ulLength+=sTable.length();
        sTable="";
      }
    }
   
    // remaining chunk
    if(bStream)
    {
      pclient->print(sTable);
      //pclient->write(sTable.c_str(),sTable.length());
    }
    ulLength+=sTable.length(); 
  }
 
  return(ulLength);
}


//////////////////////////
// create HTTP 1.1 header
//////////////////////////
String MakeHTTPHeader(unsigned long ulLength)
{
  String sHeader;
 
  sHeader  = F("HTTP/1.1 200 OK\r\nContent-Length: ");
  sHeader += ulLength;
  sHeader += F("\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n");
 
  return(sHeader);
}


////////////////////
// make html footer
////////////////////
String MakeHTTPFooter()
{
  String sResponse;
 
  sResponse  = F(" ");
/*  sResponse += ulReqcount;
  sResponse += F(" - Restarted WiFi Connection Count = ");
  sResponse += ulReconncount;
  sResponse += F(" - Free RAM = ");
  sResponse += (uint32_t)system_get_free_heap_size();
  sResponse += F(" - Max. Dataset Size = ");
  sResponse += ulNoMeasValues;*/
  sResponse += F("<BR>environmental.monitor.log@gmail.com<BR><FONT SIZE=-2>ESP8266 With DHT11 & BMP180 Sensors<BR><FONT SIZE=-2>Compiled Using ver. 1.6.5-1160-gef26c5f, built on Sep 30, 2015</body></html>");
  return(sResponse);
}
String emailbutton = "off";
String emailtime;
/////////////
// main loop
/////////////
void loop()
{
  //
  // Check button for email trigger
  //
    int button = 0;         // variable for reading the pushbutton status
    button = digitalRead(0);  // read the state of the pushbutton on gpio 0
  if (button == LOW) {
   emailbutton = "Send";
//LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Email Button...."));
  lcd.setCursor(0, 1);
  lcd.print(F("......Pressed.!!"));
  delay(1000);
  }
  ///////////////////
  // do data logging
  ///////////////////
  if (millis()>=ulNextMeas_ms)
  {
    char status;
    double T,a,P;
    P = getPressure();
    a = pressure.altitude(P,baseline);
    pressure.getTemperature(T);
      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);
    ulNextMeas_ms = millis()+ulMeasDelta_ms;
    pfHum = dht.readHumidity();
    pfTemp = dht.readTemperature();
if (pfHum==11.11 || pfTemp==11.11) {
  delay(4000);
  pfHum = dht.readHumidity();
  pfTemp = dht.readTemperature();
  }
    pfHum1 = dht1.readHumidity();
    pfTemp1 = dht1.readTemperature();
    pfVcC =  ESP.getVcc();   
    pulTime[ulMeasCount%ulNoMeasValues] = millis()/1000+ulSecs2000_timer;
    emailtime = epoch_to_string(pulTime[ulMeasCount%ulNoMeasValues]).c_str();
    lastdata="";
    lastpres="";
    lastdata += pfTemp;
    lastdata += ",hum=";
    lastdata += pfHum;
    lastdata += ",temp1=";
    lastdata += pfTemp1;
    lastdata += ",hum1=";
    lastdata += pfHum1;   
 String logdata = "[";
  logdata += pfTemp;
  logdata += ",";
  logdata += pfHum; 
  logdata += ",";
  logdata += pfTemp1;
  logdata += ",";
  logdata += pfHum1;
  logdata += ",";
  logdata += pfVcC/1000;
  logdata += ",";
  logdata += T;   
  logdata += "]";
  logdata += P;
  logdata += ",";
 lastpres += P;
 File logF = SPIFFS.open("/humidlog.CSV", "a");     
  if (logF) {
    logF.print(logdata);
    logF.close();
    logdata = "";
      }
    else {
      lcd.clear();
      lcd.print("rOr humidlog.CSV");
      while(1);
    } 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(pfTemp);
  lcd.setCursor(2, 0);
  lcd.print(F("C "));
  lcd.print(pfHum);
  lcd.setCursor(6, 0);
  lcd.print(F("% "));
  lcd.print(pfTemp1);
  lcd.setCursor(10, 0);
  lcd.print(F("C "));
  lcd.print(pfHum1);
  lcd.setCursor(14, 0);
  lcd.print(F("% ")); 
  lcd.setCursor(0, 1);
  lcd.print(P);
  lcd.print(F("mb")); 
  lcd.setCursor(12, 1);
  char tDigit = emailtime.charAt(1); 
  if (isDigit(tDigit)) {lcd.setCursor(11, 1);}  // Check for ":" no leading 0
  lcd.print(emailtime);
  delay(2000); 
     
// I2C LCD update, Ping or PIR and check email button Halt/Reboot
  if (emailtime.startsWith("7:51") || emailbutton.startsWith("Sen")) {// Set the time for the Log to be emailed !! no leading 0.....!!
    lcd.print(F("Got email - data"));
     if(sendEmail()) {
     lcd.clear();
     lcd.print(F("mail sent......"));
     delay(5000);
     wsysreset();
      }
      else {
      lcd.clear();
      lcd.print(F("Email FAILED..!!!"));
      while(1);
      }
     
  emailbutton = "off";
  }

  ulMeasCount++;
  }
if (got_text == true){
lc++;      // Use this to perform other actions........lots to choose from.....
  if (tmtxt1!=""){ 
   if (lc==100000 || lc==200000 || lc==300000 || lc==400000 || lc==500000 || lc==600000){   
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(tmtxt1);
        lcd.setCursor(0, 1);
        lcd.print(tmtxt2);
        }
        else{
        got_text == false;
   }
  }
if (lc>600000){lc=0;}
}
  //////////////////////////////
  // check if WLAN is connected
  //////////////////////////////
 
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFiStart();
  }
 
  ///////////////////////////////////
  // Check if a client has connected
  ///////////////////////////////////
  WiFiClient client = server.available();
  if (!client)
  {
    return;
  }
 
  // Wait until the client sends some data
  unsigned long ultimeout = millis()+250;
  while(!client.available() && (millis()<ultimeout) )
  {
    delay(1);
  }
  if(millis()>ultimeout)
  {
    return;
  }
 
  /////////////////////////////////////
  // Read the first line of the request
  /////////////////////////////////////
  String sRequest = client.readStringUntil('\r');
  client.flush();
 
  // stop client, if request is empty
  if(sRequest=="")
  {
    client.stop();
    return;
  }
 
  // get path; end of path is either space or ?
  // Syntax is e.g. GET /?show=1234 HTTP/1.1
  String sPath="",sParam="", sCmd="";
  String sGetstart="GET ";
  int iStart,iEndSpace,iEndQuest;
  iStart = sRequest.indexOf(sGetstart);
  if (iStart>=0)
  {
    iStart+=+sGetstart.length();
    iEndSpace = sRequest.indexOf(" ",iStart);
    iEndQuest = sRequest.indexOf("?",iStart);
   
    // are there parameters?
    if(iEndSpace>0)
    {
      if(iEndQuest>0)
      {
        // there are parameters
        sPath  = sRequest.substring(iStart,iEndQuest);
        sParam = sRequest.substring(iEndQuest,iEndSpace);
      }
      else
      {
        // NO parameters
        sPath  = sRequest.substring(iStart,iEndSpace);
      }
    }
  }
   
 
  ///////////////////////////
  // format the html response
  ///////////////////////////
  String sResponse,sResponse2,sHeader;
 
  /////////////////////////////////
  //  Update LCD with text from Web
  /////////////////////////////////
  //_________________________________________________________________
  // /ajax_inputs&L1=123456789&L2=abcdefghi&nocache=968337.7823963541
  //  1-9 on Line 1 and a - i on line 2
  //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
if (sPath.startsWith("/ajax_inputs&L1="))
   {
     ulReqcount++;
     tmtxt1="";
     tmtxt2="";
    got_text = true;                    // print the received text to the LCD if found
File in = SPIFFS.open("/temp.txt", "w");     
  if (in) {
    in.print(sPath);
    in.close();
    delay(1);
      }
    else {
      lcd.clear();
      lcd.print("rOr Temp.TXT");
      while(1);
    }
     in = SPIFFS.open("/temp.txt", "r");
     in.setTimeout(0);
String Dtmtxt = in.readStringUntil('=');
       tmtxt1 += in.readStringUntil('&');
       Dtmtxt = in.readStringUntil('=');
       tmtxt2 += in.readStringUntil('&');
     in.close();
       tmtxt1.replace("%20", " ");
       tmtxt2.replace("%20", " ");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(tmtxt1);
        lcd.setCursor(0, 1);
        lcd.print(tmtxt2);
      delay(3000);
   }
  //////////////////////////////////
  // format the html page for gauges
  //////////////////////////////////
 if(sPath=="/monitor")
  {
    ulReqcount++;
    int iIndex= (ulMeasCount-1)%ulNoMeasValues;
    sResponse  = F("<html>\n<head>\n<title>Environment Monitor</title>\n<script type=\"text/javascript\" src=\"https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['gauge']}]}\"></script>\n<script type=\"text/javascript\">\nvar temp=");
    sResponse += lastdata;   
    sResponse += F(";\ngoogle.load('visualization', '1', {packages: ['gauge']});google.setOnLoadCallback(drawgaugetemp);google.setOnLoadCallback(drawgaugehum);google.setOnLoadCallback(drawgaugetemp1);google.setOnLoadCallback(drawgaugehum1);\nvar gaugetempOptions = {min: -10, max: 40, yellowFrom: -10, yellowTo: 16,redFrom: 28, redTo: 40, minorTicks: 10, majorTicks: ['-10','0','10','20','30','40']};\n");
    sResponse += F("var gaugehumOptions = {min: 0, max: 100, yellowFrom: 0, yellowTo: 25, redFrom: 70, redTo: 100, minorTicks: 10, majorTicks: ['0','10','20','30','40','50','60','70','80','90','100']};\nvar gaugehum1Options = {min: 0, max: 100, yellowFrom: 0, yellowTo: 25, redFrom: 70, redTo: 100, minorTicks: 10, majorTicks: ['0','10','20','30','40','50','60','70','80','90','100']};\n");
    sResponse += F("var gaugetemp1Options = {min: -10, max: 40, yellowFrom: -10, yellowTo: 16,redFrom: 28, redTo: 40, minorTicks: 10, majorTicks: ['-10','0','10','20','30','40']};\nvar gaugetemp,gaugehum,gaugetemp1,gaugehum1;\nfunction drawgaugetemp() {\ngaugetempData = new google.visualization.DataTable();\n"); 
    sResponse += F("gaugetempData.addColumn('number', 'Int \260C');\ngaugetempData.addRows(1);\ngaugetempData.setCell(0, 0, temp);\ngaugetemp = new google.visualization.Gauge(document.getElementById('gaugetemp_div'));\ngaugetemp.draw(gaugetempData, gaugetempOptions);\n}\n\n");
    sResponse += F("function drawgaugehum() {\ngaugehumData = new google.visualization.DataTable();\ngaugehumData.addColumn('number', 'Int %');\ngaugehumData.addRows(1);\ngaugehumData.setCell(0, 0, hum);\ngaugehum = new google.visualization.Gauge(document.getElementById('gaugehum_div'));\ngaugehum.draw(gaugehumData, gaugehumOptions);\n}\n");
    sResponse += F("\n\nfunction drawgaugetemp1() {\ngaugetemp1Data = new google.visualization.DataTable();\n");
    sResponse += F("gaugetemp1Data.addColumn('number', 'Ext \260C');\ngaugetemp1Data.addRows(1);\ngaugetemp1Data.setCell(0, 0, temp1);\ngaugetemp1 = new google.visualization.Gauge(document.getElementById('gaugetemp1_div'));\ngaugetemp1.draw(gaugetemp1Data, gaugetemp1Options);\n}\n\n");
    sResponse += F("function drawgaugehum1() {\ngaugehum1Data = new google.visualization.DataTable();\ngaugehum1Data.addColumn('number', 'Ext %');\ngaugehum1Data.addRows(1);\ngaugehum1Data.setCell(0, 0, hum1);\ngaugehum1 = new google.visualization.Gauge(document.getElementById('gaugehum1_div'));\ngaugehum1.draw(gaugehum1Data, gaugehum1Options);\n}\n");
    sResponse += F("</script>\n</head>\n<body>\n<font color=\"#000000\"><body bgcolor=\"#d0d0f0\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\"><h1>Environment Monitor</h1><BR><BR><FONT SIZE=+1>Last Sample Taken ");
    sResponse += epoch_to_string(pulTime[iIndex]).c_str();

   
    sResponse2 = F("GMT<BR>\n<div id=\"gaugetemp_div\" style=\"float:left; width:200px; height: 200px;\"></div> \n<div id=\"gaugehum_div\" style=\"float:left; width:200px; height: 200px;\"></div>\n<div style=\"clear:both;\"></div>\n<div id=\"gaugetemp1_div\" style=\"float:left; width:200px; height: 200px;\"></div> \n<div id=\"gaugehum1_div\" style=\"float:left; width:200px; height: 200px;\">");
    sResponse2 += F("</div>\n<div style=\"clear:both;\"></div><p>Environment Display<BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a><BR><a href=\"/graphic\">Sensor Graph Page</a><BR><a href=\"/table\">Sensor Datalog Page</a><BR><a href=\"/diag\">Diagnostics Information Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a></p>");
   sResponse2 += MakeHTTPFooter().c_str();
   
    // Send the response to the client
    client.print(MakeHTTPHeader(sResponse.length()+sResponse2.length()).c_str());
    client.print(sResponse);
    client.print(sResponse2);
  }
  else if(sPath=="/")
  {
    ulReqcount++;
                           // send rest of HTTP header
                        client.println("HTTP/1.1 200 OK");     
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                        //client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                      File webFile = SPIFFS.open("/index1.htm", "r");        // open web page file
                        if (webFile) {
                            while(webFile.available()) {
                                client.print(webFile.readString()); // send web page to client
                            }
                            webFile.close();
                        }
  }
    else if(sPath=="/pressure")
  {
    ulReqcount++;
                           // send HTTP header
                        client.println("HTTP/1.1 200 OK");     
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                        client.println();
      // send web page
      for (int i = 0; i < 7; ++i) {
      String name = "/presure";
      name += i;
      name += ".htm";

      File webFile = SPIFFS.open(name, "r");
      if (!webFile) {
        lcd.clear();       
        lcd.print("ror open webpage");
        while(1);
        }
             while(webFile.available()) {
             client.print(webFile.readString()); // send web page to client
             }
        }
                           client.print(lastpres);       
                      File webFile = SPIFFS.open("/presureF.htm", "r");        // open web page file
                        if (webFile) {
                           while(webFile.available()) {
                           client.print(webFile.readString()); // send web page to client
                            }
                        }                       
                       
  }
  else if(sPath=="/table")
  ////////////////////////////////////
  // format the html page for /tabelle
  ////////////////////////////////////
  {
    ulReqcount++;
    unsigned long ulSizeList = MakeTable(&client,false); // get size of table first
   
    sResponse  = F("<html><head><title>Environment Monitor</title></head><body>");
    sResponse += F("<font color=\"#000000\"><body bgcolor=\"#d0d0f0\">");
    sResponse += F("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">");
    sResponse += F("<h1>Environment Monitor</h1>");
    sResponse += F("<FONT SIZE=+1><BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a>");
    sResponse += F("<BR><a href=\"/graphic\">Sensor Graph Page</a><BR><a href=\"/diag\">Diagnostics Information Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a><BR><BR>Sample Interval ");
    sResponse += ulMeasDelta_ms/1000;
    sResponse += F(" Seconds<BR>");
    // here the big table will follow later - but let us prepare the end first
     
    // part 2 of response - after the big table
    sResponse2 = MakeHTTPFooter().c_str();
   
    // Send the response to the client - delete strings after use to keep mem low
    client.print(MakeHTTPHeader(sResponse.length()+sResponse2.length()+ulSizeList).c_str());
    client.print(sResponse); sResponse="";
    MakeTable(&client,true);
    client.print(sResponse2);
  }
  else if(sPath=="/graphic")
  ///////////////////////////////////
  // format the html page for /grafik
  ///////////////////////////////////
  {
    ulReqcount++;
    unsigned long ulSizeList = MakeList(&client,false); // get size of list first

    sResponse  = F("<html>\n<head>\n<title>Environment Monitor</title>\n<script type=\"text/javascript\" src=\"https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}\"></script>\n");
    sResponse += F("<script type=\"text/javascript\"> google.setOnLoadCallback(drawChart);\nfunction drawChart() {var data = google.visualization.arrayToDataTable([\n['Time / GMT', 'InTmp', 'InHum', 'ExTmp', 'ExHum', 'SySVcc', 'SySTemp'],\n");   
    // here the big list will follow later - but let us prepare the end first
     
    // part 2 of response - after the big list
    sResponse2  = F("]);\nvar options = {title: 'Environment',vAxes:{0:{viewWindowMode:'explicit',gridlines:{color:'black'},format:\"##.##\260C\"},1: {gridlines:{color:'transparent'},format:\"##,##%\"},},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1},2:{targetAxisIndex:0},3:{targetAxisIndex:1},4:{targetAxisIndex:0},5:{targetAxisIndex:0},},curveType:'function',legend:{ position: 'bottom'}};");
    sResponse2 += F("var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));chart.draw(data, options);}\n</script>\n</head>\n");
    sResponse2 += F("<body>\n<font color=\"#000000\"><body bgcolor=\"#d0d0f0\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\"><h1>Environment Monitor</h1><BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a><BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/table\">Sensor Datalog Page</a>");
    sResponse2 += F("<BR><a href=\"/diag\">Diagnostics Information Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a><BR><BR>\n<div id=\"curve_chart\" style=\"width: 600px; height: 400px\"></div>");
    sResponse2 += MakeHTTPFooter().c_str();
   
    // Send the response to the client - delete strings after use to keep mem low
    client.print(MakeHTTPHeader(sResponse.length()+sResponse2.length()+ulSizeList).c_str());
    client.print(sResponse); sResponse="";
    MakeList(&client,true);
    client.print(sResponse2);
  }
  else if(sPath=="/yfireset")
  {
    ulReqcount++;
   
                                client.println("HTTP/1.1 200 OK");
                                client.println("Content-Type: text/html");
                                client.println("Connection: close");
                                client.println();
                                client.println("<!DOCTYPE HTML>");
                                client.print("<html><head><title>Environment Monitor</title></head><body>");
                                client.print("<font color=\"#000000\"><body bgcolor=\"#d0d0f0\">");
                                client.print("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">");
                                client.print("<h1>Environment Monitor<BR>WiFi Reset Page </h1><BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a>");
                                client.print("<BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/graphic\">Sensor Graph Page</a><BR><a href=\"/table\">Sensor Datalog Page</a><BR><BR><BR><BR>Restarted WiFiConnections = ");
                                client.print(ulReconncount);
                                client.print("<BR><FONT SIZE=-2>environmental.monitor.log@gmail.com<BR><FONT SIZE=-2>ESP8266 With DHT11 & BMP180 Sensors<BR>");
                                client.print("<FONT SIZE=-2>Compiled Using ver. 1.6.5-1160-gef26c5f, built on Sep 30, 2015<BR>");
                                client.println("<IMG SRC=\"https://raw.githubusercontent.com/genguskahn/ESP8266-For-DUMMIES/master/SoC/DimmerDocs/organicw.gif\" WIDTH=\"250\" HEIGHT=\"151\" BORDER=\"1\"></body></html>");

  WiFiStart();
  }
  else if(sPath=="/diag")
  {   
     float   servolt1 = ESP.getVcc();
     long int spdcount = ESP.getCycleCount();
     delay(1);
     long int spdcount1 = ESP.getCycleCount();
     long int speedcnt = spdcount1-spdcount;
     FlashMode_t ideMode = ESP.getFlashChipMode();
     ulReqcount++;
File logF = SPIFFS.open("/humidlog.CSV", "r");     
     Dfsize = logF.size();
                                client.println("HTTP/1.1 200 OK");
                                client.println("Content-Type: text/html");
                                client.println("Connection: close");
                                client.println();
                                client.println("<!DOCTYPE HTML>");
                                client.print("<html><head><title>Environment Monitor</title></head><body>");
                                client.print("<font color=\"#000000\"><body bgcolor=\"#d0d0f0\">");
                                client.print("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">");
                                client.print("<h1>Environment Monitor<BR>SDK Diagnostic Information</h1><BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a>");
                                client.print("<BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/graphic\">Sensor Graph Page</a><BR><a href=\"/table\">Sensor Datalog Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a><BR>Restarted WiFiConnections = ");
                                client.print(ulReconncount);
                                client.print("<BR>  Web Page Requests = ");
                                client.print(ulReqcount);
                                client.print("<BR>  WiFi Station Hostname = ");
                                client.print(wifi_station_get_hostname());
                                client.print("<BR>  Free RAM = ");
                                client.print((uint32_t)system_get_free_heap_size()/1024);
                                client.print(" KBytes<BR>  Logged Sample Count = ");
                                client.print(ulMeasCount);
                                client.print("<BR>  Total Sample points in 24 Hours = ");
                                client.print(ulNoMeasValues);                                 
                                client.print("<BR>  Average Sample Logging Interval = ");
                                client.print((ulMeasDelta_ms/1000+0.5)/60,0);
                                client.print(" Minutes<BR>  SDK Version = ");
                                client.print(ESP.getSdkVersion());
                                client.print("<BR>  Boot Version = ");
                                client.print(ESP.getBootVersion());
                                client.print("<BR>");
                                client.print("  Free Sketch Space  = ");
                                client.print(ESP.getFreeSketchSpace()/1024);
                                client.print(" KBytes<BR>  Sketch Size  = ");
                                client.print(ESP.getSketchSize()/1024);
                                client.print(" KBytes<BR>");
                                client.printf("  Flash Chip id = %08X\n", ESP.getFlashChipId());
                                client.print("<BR>");
                                client.printf("  Flash Chip Mode = %s\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN"));
                                client.print("<BR>  Flash Size By ID = ");
                                client.print(ESP.getFlashChipRealSize()/1024);
                                client.print(" KBytes<BR>  Flash Size (IDE) = ");
                                client.print(ESP.getFlashChipSize()/1024);
                                client.print(" KBytes<BR>  Flash Speed = ");
                                client.print(ESP.getFlashChipSpeed()/1000000);
                                client.print(" MHz<BR>  ESP8266 CPU Speed = ");
                                client.print(ESP.getCpuFreqMHz());
                                client.print(" MHz<BR>");
                                client.printf("  ESP8266 Chip id = %08X\n", ESP.getChipId());
                                client.print("<BR>  System Instruction Cycles Per Second = ");
                                client.print(speedcnt*1000); 
                                client.print("<BR>  Last System Restart Time = ");
                                client.print(epoch_to_string(ulSecs2000_timer).c_str());
                                client.print("<BR>  Last System Restart Reason = ");
                                client.print(ESP.getResetInfo());
                                client.print("<BR>  System Time = ");
                                client.print(emailtime);                               
                                client.print(" (Last Recorded Sample Time)<BR>  System VCC = ");
                                client.print(servolt1/1000, 3);
                                client.print(" V <BR>  Datalog File Size in Bytes = ");
                                client.print(Dfsize);
                                client.print("<BR><FONT SIZE=-2>environmental.monitor.log@gmail.com<BR><FONT SIZE=-2>ESP8266 With DHT11 & BMP180 Sensors<BR>");
                                client.print("<FONT SIZE=-2>Compiled Using ver. 1.6.5-1160-gef26c5f, built on Sep 30, 2015<BR>");
                                client.println("<IMG SRC=\"https://raw.githubusercontent.com/genguskahn/ESP8266-For-DUMMIES/master/SoC/DimmerDocs/organicw.gif\" WIDTH=\"250\" HEIGHT=\"151\" BORDER=\"1\"></body></html>");
  }
   else if(sPath=="/srestart")
  {
                                client.println("HTTP/1.1 200 OK");
                                client.println("Content-Type: text/html");
                                client.println("Connection: close");
                                client.println();
                                client.println("<!DOCTYPE HTML>");
                                client.print("<html><head><title>Environment Monitor</title></head><body>");
                                client.print("<font color=\"#000000\"><body bgcolor=\"#d0d0f0\">");
                                client.print("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">");
                                client.print("<h1>Environment Monitor<BR>Please wait 10 Seconds......<BR><FONT SIZE=+2>System Reset Page !!!! </h1><BR><a href=\"/graphic2\">Pressure Graph Page</a><BR><a href=\"/pressure\">Pressure Gauge Page</a>");
                                client.print("<BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/graphic\">Sensor Graph Page</a><BR><a href=\"/table\">Sensor Datalog Page</a><BR><a href=\"/diag\">Diagnostics Information Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a><BR><BR><BR><BR>Restarted WiFiConnections = ");
                                client.print(ulReconncount);
                                client.print("<BR><BR><BR><FONT SIZE=-2>environmental.monitor.log@gmail.com<BR><FONT SIZE=-2>ESP8266 With DHT11 & BMP180 Sensors<BR>");
                                client.print("<FONT SIZE=-2>Compiled Using ver. 1.6.5-1160-gef26c5f, built on Sep 30, 2015<BR>");
                                client.println("<IMG SRC=\"https://raw.githubusercontent.com/genguskahn/ESP8266-For-DUMMIES/master/SoC/DimmerDocs/organicw.gif\" WIDTH=\"250\" HEIGHT=\"151\" BORDER=\"1\"></body></html>");
client.stop();
wsysreset();
  }
  else if(sPath=="/graphic2")
  //////////////////////////////////////
  // format the html page for Barometer
  //////////////////////////////////////
  {
    barom = true;
    ulReqcount++;
    unsigned long ulSizeList = MakeList(&client,false); // get size of list first

    sResponse  = F("<html>\n<head>\n<title>Environment Monitor</title>\n<script type=\"text/javascript\" src=\"https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}\"></script>\n");
    sResponse += F("<script type=\"text/javascript\"> google.setOnLoadCallback(drawChart);\nfunction drawChart() {var data = google.visualization.arrayToDataTable([\n['Time / GMT', 'Pressure'],\n");   
    // here the big list will follow later - but let us prepare the end first
     
    // part 2 of response - after the big list
    sResponse2  = F("]);\nvar options = {title: 'Barometric Pressure',vAxes:{0:{viewWindowMode:'explicit',gridlines:{color:'black'},format:\"##.##mbar \"},},series:{0:{targetAxisIndex:0},},curveType:'function',legend:{ position: 'bottom'}};");
    sResponse2 += F("var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));chart.draw(data, options);}\n</script>\n</head>\n");
    sResponse2 += F("<body>\n<font color=\"#000000\"><body bgcolor=\"#d0d0f0\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\"><h1>Environment Monitor</h1><BR><a href=\"/pressure\">Pressure Gauge Page</a><BR><a href=\"/monitor\">Sensor Gauges Page</a><BR><a href=\"/graphic\">Sensor Graph Page</a>");
    sResponse2 += F("<BR><a href=\"/table\">Sensor Datalog Page</a><BR><a href=\"/diag\">Diagnostics Information Page</a><BR><a href=\"/\">Monitor LCD Text Input Page</a><BR>\n<div id=\"curve_chart\" style=\"width: 600px; height: 400px\"></div>");
    sResponse2 += MakeHTTPFooter().c_str();
   
    // Send the response to the client - delete strings after use to keep mem low
    client.print(MakeHTTPHeader(sResponse.length()+sResponse2.length()+ulSizeList).c_str());
    client.print(sResponse); sResponse="";
    MakeList(&client,true);
    client.print(sResponse2);
    barom = false;
  }
  else
////////////////////////////
// 404 for non-matching path
////////////////////////////
  {
    sResponse="<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server, What did you sk for?.</p></body></html>";
    ulReqcount++;
    sHeader  = F("HTTP/1.1 404 Not found\r\nContent-Length: ");
    sHeader += sResponse.length();
    sHeader += F("\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n");
   
    // Send the response to the client
    client.print(sHeader);
    client.print(sResponse);
  }
 
  // and stop the client
  client.stop();
}

byte sendEmail()
{
//  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    lcd.print(F("."));
  }
  lcd.clear();
  lcd.print(F("WiFi connected"));
  lcd.setCursor(0, 1);
  lcd.print(F("IP="));
  lcd.print(WiFi.localIP());

  byte thisByte = 0;
  byte respCode;

  if(client.connect( popyahoo,port) == 1) {
    lcd.clear();
    lcd.print(F("connectedsmtp2go"));
  } else {
    lcd.clear();
    lcd.print(F("SMconnect failed"));
    return 0;
  }
  if(!eRcv()) {lcd.print("before ehlo");return 0 ;}
    lcd.clear();
    lcd.print(F("Sending ehlo"));
  client.print("EHLO ");
    client.println(WiFi.localIP());
  lcd.setCursor(0, 1); 
  if(!eRcv()) {lcd.print("ehlo");return 0 ;}
  lcd.clear();
  lcd.print(F("Sending auth login"));
  client.println("auth login");
  lcd.setCursor(0, 1);
  if(!eRcv()) {lcd.print("auth");return 0 ;}
  lcd.print("Sending User");
// Change to your base64 encoded user
  client.println(b64Usernm);//
  if(!eRcv()) {lcd.print("user");return 0 ;}
  lcd.clear();
  lcd.print(F("Sending Password"));
// change to your base64 encoded password
  client.println(b64Passwd);//
  lcd.setCursor(0, 1);
  if(!eRcv()) {lcd.print("ehlo");return 0;}
  lcd.clear();
// change to your email address (sender)  Send All Mail to Environment Monitor
  lcd.print(F("Sending From"));
  client.println(frmaddrs);
  lcd.setCursor(0, 1);
  if(!eRcv()) {lcd.print("email");return 0 ;}
  lcd.clear();
// change to recipient address Send All Mail to Environment Monitor
  lcd.print(F("Sending To"));
  client.println(toaddres);
  lcd.setCursor(0, 1);
  if(!eRcv()) {lcd.print("email");return 0 ;}
  lcd.clear();
  lcd.print(F("Sending DATA"));
  client.println("DATA");
  lcd.setCursor(0, 1);
  if(!eRcv()) {lcd.print("email");return 0 ;}
int ulEnd=0;
if (ulMeasCount>ulNoMeasValues) {ulEnd=(ulMeasCount-ulNoMeasValues);}
String sTable="";
  lcd.clear();
  lcd.print(F("Sending email"));

// change to recipient address Send All Mail to Environment Monitor
  client.println("To: The Environment Monitor <environmental.monitor.log@gmail.com>");

// change to your address This is sensor ID
  client.print("From: Weather Station Development <");
  client.print(wifi_station_get_hostname());
  client.println(">");

  client.println("Subject: ESP8266 Daily Environment Report\r\n");

  client.println("This is Sent Directly from An ESP8266 Module every 24 Hours");

  client.print("The Total Number Of Environment Samples Values Being Tranferred Are -  ");

  client.println(ulMeasCount-ulEnd);
 
  client.println("_____________________________________________________________");
File logF = SPIFFS.open("/humidlog.CSV", "r");
    if (!logF) {
      lcd.clear();
      lcd.print("rOr humidlog.CSV");
      while(1);
    }
    for (unsigned long li=ulMeasCount;li>ulEnd;li--)
    {
      unsigned long ulIndex=(li-1)%ulNoMeasValues;
      sTable += epoch_to_string(pulTime[ulIndex]).c_str();
      sTable += " ,";
     DsTable = logF.readStringUntil('[');
      sTable += logF.readStringUntil(']');
      sTable += (",");
      sTable += logF.readStringUntil(',');   
      client.println(sTable);
      sTable="";
    }

  client.println(sTable);

  client.println("_________________End of Data_______________");

  client.println(".");
  lcd.clear();
  if(!eRcv()) {lcd.print("aftersending");return 0 ;}
  lcd.setCursor(0, 1);
  lcd.print(F("Sending QUIT"));
  client.println("QUIT");
  lcd.clear();
  if(!eRcv()) {lcd.print("afterQuit");return 0 ;}
  client.stop();
  lcd.setCursor(0, 1);
  lcd.print(F("disconnected"));
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;
  int loopCount = 0;

  while(!client.available()) {
    delay(1);
    loopCount++;

    // if nothing received for 20 seconds, timeout
    if(loopCount > 20000) {
      client.stop();
      lcd.clear();
      lcd.print(F("20 sec Timeout"));
      return 0;
    }
  }

  respCode = client.peek();

  while(client.available())
  {
    thisByte = client.read();
  }

  if(respCode >= '4')
  {
    efail();
    return 0;
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;
  int loopCount = 0;

  client.println(F("QUIT"));

  while(!client.available()) {
    delay(1);
    loopCount++;

    // if nothing received for 10 seconds, timeout
    if(loopCount > 10000) {
      client.stop();
      lcd.clear();
      lcd.print(F("efail Timeout"));
      return;
    }
  }

  while(client.available())
  {
    thisByte = client.read();
  }

  client.stop();
  lcd.clear();
  lcd.print(F("disconnected"));
}

User avatar
By GengusKahn
#33792 To Index to a data point, each record is 64 bytes, there are place holders to count in the string record
to select an individual data point.

See the single file, Arduino Sketch, ESP8266 Monitor code using the SPIFFS
https://raw.githubusercontent.com/EnvironmentMonitor/ESP8266-DHT11-WiFi_Sensor/master/DDTMonitor.ino

The SPIFFS Record selction.......to allow reading/modifying a value.......
Code: Select allFile dataFile1 = SPIFFS.open("/humidlog.CSV", "r"); //  a = append/modify, r = read or create w = write
  if(!dataFile1.seek(0, SeekSet))   //  Other Commands are seekCur or seekEnd
  {
    Serial.println(F("Rewind fail"));
    dataFile1.close();
  }
 stringholder = dataFile1.readStringUntil("[");  //Start of Record idexed to with file offset currently=0