Help on defining a function

I am trying to create a function to send an email - I want to send different message text depending on a prior test, so I'm trying to send a parameter (simply a 0 or a 1) when I call the function, and within the function the message text is set to two different messages corresponding to the 0 or the 1.

I am getting an error message related to the function, and have tried numerous solutions, none of which have worked, so I'm hoping for advice. I have not created my own function before, so I suspect the error is a simple one. The function is called "sendEmail(acStatus)" and acStatus can be 0 or 1. I have tried defining the function in and out of the setup() and without "int" , using "void" instead.

I have also tried putting the function code at the end of the sketch.

Here's the code and error messages (I've put the function name in bold at each place it is used to make it easier to find):

type or paste code here

// Define pins; these won't change and so are constants
const int acTestPin = 33;         // The GPIO pin for testing state of AC relay contacts.  This is an INPUT
const int greenLedPin = 25;       // The GPIO pin for the Green LED.                       This is an OUTPUT.
const int redLedPin = 26;         // The GPIO pin for the Red LED.                         This is an OUTPUT.
const int buzzerPin = 14;         // The GPIO pin for the buzzer.                          This is an OUTPUT.
const int maxEmailsCountOff = 3;  //This is the maximum number of emails we want to receive.
const int maxEmailsCountOn = 3;
const int acCheckDelay = 5000;  // This is how long to wait (in milliseconds) before checking to see if mains is still OFF after an initial failure of the mains. 5000 = 5 seconds.

//Define the variables. These will change, and so are not constant
int emailCountOn = 0;  //initialise the email for ON count variable to zero
int emailCountOff = 0;
int acStatus = 0;  // This provides the status of the mains, i.e. 1 = ON, 0 = OFF

#include <Arduino.h>
#include <WiFi.h>
#include <ESP_Mail_Client.h>

#define WIFI_SSID "******"   //Elmtree House wifi
#define WIFI_PASSWORD "*********"  //Elmtree House wifi password

// The smtp host name is smtp.gmail.com for GMail, and the port is 465
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

/* The sign in credentials. These are the new email address and application password */
#define AUTHOR_EMAIL "*****@gmail.com"
#define AUTHOR_PASSWORD "**** **** **** ****"

/* Recipient's email*/
#define RECIPIENT_EMAIL "***@gmail.com"

/* Declare the global used SMTPSession object for SMTP transport */
SMTPSession smtp;

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);
void setup() {
  // Begin serial communication at 9600 baud rate
  Serial.begin(9600);
  // initialize digital pin buzzerPin as an output.
  pinMode(buzzerPin, OUTPUT);
  // initialise digital pin greenLedPi as an output
  pinMode(greenLedPin, OUTPUT);
  // initialize digital pin redLedPin as an output
  pinMode(redLedPin, OUTPUT);
  // initialise digital pin acTestPin as an input
  pinMode(acTestPin, INPUT);
}
// *********************
//function to send the email
int **sendEmail(acStatus)** 
{
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  /*  Set the network reconnection option */
  MailClient.networkReconnect(true);

  /** Enable the debug via Serial port
        * 0 for no debugging
        * 1 for basic level debugging
        *
        * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h
        */
  smtp.debug(1);

  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

  /* Declare the Session_Config for user defined session credentials */
  Session_Config config;

  /* Set the session config */
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = "";

  /*
        Set the NTP config time
        For times east of the Prime Meridian use 0-12
        For times west of the Prime Meridian add 12 to the offset.
        Ex. American/Denver GMT would be -6. 6 + 12 = 18
        See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
        */
  config.time.ntp_server = F("europe.pool.ntp.org,time.nist.gov");
  config.time.gmt_offset = 0;
  config.time.day_light_offset = 0;

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = F("ESP");
  message.sender.email = AUTHOR_EMAIL;
  message.subject = F("From your AC Mains Monitor");
  message.addRecipient(F("Steve"), RECIPIENT_EMAIL);
  //message.addCc(RECIPIENT_CC1); //This is for the CC email address
  //Set the raw text message
  String textMsg;
  Serial.println("at the delay point - stick the pin back in!!");
  delay(5000);
  if (acStatus = ON) {
    textMsg = "Mains is restored to kitchen circuit";  // this is the mesage I want to send if mains is back ON
  } else {
    textMsg = "Mains is OFF in kitchen circuit";  // this is the mesage I want to send if mains is OFF
  }
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

  /* Connect to the server */
  if (!smtp.connect(&config)) {
    ESP_MAIL_PRINTF("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    return;
  }

  if (!smtp.isLoggedIn()) {
    Serial.println("\nNot yet logged in.");
  } else {
    if (smtp.isAuthenticated())
      Serial.println("\nSuccessfully logged in.");
    else
      Serial.println("\nConnected with no Auth.");
  }
  /* having done all of the above to set up the wifi and email stuff, send the Email and close the session */

  if (!MailClient.sendMail(&smtp, &message))
    ESP_MAIL_PRINTF("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
  
}
// *********************
void loop() {
  // This 'while loop' checks to see if the AC relay is operated, i.e. mains is ON. If is, then just loop around indefinitely until the mains fails.
  while (digitalRead(acTestPin) == LOW) {
    digitalWrite(buzzerPin, LOW);     //turn off buzzer
    digitalWrite(redLedPin, LOW);     // turn off the red LED
    digitalWrite(greenLedPin, HIGH);  // light the green LED
    Serial.println("Mains is ON");
    emailCountOn = 0;  //set the email counter to zero in case previous alarms have incremented the email count value
    Serial.print("emailCountOn is = ");
    Serial.println(emailCountOn);
    emailCountOff = 0;
    delay(500);  // wait half a second
  }
  // If the code gets to this point, it means the AC has failed, and so the acTestPin will be HIGH
  delay(acCheckDelay);                 //wait before checking again to see if mains is still OFF, i.e. the acTestPin is still HIGH
  if (digitalRead(acTestPin) == HIGH)  //need to check that mains is still OFF after the delay
  {
    Serial.println("Mains is still OFF after acCheckDelay");

    if ((emailCountOff < maxEmailsCountOff) && (digitalRead(acTestPin) == HIGH)) {
      /* The mains is still OFF after "acCheckDelay" seconds, and we haven't sent more than 3 emails, so now need to send a mail, increment the email count, light the Red LED, 
      turn off the Green LED and sound the buzzer briefly. */
      Serial.print("The emailCountOff is = ");
      Serial.println(emailCountOff);
      Serial.println("Time to send an email to say Mains is OFF");
      acStatus = 0;
      **sendEmail(acStatus);**
      emailCountOff = ++emailCountOff;
    }
    Serial.print("The emailCountOff is = ");
    Serial.println(emailCountOff);
    digitalWrite(greenLedPin, LOW);  // turn off the green LED
    digitalWrite(redLedPin, HIGH);   // turn on the red LED
    Serial.println("Mains is OFF");
    digitalWrite(buzzerPin, HIGH);  //turn on the buzzer
    delay(5000);                    //keep the buzzer on for 5 seconds
    digitalWrite(buzzerPin, LOW);   //turn off buzzer
  }
  if ((emailCountOn < maxEmailsCountOn) && (digitalRead(acTestPin) == LOW)) {
    Serial.print("The emailCountOn is = ");
    Serial.println(emailCountOn);
    Serial.println("Time to send an email to say Mains is ON");
    acStatus = 1;
    **sendEmail(acStatus);**
    emailCountOn = ++emailCountOn;
    Serial.print("The emailCountOn is = ");
    Serial.println(emailCountOn);
    //we've incremented the email counter - now need to tell the user that mains is ON
    digitalWrite(greenLedPin, HIGH);  // turn off the green LED
    digitalWrite(redLedPin, LOW);     // turn on the red LED
    Serial.println("Mains is ON");
    digitalWrite(buzzerPin, LOW);  //turn off buzzer
  }

}  //end loop

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status) {
  /* Print the current status */
  Serial.println(status.info());
  /* Print the sending result */
  if (status.success()) {
    // ESP_MAIL_PRINTF used in the examples is for format printing via debug Serial port
    // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266.
    // In ESP8266 and ESP32, you can use Serial.printf directly.

    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failed: %d\n", status.failedCount());
    Serial.println("----------------\n");

    for (size_t i = 0; i < smtp.sendingResult.size(); i++) {
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);
      // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if
      // your device time was synched with NTP server.
      // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970.
      // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970)
      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str());  //month, day of month, Year, Hours
      //Minutes, Seconds
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients.c_str());
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
    }
    Serial.println("----------------\n");
    // You need to clear sending result as the memory usage will grow up.
    smtp.sendingResult.clear();
  }
}

This is the error message:

/Users/steveknell/Documents/Arduino/my code/AC_monitor_v2/AC_monitor_v2.ino:55:5: error: redefinition of 'int sendEmail'
55 | int sendEmail(acStatus)
| ^~~~~~~~~
/Users/steveknell/Documents/Arduino/my code/AC_monitor_v2/AC_monitor_v2.ino:55:5: note: 'int sendEmail' previously declared here
55 | int sendEmail(acStatus)
| ^~~~~~~~~
/Users/steveknell/Documents/Arduino/my code/AC_monitor_v2/AC_monitor_v2.ino: In function 'void loop()':
/Users/steveknell/Documents/Arduino/my code/AC_monitor_v2/AC_monitor_v2.ino:175:16: error: 'sendEmail' cannot be used as a function
175 | sendEmail(acStatus);
| ~^~
/Users/steveknell/Documents/Arduino/my code/AC_monitor_v2/AC_monitor_v2.ino:192:14: error: 'sendEmail' cannot be used as a function
192 | sendEmail(acStatus);
| ~^~
Multiple libraries were found for "SD.h"
Used: /Users/steveknell/Library/Arduino15/packages/esp32/hardware/esp32/3.1.1/libraries/SD
Not used: /Users/steveknell/Library/Arduino15/libraries/SD
exit status 1

Compilation error: redefinition of 'int sendEmail'

Apologies - I just noticed an error - which doesn't solve the issue - which is that I have written:

if (acStatus = ON)

instead of

if (acStatus = 1)

I've corrected this and re-compiled, but it made no difference, as suspected!

should use ==, not =

This line tells me that you have more than one .INO sketches in your sketch folder.

Other problem

You need to specify the type of the argument that you pass. You only have specified the return type.

So the function could be

int sendEmail(int acStatus)
{

The return type tells the compiler that you're planning to return an integer. But you don't. E.g. in below you do not return anything.

If you're not planning to return anything, this would be the function

void sendEmail(int acStatus)
{

Thank you so much - this change worked perfectly!

Hi - I'm not sure I understand your reply; I have many .INO sketches in my sketch folder and I did not think the compiler would look at any other sketches when compiling a given sketch.

But I could be wrong....!!

Good spot Greg - that would have had me going in circles for a loooong time...!!

Thank you!

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