Replace delay for SMS code

void SendMessage()
{
mySerial.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
delay(1000); // Delay of 1000 milli seconds or 1 second
mySerial.println("AT+CMGS=\"+xxxxxxxxxxx\"\r"); // Replace x with mobile number
delay(1000);
mySerial.println(" ");// The SMS text you want to send
delay(200);
mySerial.println((char)26);// ASCII code of CTRL+Z
delay(1000);
}

This is the partial code that I used to send SMS. It works great and all. Except that the delay() caused my sensor reading not really responsive (it still works) because of the delay(). I tried to change all delay(1000) to delay (130) and SMS was successfully sent to my phone but still my sensor reading was not really responsive. I don't know is this even a legit solution I just tried it on a whim. Is there any alternative that I can use to replace delay(). I read that delay() causes "blocking" as the program runs on at a time in sequence. I'm still a total beginner in programming.

Use the built in timing function millis() to schedule events, without ever using delay().

The basic idea is covered in this excellent tutorial: Blink without delay() explained line-by-line

void SendMessage6() {
  mySerial.println("AT+CMGF=1"); 
if((unsigned long)(millis() - previousMillissms6a) >= messageperiodsms6a) {
  previousMillissms6a = millis();
  mySerial.println("AT+CMGS=\"+xxxxxxxxxx\"\r");
  }
if((unsigned long)(millis() - previousMillissms6b) >= messageperiodsms6b) {
  previousMillissms6b = millis();
  mySerial.println("Message here");
  }
if((unsigned long)(millis() - previousMillissms6c) >= messageperiodsms6c) { 
  previousMillissms6c = millis();
  mySerial.println((char)26);
  }
if((unsigned long)(millis() - previousMillissms6d) >= messageperiodsms6d) {
  previousMillissms6d = millis();
  }
}

I tried to use millis(), no error compiling. When I sent the message it stated everything is fine but I received no message from my phone.

The snippet won't work for several reasons, The way you have set it up, the messages are all independently sent, and will be out of order, depending on when SendMessage6() is called.

Blink without delay() works only in a continuously looping situation. Best to do everything in the loop() function, rather than have a separate function to send a message.

Always post ALL your code, so people can see how variables are defined, etc.

#include <Filters.h>                      //This library does a massive work check it's .cpp file
#include <Wire.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <stdlib.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
SoftwareSerial mySerial(9, 10);
char msg;
char lcdc1;
char lcdc2;
char lcdv1[15];
char lcdv2[15];

#define ACS_Pin1 A0                        //Sensor data pin on A0 analog input
#define ACS_Pin2 A1                        //Sensor data pin on A0 analog input

float ACS_ValueC1;                              //Here we keep the raw data valuess
float ACS_ValueC2;                              //Here we keep the raw data valuess
float testFrequencyC1 = 50;                    // test signal frequency (Hz)
float testFrequencyC2 = 50;                    // test signal frequency (Hz)
float testFrequencyV1 = 50;                    // test signal frequency (Hz)
float testFrequencyV2 = 50;                    // test signal frequency (Hz)
float windowLengthC1 = 40.0/testFrequencyC1;     // how long to average the signal, for statistist
float windowLengthC2 = 40.0/testFrequencyC1;     // how long to average the signal, for statistist
float windowLengthV1 = 40.0/testFrequencyV1;     // how long to average the signal, for statistist
float windowLengthV2 = 40.0/testFrequencyV1;     // how long to average the signal, for statistist

int SensorV1 = 2; //Sensor analog input, here it's A2
int SensorV2 = 3; //Sensor analog input, here it's A3

float interceptC1 = 0; // to be adjusted based on calibration testing
float slopeC1 = 0.0752; // to be adjusted based on calibration testing                 
float Amps_TRMSC1; // estimated actual current in amps

float interceptC2 = 0; // to be adjusted based on calibration testing
float slopeC2 = 0.0752; // to be adjusted based on calibration testing                 
float Amps_TRMSC2; // estimated actual current in amps

float interceptV1 = -0.04; // to be adjusted based on calibration testing
float slopeV1 = 0.0405; // to be adjusted based on calibration testing
float current_VoltsV1; // Voltage

float interceptV2 = -0.04; // to be adjusted based on calibration testing
float slopeV2 = 0.0405; // to be adjusted based on calibration testing
float current_VoltsV2; // Voltage

unsigned long printPeriodC1 = 1000; // in milliseconds 
unsigned long previousMillisC1 = 0;

unsigned long printPeriodC2 = 1000; // in milliseconds 
unsigned long previousMillisC2 = 0;

unsigned long printPeriodV1 = 1000; //Refresh rate
unsigned long previousMillisV1 = 0;

unsigned long printPeriodV2 = 1000; //Refresh rate
unsigned long previousMillisV2 = 0;

void setup() {
  Serial.begin( 9600 );    // Start the serial port
  mySerial.begin(9600); 
  lcd.begin(16,2);//Defining 16 columns and 2 rows of lcd display
  lcd.backlight();//To Power ON the back light
  pinMode(ACS_Pin1,INPUT);  //Define the pin mode
  pinMode(ACS_Pin2,INPUT);  //Define the pin mode
}

void loop()   {
  RunningStatistics inputStatsC1;                 // create statistics to look at the raw test signal
  inputStatsC1.setWindowSecs( windowLengthC1 );     //Set the window length 

  RunningStatistics inputStatsC2;                 // create statistics to look at the raw test signal
  inputStatsC2.setWindowSecs( windowLengthC2 );     //Set the window length 

  RunningStatistics inputStatsV1;                //Easy life lines, actual calculation of the RMS requires a load of coding
  inputStatsV1.setWindowSecs( windowLengthV1 );

  RunningStatistics inputStatsV2;                //Easy life lines, actual calculation of the RMS requires a load of coding
  inputStatsV2.setWindowSecs( windowLengthV2 );

  while( true ) {   
    ACS_ValueC1 = analogRead(ACS_Pin1);  // read the analog in value:
    inputStatsC1.input(ACS_ValueC1);  // log to Stats function
    
    SensorV1 = analogRead(A2);  // read the analog in value:
    inputStatsV1.input(SensorV1);  // log to Stats function

    ACS_ValueC2 = analogRead(ACS_Pin2);  // read the analog in value:
    inputStatsC2.input(ACS_ValueC2);  // log to Stats function

    SensorV2 = analogRead(A3);  // read the analog in value:
    inputStatsV2.input(SensorV2);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillisC1) >= printPeriodC1 || ((unsigned long)(millis() - previousMillisV1) >= printPeriodV1) || ((unsigned long)(millis() - previousMillisC2) >= printPeriodC2) || ((unsigned long)(millis() - previousMillisV2) >= printPeriodV2)){ //every second we do the calculation
      previousMillisC1 = millis();   // update time
      previousMillisC2 = millis();   // update time
      previousMillisV1 = millis();   // update time every second
      previousMillisV2 = millis();   // update time every second
      Amps_TRMSC1 = interceptC1 + slopeC1 * inputStatsC1.sigma();
      Amps_TRMSC2 = interceptC2 + slopeC2 * inputStatsC2.sigma();
      current_VoltsV1 = interceptV1 + slopeV1 * inputStatsV1.sigma(); //Calibartions for offset and amplitude
      current_VoltsV1 = current_VoltsV1*(40.3231);                //Further calibrations for the
      current_VoltsV2 = interceptV2 + slopeV2 * inputStatsV2.sigma(); //Calibartions for offset and amplitude
      current_VoltsV2 = current_VoltsV2*(40.3231);                //Further calibrations for the amplitude 
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print(Amps_TRMSC1);
      lcd.setCursor(5,0);
      lcd.print("A");
      lcd.setCursor(8,0);
      lcd.print(current_VoltsV1);
      lcd.setCursor(15,0);
      lcd.print("V");
      lcd.setCursor(0,1);
      lcd.print(Amps_TRMSC2);
      lcd.setCursor(5,1); 
      lcd.print("A");
      lcd.setCursor(8,1);
      lcd.print(current_VoltsV2);
      lcd.setCursor(15,1);
      lcd.print("V");
      Serial.print( "Amps1: " ); 
      Serial.println( Amps_TRMSC1);
      Serial.print( "Voltage1: " );
      Serial.println( current_VoltsV1); //Calculation and Value display is done the rest is if you're using an OLED display;
      Serial.println( " " );
      Serial.print( "Amps2: " ); 
      Serial.println( Amps_TRMSC2);
      Serial.print( "Voltage2: " );
      Serial.println( current_VoltsV2); //Calculation and Value display is done the rest is if you're using an OLED display
      Serial.println( " " );
    }
      {
      if ((Amps_TRMSC1 < 0.25) && (current_VoltsV1 > 240.00))
        {
        SendMessage1();
        }
      }

      {
      if ((Amps_TRMSC1 > 0.8) && (current_VoltsV1 > 240.00))
        {
        SendMessage2();
        }
      }

      {
      if (current_VoltsV1 < 150.00)
        {
        SendMessage3();
        }
      }

      {
      if ((Amps_TRMSC2 < 0.25) && (current_VoltsV2 > 240.00))
        {
        SendMessage4();
        }
      }

      {
      if ((Amps_TRMSC2 > 0.8) && (current_VoltsV2 > 240.00))
        {
        SendMessage5();
        }
      }

      {
      if (current_VoltsV2 < 150.00)
        {
        SendMessage6();
        }
      }
  }
}

void SendMessage1()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 1: Current below threshold.\nVoltage = "+String(current_VoltsV1)+" V"+" \nCurrent ="+String(Amps_TRMSC1)+" A");// The SMS text you want to send
  delay(100);
   mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(130);
}

void SendMessage2()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 1: Current above threshold.\nVoltage = "+String(current_VoltsV1)+" V"+" \nCurrent ="+String(Amps_TRMSC1)+" A");// The SMS text you want to send
  delay(100);
   mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void SendMessage3()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 1: Voltage below threshold.\nVoltage = "+String(current_VoltsV1)+" V"+" \nCurrent ="+String(Amps_TRMSC1)+" A");// The SMS text you want to send
  delay(100);
   mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(130);
}

void SendMessage4()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 2: Current below threshold.\nVoltage = "+String(current_VoltsV2)+" V"+" \nCurrent ="+String(Amps_TRMSC2)+" A");// The SMS text you want to send
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(130);
}

void SendMessage5()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 2: Current above threshold.\nVoltage = "+String(current_VoltsV2)+" V"+" \nCurrent ="+String(Amps_TRMSC2)+" A");// The SMS text you want to send
  delay(100);
   mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(130);
}

void SendMessage6()
{
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(130);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+60179023457\"\r"); // Replace x with mobile number
  delay(130);
  mySerial.println("Zone 2: Voltage below threshold.\nVoltage = "+String(current_VoltsV2)+" V"+" \nCurrent ="+String(Amps_TRMSC2)+" A");// The SMS text you want to send
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(130);
}

I didn't understand your first paragraph reply above.

This is the full code of my project. A little description:
Disclaimer: All the codes above I found on the internet. I just change all values and add variables according to my needs.

  1. A system to measure the current and voltage depending on the load (in this case I just use a simple AC bulb)
  2. Consists of 2 currents (ACS712) and 2 voltage (ZMPT101B) sensors.
  3. Consists of 2 bulbs, each bulb connected with 1 current and 1 voltage sensor.
  4. LCD to display the value of the current and voltage (updated every second).
  5. Message will be sent if voltage below set level, current above/below-set level.

Before I add the send message function, the sensor reading was very responsive on the LCD depending if I manipulate the load or the supply. When I incorporate the send message function, the sensor reading was not responsive, I suspected due to the delay(). The send message function working fine though.

Replace the mySerial.println() statements with Serial.println() to see the problem.

The basic problem is that the computer cannot do anything else when it is instructed to delay(). For example, it cannot read the sensor when executing delay(), which would be for over three seconds in the code first posted.

Keep in mind that the speed of data transmission is limited by the speed of the SMS module.

Yes I get that delay() block all the execution until the delay itself is done. Are there any other alternatives so that the SMS function does not cause the sensor reading to not be responsive.

My target is to get the sensor reading to be responsively displayed on LCD while also can send SMS, it does not have to be an instantaneous message as long as it can be received to the phone.

Right now my situation sensor reading display on LCD is not being responsive unless if I drop the SMS function altogether due to the delay() inside the SMS function itself.

No. These modifications require some programming skills.

If you don't want to learn how to make them yourself (by starting with simpler projects and working your way up), you can post on the Jobs and Paid Consultancies forum section.

All good buddy! Thanks for the explanation.

LCD displaying is faster than SMS sending, so display the data from the sensor as soon as you receive them, then take care of the SMS when the display is already updated.