Programming question, how to call email when certain conditions exist

Hi, I have this code cobbled together maybe but it works well. I look at the level of fuel in a tank with a JSN-S04T and get the gallons in tank. I have an app in phone that can query and get the level and gallons. There is a email function in the end of setup that will, in future, (and works now) send when the level is at a certain level. I also want that email to send the level each week. OK so I don't understand how to call the email part of the code. Please document your responses, I won't understand it if you just say to do something, I need to see how to do it.
Thanks, Tom

#include <ESP8266WiFi.h>
#include "Gsender.h"

#pragma region Globals
const char* ssid = "ASUS";                       // WIFI network name
const char* password = "*********";              // WIFI network password
uint8_t connection_state = 0;                    // Connected to WIFI or not
uint16_t reconnect_interval = 10000;             // If not connected wait time to try again
#pragma endregion Globals

WiFiServer server (80);

//** CHANGE TO SUIT TANK DIMENSIONS
const int Depth = 52;                         //total depth of tank in inches, from sensor to base inside
const unsigned int Period = 2000;             //period between pings, in milliseconds. i.e  1 munute = 60,000. max 65535. Want longer? use unsigned long

//** SENSOR PINS
const int trigPin = 5;                           // GPIO5,  D1
const int echoPin = 4;                           // GPIO4,  D2

// Global variables
int Gallons;
int Distance;
int FuelDepth;
int duration;
int gallonList[] = {0,2,5,9,14,19,25,31,37,44,51,58,65,72,80,87,94,101,108,115,123,130,137,144,151,158,166,173,180,187,194,201,216,223,230,236,243,249,254,260,265,269,272,275,};

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);  
        Serial.println(nSSID);
    } else {
        WiFi.begin(ssid, password);
        Serial.println(ssid);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED && i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) && !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

void setup()
{
  Serial.begin (115200);
  pinMode(trigPin, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(echoPin, INPUT_PULLUP);

  // Connect to the Wi-Fi network
  Serial.println ();
  Serial.println ();
  Serial.print ( "Connecting with" );
  Serial.println (ssid);

  WiFi.begin (ssid, password);

  while (WiFi.status () != WL_CONNECTED) {
    delay (500);
    Serial.print ( "." );
  }
  Serial.println ( "" );
  Serial.println ( "Connected with WiFi." );

  // Start of the Web Server
  server.begin ();
  Serial.println ( "Web server started." );

  // This gets the IP address
  Serial.print ( "This is the IP to connect:" );
  Serial.print ( "http: //" );
  Serial.print (WiFi.localIP ());
  Serial.println ( "/" );

//...
    connection_state = WiFiConnect();
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

    Gsender *gsender = Gsender::Instance();    // Getting pointer to class instance           // sends amail
    String subject = "Heating oil level";
    if(gsender->Subject(subject)->Send("********@gmail.com", "Heating oil is low")) {
        Serial.println("Message sent.");
        delay(50);
    } else {
        Serial.print("Error sending message: ");
        Serial.println(gsender->getError());
   }
//...   
}


void loop() {

  digitalWrite(trigPin, LOW);

  delayMicroseconds(5);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  Distance = duration / 127.000;

  //***********Reading Fuel Tank

  if (Distance >= Depth || Distance == 0 )  Distance = Depth;      //check it does not go negative

  FuelDepth = Depth - Distance;

  Gallons = gallonList[FuelDepth];

  delay(50);

  // Check if a client has been connected
  WiFiClient client = server.available ();
  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response

          if (currentLine.length() == 0) {                    // Check to see if the client request was just the IP address if it was just refresh

            client.println("HTTP/1.1 200 OK");                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            client.println("Content-Type:text/html");         // and a content-type so the client knows what's coming, then a blank line
            client.println("");                               // The HTTP response ends with another blank line:

            // sends to network. works.
            // print out the fuel depth and gallons.
            client.println();                          // print blank line
            client.print("Gallons  ");
            client.println(Gallons);                   // send to client
            client.println();                          // print blank line
            client.print("Fuel  ");
            client.println(FuelDepth);                 // send to client
            client.print(" Inches");
            client.println();                          // print blank line
            delay(5);                                  // delay in between reads for stability
            
              break;                                 // break out of the while loop:
          }
          else {
            currentLine = "";                      // if you got a newline, then clear currentLine:
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
  }

  //************************* can be commented out, test use only
  Serial.println();
  Serial.println();
  Serial.println("Tank fuel distance: " + String(Distance));       //print distance
  Serial.println("Tank fuel depth: " + String(FuelDepth));         //print depth
  Serial.println("Tank gallons: " + String(Gallons));              //print gallons
  //***********************************************


  delay(10);

  //**    can be commented out, test only
  Serial.begin(115200);                                               // Open serial console.
  Serial.println();
  //*******************************

  delay(2000);

  client.stop();    // close the connection:
  Serial.println("client disconnected");
}

tom_bauer:
Please document your responses, I won't understand it if you just say to do something, I need to see how to do it.

No, you need to learn how to write code. This forum does not write code for you. You need to figure out how much time has elapsed and, if it is one week, then call the same sort of function that is inside setup(). Since you only have millis(), you can calculate how many milliseconds are in a week and do a comparison. Look at the Blink Without Delay example in the IDE to figure out how to determine elapsed time (File -> Examples -> 02.Digital -> BlinkWithoutDelay)

You just don't get it. thanks for your opinion though, I have been reading for a couple of days and do not understand how to call a function inside setup.

The problem with people teaching things is they completely understand it so just say to do it. How can I do it? I don't know how!! I have read lots with no or very little gain. I have put the emailing part in a

void email()

Now it does not email until I put

email()

line in void loop() so now I need to learn how to call it when a set of circumstances occurs such as Gallons is less than some amount but I cannot discover this.

I need to learn how to call it when a set of circumstances occurs such as Gallons is less than some amount

You can do something like this if you declare a boolean control variable emailSent and intitialize it to false.

if (Gallons<threshold and emailSent==false)
{
  emailSent = true;
  email();
}

This will send one email. The issue will be to determine the conditions where you want to reenable the code to send another email.

OK, thanks I understand that and did this, it sends when level gets to 50 gallons, just 1 time. Then needs reset which does not send but waits until 50 gal again. Could this reset emailSent to false after 2 days as a reminder? I think I remember delay cannot be used in loop without affecting other timing?
Tom

#include <ESP8266WiFi.h>
#include "Gsender.h"

#pragma region Globals
const char* ssid = "ASUS";                       // WIFI network name
const char* password = "*********";              // WIFI network password
uint8_t connection_state = 0;                    // Connected to WIFI or not
uint16_t reconnect_interval = 10000;             // If not connected wait time to try again
#pragma endregion Globals

WiFiServer server (80);

//** CHANGE TO SUIT TANK DIMENSIONS
const int Depth = 52;                         //total depth of tank in inches, from sensor to base inside
const unsigned int Period = 2000;             //period between pings, in milliseconds. i.e  1 munute = 60,000. max 65535. Want longer? use unsigned long

//** SENSOR PINS
const int trigPin = 5;                           // GPIO5,  D1
const int echoPin = 4;                           // GPIO4,  D2

// Global variables
bool emailSent = false;
char FuelMessage;
int Gallons;
int Distance;
int FuelDepth;
int duration;
int gallonList[] = {0, 2, 5, 9, 14, 19, 25, 31, 37, 44, 51, 58, 65, 72, 80, 87, 94, 101, 108, 115, 123, 130, 137, 144, 151, 158, 166, 173, 180, 187, 194, 201, 216, 223, 230, 236, 243, 249, 254, 260, 265, 269, 272, 275,};

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
  static uint16_t attempt = 0;
  Serial.print("Connecting to ");
  if (nSSID) {
    WiFi.begin(nSSID, nPassword);
    Serial.println(nSSID);
  } else {
    WiFi.begin(ssid, password);
    Serial.println(ssid);
  }

  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 50)
  {
    delay(200);
    Serial.print(".");
  }
  ++attempt;
  Serial.println("");
  if (i == 51) {
    Serial.print("Connection: TIMEOUT on attempt: ");
    Serial.println(attempt);
    if (attempt % 2 == 0)
      Serial.println("Check if access point available or SSID and Password\r\n");
    return false;
  }
  Serial.println("Connection: ESTABLISHED");
  Serial.print("Got IP address: ");
  Serial.println(WiFi.localIP());
  return true;
}

void Awaits()
{
  uint32_t ts = millis();
  while (!connection_state)
  {
    delay(50);
    if (millis() > (ts + reconnect_interval) && !connection_state) {
      connection_state = WiFiConnect();
      ts = millis();
    }
  }
}

void setup()
{
  Serial.begin (115200);
  pinMode(trigPin, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(echoPin, INPUT_PULLUP);

  // Connect to the Wi-Fi network
  Serial.println ();
  Serial.println ();
  Serial.print ( "Connecting with" );
  Serial.println (ssid);

  WiFi.begin (ssid, password);

  while (WiFi.status () != WL_CONNECTED) {
    delay (500);
    Serial.print ( "." );
  }
  Serial.println ( "" );
  Serial.println ( "Connected with WiFi." );

  // Start of the Web Server
  server.begin ();
  Serial.println ( "Web server started." );

  // This gets the IP address
  Serial.print ( "This is the IP to connect:" );
  Serial.print ( "http: //" );
  Serial.print (WiFi.localIP ());
  Serial.println ( "/" );

  //...
  connection_state = WiFiConnect();
  if (!connection_state) // if not connected to WIFI
    Awaits();          // constantly trying to connect
}

void email() {
  Gsender *gsender = Gsender::Instance();    // Getting pointer to class instance
  String subject = "Heating oil level";
  if (gsender->Subject(subject)->Send("********@gmail.com", "Heating oil is below 50 gallons")) {           // sends amail 
    Serial.println("Message sent.");
    delay(50);
  } else {
    Serial.print("Error sending message: ");
    Serial.println(gsender->getError());
  }
}
//...

void loop() {

  digitalWrite(trigPin, LOW);

  delayMicroseconds(5);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  Distance = duration / 127.000;

  //***********Reading Fuel Tank

  if (Distance >= Depth || Distance == 0 )  Distance = Depth;      //check it does not go negative

  FuelDepth = Depth - Distance;

  Gallons = gallonList[FuelDepth];

  FuelMessage = Gallons;

  delay(50);

  if (Gallons<50 and emailSent==false)
{
  emailSent = true;
  email();
//?? wait 2 days and set emailSent to false again?
}

  // Check if a client has been connected
  WiFiClient client = server.available ();
  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response

          if (currentLine.length() == 0) {                    // Check to see if the client request was just the IP address if it was just refresh

            client.println("HTTP/1.1 200 OK");                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            client.println("Content-Type:text/html");         // and a content-type so the client knows what's coming, then a blank line
            client.println("");                               // The HTTP response ends with another blank line:

            // sends to network. works.
            // print out the fuel depth and gallons.
            client.println();                          // print blank line
            client.print("Gallons  ");
            client.println(Gallons);                   // send to client
            client.println();                          // print blank line
            client.print("Fuel  ");
            client.println(FuelDepth);                 // send to client
            client.print(" Inches");
            client.println();                          // print blank line
            delay(5);                                  // delay in between reads for stability

            break;                                 // break out of the while loop:
          }
          else {
            currentLine = "";                      // if you got a newline, then clear currentLine:
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
  }

  //************************* can be commented out, test use only
  Serial.println();
  Serial.println();
  Serial.println("Tank fuel distance: " + String(Distance));       //print distance
  Serial.println("Tank fuel depth: " + String(FuelDepth));         //print depth
  Serial.println("Tank gallons: " + String(Gallons));              //print gallons
  //***********************************************


  delay(10);

  //**    can be commented out, test only
  Serial.begin(115200);                                               // Open serial console.
  Serial.println();
  //*******************************

  delay(2000);

  client.stop();    // close the connection:
  Serial.println("client disconnected");
}

This will reset the process when tank is refilled, but I would like to have the email repeat every 2 days as a failsafe reminder.

  if (Gallons<50 and emailSent==false)
{
  emailSent = true;
  email();
}

  if (Gallons>100 and emailSent==true)
{
  emailSent = false;                             //sets emailSent back to false when filled
}

would like to have the email repeat every 2 days as a failsafe reminder.

You can do this with a millis() timer and the control variables you have. You can make adjustments to the period based on the accuracy of the internal timer on the esp8266.

There are two new variables.

unsigned long timeSent;
unsigned long timeToReset = 2*24*60*60*1000ul;//two days in millis()

You set timeSent = millis() when the message is sent.

if (Gallons<50 and emailSent==false)
{
  emailSent = true;
  email();
  timeSent = millis();
}

Here's the millis() timer for the reset

if(emailSent == true and millis() - timeSent >= timeToReset)
{
  emailSent = false;
}

Thanks, I just made it send at 50 gal and again at 40 gal, then reset when filled. all works well.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.