ESP32 Stops Sending Emails!

Hi everyone.

I've been struggling on this issue for a while now, and I am unable to find a feasible solution, so I would really appreciate it if anyone in this forum can help me out!

I'm using a 7-in-1 soil sensor. An Arduino Uno reads the sensor data parameters through an RS485 module. In addition, a DFRobot Firebeetle ESP32 is wired to the Arduino Uno for serial communication. The ESP32 gets the data from the Arduino Uno and sends it to an email address after every specific time interval.

Everything was working fine for about 2 weeks, where suddenly, the ESP32 stopped sending emails with the sensor readings. The power supply is fine, and the Arduino Uno is still able to read the sensor parameters. But for some reason, the ESP32 has stopped sending those sensor parameters to my email. Could it be a memory issue?

This is my code in the Arduino Uno:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <stdio.h>

 
#define RE 8
#define DE 7

 
const byte cond[] = {0x01,0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xce};
const byte ph[]   = {0x01,0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};
const byte nitro[]= {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte pota[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
const byte temp[] = {0x01,0x03, 0x00, 0x12, 0x00, 0x02, 0x64, 0x0e};
const byte moisture[] = {0x01, 0x03, 0x00, 0x12, 0x00, 0x01, 0x24, 0x0f};

uint16_t values[11];
char buffer[40];
 
SoftwareSerial mod(2,3);
 
void setup() {
  Serial.begin(115200);
  mod.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  delay(1000);
}


void loop() {
 uint16_t val1,val2,val3,val4,val5,val6,val7;
 
  val1 = sensor_request(nitro[0],nitro[1],nitro[2],nitro[3],nitro[4],nitro[5],nitro[6],nitro[7]);
  sprintf(buffer, "Nitrogen    = %04u mg/kg\r\n",    val1);
  Serial.print(buffer);  delay(450);
  
  val2 = sensor_request(phos[0],phos[1],phos[2],phos[3],phos[4],phos[5],phos[6],phos[7]);
  sprintf(buffer, "Phosphorous   = %04u mg/kg\r\n", val2);
  Serial.print(buffer);  delay(450);
 
  val3 = sensor_request(pota[0],pota[1],pota[2],pota[3],pota[4],pota[5],pota[6],pota[7]);
  sprintf(buffer, "Potassium     = %04u mg/kg\r\n",   val3);
  Serial.print(buffer); delay(450);

  val4 = sensor_request(ph[0],ph[1],ph[2],ph[3],ph[4],ph[5],ph[6],ph[7]);
  sprintf(buffer, "PH            = %04u  \r\n",               val4);
  Serial.print(buffer); delay(450);

  val5 = sensor_request(cond[0],cond[1],cond[2],cond[3],cond[4],cond[5],cond[6],cond[7]);
  sprintf(buffer, "Electrical Conductivity   = %04u us/cm\r\n",val5);
  Serial.print(buffer); delay(450);
 
  val6 = sensor_request(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7]);
  sprintf(buffer, "Temperature    = %04u degrees celsius\n",    val6);
  Serial.print(buffer);

  val7 = sensor_request(moisture[0],moisture[1],moisture[2],moisture[3],moisture[4],moisture[5],moisture[6],moisture[7]);
  sprintf(buffer, "Moisture    = %04u R.H\n",    val7);
  Serial.print(buffer);

  // Add timestamps to each value
  unsigned long currentMillis = millis();
  String data = String(currentMillis) + "," + String(val1) + "," + String(val2) + "," + String(val3) + "," + String(val4) + "," + String(val5) + "," + String(val6) + "," + String(val7);

  // Send the data to the Arduino MKR 1010
  mod.println(data);

  delay(5000);  // Send data every 5 seconds

}
 
 uint16_t sensor_request(byte d1,byte d2,byte d3,byte d4,byte d5,byte d6,byte d7,byte d8){
  byte inicio;
  uint16_t hbyte;
  while (mod.available()) mod.read(); //Esvazia Buffer Leitura...
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  mod.write(d1);mod.write(d2);mod.write(d3);mod.write(d4);
  mod.write(d5);mod.write(d6);mod.write(d7);mod.write(d8);
  mod.flush(); 
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(250);
 
  inicio=0;
   for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    if (inicio == 0 and values[i] ==0 and mod.available()) values[i] = mod.read();
    if (inicio == 0 and values[i] ==0 and mod.available()) values[i] = mod.read();
    if (inicio == 0 and values[i] ==0 and mod.available()) values[i] = mod.read();
    inicio=1;
  }
 /*
  sprintf(buffer,"%02x %02x %02x %02x %02x %02x %02x %02x ", d1,d2,d3,d4,d5,d6,d7,d8);
  Serial.print(buffer);
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();  
*/ 
  return (values[3] << 8 | values[4]);
}

uint8_t temperature(){
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(temp); i++ ) mod.write( temp[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
    for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", temp[i]);
        Serial.print(buffer);
  }
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();
  return (values[3] << 16 | values[4]);
}


uint8_t PH(){
  uint8_t ph_val=0;
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(ph); i++ ) mod.write( ph[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
    for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", ph[i]);
        Serial.print(buffer);
  }
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();
  ph_val = values[3] << 16 | values[4];
  return ph_val;
}


uint8_t condutividade(){
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(cond); i++ ) mod.write( cond[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
  for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", cond[i]);
        Serial.print(buffer);
  }
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();  
  return (values[3] << 16 | values[4]);
}

 
uint8_t phosphorous(){
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(phos); i++ ) mod.write( phos[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();  
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
  for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", phos[i]);
        Serial.print(buffer);
        // Serial.print(nitro[i] ,HEX); Serial.print(" ");
  }
  Serial.print (" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();
  return (values[3] << 16 | values[4]);
}
 
uint8_t potassium(){
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(pota); i++ ) mod.write( pota[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();  
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
  for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", pota[i]);
        Serial.print(buffer);
  }
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();
  return (values[3] << 16 | values[4]);
 }

 uint8_t moistureLevel(){
  while (mod.available()) mod.read(); 
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(1);
  for (uint8_t i = 0; i < sizeof(moisture); i++ ) mod.write( moisture[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(200);
  if (mod.available()>7) mod.read();  
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
  }
  for(byte i=0;i<8;i++) {
        sprintf(buffer,"%02x ", moisture[i]);
        Serial.print(buffer);
  }
  Serial.print(" => ");
  for(byte i=0;i<7;i++){
        sprintf(buffer,"%02x ", values[i]);
        Serial.print(buffer);
  }
  Serial.println();
  return (values[3] << 16 | values[4]);
 }

And this one is for the ESP32:

#include <WiFi.h>
#include <EMailSender.h>

const char* ssid = " ";
const char* password = " ";

String data = ""; 
String completeMessage = ""; // To store the complete message from Arduino Uno
unsigned long lastSendTime = 0;  // To keep track of the last sending time
const unsigned long sendInterval = 7200000;  // 2 hour in milliseconds

EMailSender emailSend(" ", " ");

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 3, 1); // RX, TX (use the correct pins)
}

void loop() {
  // connect to wifi first
  WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
   }

  Serial.println("Connected to WiFi");
  
  // Check if it's time to send data
  if (millis() - lastSendTime >= sendInterval) {
    // Read data from the Arduino Uno over Serial
    while (Serial2.available() > 0) {
      char receivedChar = Serial2.read();
      completeMessage += receivedChar;
    }

    // Check if it's time to send
    if (millis() - lastSendTime >= sendInterval) {
      // Print the complete received message for debugging
      Serial.print("Received Message: ");
      Serial.println(completeMessage);

      // Create and send the email
      EMailSender::EMailMessage message;
      message.subject = "Sensor Data";
      message.message = completeMessage;

      EMailSender::Response resp = emailSend.send(" ", message);

      Serial.println("Sending status:");
      Serial.println(resp.status);
      Serial.println(resp.code);
      Serial.println(resp.desc);

      // Clear the complete message to prepare for the next one
      completeMessage = "";

      // Update the last send time
      lastSendTime = millis();

      // clear data 
      data = "";
    }
  }
}

If anyone could help me debug the issue, that would be greatly appreciated!

how is the ESP32 connected to the UNO?
the UNO uses 5V logic the ESP32 3.3V logic
the UNO serial TX tp EsP32 Rx should have a potential divider to convert the logic levels or the ESP32 can be damaged

can you load any code into the ESP32, e.g. the blink example?

ESP32 has 5V tolerant pins.

Get wireshark and see what the ESP32 sends.

Hello! Yes, the ESP32 still works. I can load a blink example. The problem is that it is able to read the sensor readings from the Arduino Uno but it just stops sending emails.

is the ESP32 still receiving messages from the UNO - it is just the emails are not received?
can you upload a printout of the serial monitor (as text not a screen image)?
e.g. what is the value of resp.status etc?

Edit: it looks like the UNO transmits a new message every 5 seconds
could you be overloading the email SMTP server?
what if you change it to every minute?

Yes, the ESP32 is still receiving messages from the UNO! I'll try to get you a printout of the serial monitor. (The project is implemented in another country for a university project, so I'm in contact with a Professor over there to help me troubleshoot! Sorry if this causes a delay in my replies)

Also, my Professor ran the code again. The ESP32 was able to send emails for a couple of hours again before completely stopping.

I'll change the transmission to every minute and ask my Professor to test it. I'll update you on the results of this as well

I repeat myself, but please get wireshark and sniff the traffic.

Hi @itssaraki ,

I suggest to change your ESP32 code first:

  • WiFi.begin() is called every loop(). Without having checked the WiFi library it is not necessary and it might create problems ...
  • Serial data are only read from the serial buffer every two hours but without any synchronization.
  • A message is considered "complete" if the buffer is empty. That's not really a valid criteria.
  • There are two nested if (millis()-) conditions where the second is not useful.

For the WiFi part you could extract the connection code, call it in setup() and in loop() only if the connection is broken; here just a snippet of the relevant parts:

// ..

void connectWifi(){
  // connect to wifi first
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
 }
  Serial.println("Connected to WiFi");
}

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 3, 1); // RX, TX (use the correct pins)
  connectWifi();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
	  connectWifi()
  };
  // Check if it's time to send data
  if (millis() - lastSendTime >= sendInterval) {
// ...

Then I would move the code that reads from Serial2 into loop(), store the last complete message and transmit the last received complete message (whatever that is ...!) when the time has come.

Could you also explain which interface you use to send data to the ESP32, Serial or mod ? I suggest also to rewrite that code:

  • Collect the data from the sensors and fill some C strings
  • Send to the ESP32 from one place in the sketch only, not spread all over the code. That eases to define a clear length and clear "start" and "end" of message ...

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