SIM800L not detecting received SMS and problems with SoftwareSerial library

Hello! This is my first time posting on here, and i need help. I hope that i explained everything well. Sorry that the code is messy, i made it by combining many other codes.

I have built an digital scale using esp32, hx711, four 50kg load cells, ds3231 RTC, 1602 I2C LCD, pushbutton to "wake up" the scale and the sim800l module that is powered through the lm2596 buck converter.
The idea was to build a scale that would work on a power bank, that would measure the weight of a bee hive remotely and sent it with SMS at the times of the day written in the code. I made that and it worked perfectly.

The issue came when i wanted to add a feature that would detect when the sim800l received a message, and then would send an message back containing the weight. Previously the message was sent when the function " void sendSMS() " was called ( which was when the code detected that the set time was reached ) , so that meant that now i only needed a way to detect when the sim800l received a message, and then call the function sendSMS(). With the help of ChatGPT i used the following IF function:

if (mySerial.available()) {
    String response = mySerial.readString();
    Serial.println(response);

    if (response.indexOf("+CMT") != -1) {
      Serial.println("New SMS received!");
      sendSMS();
  }

This code would detect when the sim800l got data that contained " +CMT " which indicates a new SMS. The problem is that in all my testing over the past month the code never detected this, or anything else i replaced " +CMT " with. I decided to just use the " if (mySerial.available()) " part to detect when the SMS was received, as you can see in the final code, which resulted in it detecting the SMS only sometimes and it being highly unreliable. That is where i am stuck right now.

There is another issue i have that i dont know if its related to my main issue. (It didnt cause any problems before i tried adding the detection of received SMS). SoftwareSerial library is used to start serial communication with the sim800l ( SoftwareSerial mySerial(16, 17); ) . Then the " void updateSerial() " function is used to write anything i, or the code, sends in the serial monitor to the sim800l, and write out in the serial monitor anything that was sent by the sim800l. The problem is that anything sent by the sim800l was just random characters in the serial monitor ( such as "�1 Sc�� o�"). It was still sent in the same time that the real words were suppost to show up, but its just these random characters. The part that reads what i, or the code, types in the serial monitor and sends it to the sim800l still works, but only those random characters are shown in the serial monitor. To further explain this, heres an example. In the setup, the code sends a bunch of "AT" commands that set up the sim800l. For example " mySerial.println("AT+CMGF=1"); ". That means that in the serial it should print out "AT+CMGF=1" (what i sent) and " OK " (the response from sim800l confirming the execution of the command. Instead of that all that is printed is the random characters, but the command is still executed. By the way, the weight is printed out in the serial monitor with every loop, and that prints out completely fine, so i think the issue is with the SoftwareSerial part of the code.

I dont think the problem is in the wiring, since the module still sends the sms without any problems. For majority of the testing sim800l was on 4V, but recently i changed it to 4,2V to see if that will help my problem but it didnt change anything.

Heres the link of the documentation of all the AT commands of the sim800l module.

link

I would suggest looking at pages 124 and 350 which describe the AT+CNMI command that configures how new SMS messages are received.

I am a highschool student and dont have a lot of money but i want to offer at least a few euros to anyone who solves my problem :smiley:

Heres the full code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <driver/rtc_io.h>
#include "HX711.h"
#include <RTClib.h>
#include <SoftwareSerial.h>


const int buttonPin = 15;     // Pushbutton connected to pin 15
bool displayOn = false;       // Tracks if the display is currently on
unsigned long onStartTime = 0;  // Time when the display was turned on

SoftwareSerial mySerial(16, 17); //SIM800L Tx & Rx

// Initialize LCD (I2C address 0x27, 16x2 display)
LiquidCrystal_I2C lcd(0x27, 16, 2);

// HX711 circuit wiring
#define LOADCELL_DOUT_PIN  4  // Data pin
#define LOADCELL_SCK_PIN   5  // Clock pin
HX711 scale;

// Calibration factor (adjust based on calibration)
float calibration_factor = 22.85; // Adjust this value

RTC_DS3231 rtc;

bool triggeredThisMinute = false;

void setup() {
    Serial.begin(115200);
    mySerial.begin(9600);
    delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();

  mySerial.println("AT+CNMI=1,2,0,0,0");
  updateSerial();

  mySerial.println("AT+CSCLK=2"); // Sleep mode
  updateSerial();

    Wire.begin();
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC. Please check your wiring!");
    while (1);  // Halt if RTC is not found
  }

  // Optionally, if the RTC lost power, set it to the current compile time.
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

    
    lcd.init();
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Iniciacija...");

    pinMode(buttonPin, INPUT_PULLDOWN);
    
    scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
    scale.set_scale(calibration_factor); // Apply calibration factor
    scale.tare(); // Reset scale to zero
    
    lcd.clear();
    lcd.setCursor(5, 0);
    lcd.print("-Vaga-");
    delay(1500);
    lcd.noBacklight();
    lcd.noDisplay();



    delay(1000);
}

void loop() {
  DateTime now = rtc.now();

  float weight = scale.get_units(); // Get weight in grams

  int buttonState = digitalRead(buttonPin);
  if (mySerial.available()) {
        mySerial.println("AT+CSCLK=0"); //Get out of sleep mode 
        String response = mySerial.readStringUntil('\n');
        Serial.println("SIM800L: " + response);
        Serial.println("ON");
        Serial.println(response.indexOf("+CMT"));
        delay(3000);
        sendSMS();

        if (response.indexOf("+CMT") != -1) {  
          Serial.println("New SMS received!");
        }
    }

  if ((now.hour() == 18 && now.minute() == 29)||(now.hour() == 8 && now.minute() == 44))  { //Vreme alarma
    if (!triggeredThisMinute) {
      Serial.println("Target time reached!");
    lcd.backlight();
    lcd.display();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Saljem sms ");
    delay(3500);
      sendSMS(); 
    lcd.noBacklight();
    lcd.noDisplay();
      triggeredThisMinute = true;
    }
  } else {
    // Reset flag once we're outside the target minute and turn off the output
    triggeredThisMinute = false;
  }

  // Run loop tasks every 500 milliseconds
  if (buttonState == HIGH && !displayOn) {
    lcd.backlight();
    lcd.display();     // Turn on the display
    lcd.clear();       // Clear any previous content
    lcd.print("Display ON");
    
    // Record the time when the display was turned on
    onStartTime = millis();
    displayOn = true;
  }

  // Check if 10 seconds have elapsed (non-blocking)
  if (displayOn && (millis() - onStartTime >= 20000)) {
    Serial.println(onStartTime);
    Serial.println("10 seconds elapsed. Preparing to enter light sleep mode...");
    lcd.noBacklight();
    lcd.noDisplay();
    displayOn = false;
    }

  
    
    Serial.print("Tezina: ");
    Serial.print(weight);
    Serial.println(" g");
    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tezina: ");
    lcd.setCursor(8, 0);
    lcd.print(weight/1000, 2);
    lcd.setCursor(14, 0);
    lcd.print("kg");

    updateSerial();

    delay(100); // Refresh rate
}
void sendSMS(){
  Serial.print("Saljem sms");
  
  float weight = scale.get_units();

  mySerial.println("AT");
  delay(500);
  mySerial.println("AT+CSCLK=0");
  updateSerial();

  mySerial.println("AT+CMGS=\"xxxxxxxxx\"");//Phone number
  updateSerial();
  mySerial.print("Tezina: ");
  mySerial.print(weight/1000, 2);
  mySerial.print(" kg");
  updateSerial();
  mySerial.write(26);
  delay(5000);
  mySerial.println("AT+CSCLK=2");
  updateSerial();
  }

void updateSerial()
{
  delay(100);
  while (Serial.available()) 
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available()) 
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}