Problem in sending SMS in void loop

Hello Everyone!

I am John, and im a newbie in Arduino programming. Im working on this project wherein i have a webserver that can control relays for the temperature sensor and Dc voltage sensor. The project is automated too wherein the relays will turn on and off depending on the set conditions in the program. However im having an issue in figuring out how to set the SIM800L shield and arduino to send only one text message when the conditions have meant. For example, If (temp < = 33 ) { send_msg(); }. The problem is, this line is in the void loop and as the function itself, it will loop everything inside this function resulting to send text message repeatedly. I tried implementing flags on my codes, it worked in a way that it will only send one text message once the codes has been initiated and upload but after that and the program is running, it will not work. In example, when i upload the code and arduino reads this line = If (temp < = 33 ) { send_msg(); }for the first time i upload the codes, it will trigger to LOW the relay and it will send only one text message once the temperature is below or equal to 33, when arduino is running and detect that the temp gets higher than 33, it will trigger the relay to HIGH but it will not send a text message. There are no problems with the triggers in relays. the problem is the sending of text message. Btw, I have set different text message content. Please see below codes. Please accept my sincere apology as i am new in arduino. Your help is greatly appreciated.


//For ethernet
#include <SPI.h>
#include <Ethernet.h>
//For relay
#include <Wire.h>
#include <Relay.h>
//For Temp
#include <OneWire.h>
#include <DallasTemperature.h>
//For GSM
#include <SoftwareSerial.h>

//For GMSM---------------------------------------------------------------------------------
SoftwareSerial mySerial(2, 3);
char Rx_data[150];
unsigned char Rx_index = 0; 
int i = 0;
char msg[160];
int sig;

#define DEBUG true

//-----------------------------------------------------------------------------------------
int passFlag = 0;
int passFlag1 = 0;
int passFlag2 = 0;
int passFlag3 = 0;
//Millis timeout---------------------------------------------------------------------------

const unsigned long starttime_web = 1000;
const unsigned long starttime_temp = 1000;
const unsigned long starttime_batt = 1000;
const unsigned long starttime_gsm = 1000;
unsigned long interval_web = 0;
unsigned long interval_temp = 0;
unsigned long interval_batt = 0;
unsigned long interval_gsm = 0;
//-----------------------------------------------------------------------------------------

//Batt pin---------------------------------------------------------------------------------
#define SIGNAL_PIN A0 
//-----------------------------------------------------------------------------------------


//Temp Pin---------------------------------------------------------------------------------
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temp;
//-----------------------------------------------------------------------------------------


//Batt computation-------------------------------------------------------------------------
float adc_voltage = 0.0;
float in_voltage = 0.0;
float R1 = 30000.0;
float R2 = 7500.0;
float ref_voltage = 5.0;
int adc_value = 0;
//-----------------------------------------------------------------------------------------


//Ethernet---------------------------------------------------------------------------------
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 12);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);
//-----------------------------------------------------------------------------------------

// Relay state and pin---------------------------------------------------------------------
String relay1State1 = "ON";
String relay2State2 = "ON";
const int  TempCon= 6;
const int ChgRlyCon = 7;

//-----------------------------------------------------------------------------------------


// Client variables------------------------------------------------------------------------ 
char linebuf[80];
int charcount=0;
//-----------------------------------------------------------------------------------------

void dashboardPage(EthernetClient &client) {
  client.println("<!DOCTYPE HTML><html>");
  client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body>");
  client.println("<center><a href=\"/\">Refresh</a>");
  client.println("<h3>SERVER TEMPERATURE</a></h3>");
  client.println("<br>");
  client.println(temp);
  client.println("</br>");
  // Generates buttons to control the relay      
    client.println("<a href=\"/ACON\"><button>ON</button></a>&nbsp;&nbsp");
    client.println("<a href=\"/ACOFF\"><button>OFF</button></a>");
  client.println("<h3>SERVER BATTERY LEVEL</h3>");
    client.println("<br>");
    client.println(in_voltage);
    client.println("</br>");
  // Generates buttons to control the relay       
    client.println("<a href=\"/DCON\"><button>ON</button></a>&nbsp;&nbsp");
    client.println("<a href=\"/DCOFF\"><button>OFF</button></a></center>"); 
  
  client.println("</body></html>"); 
}  

void setup()
{
  // For GSM
  Serial.begin(9600);
  mySerial.begin(19200);
  
  
  //---------------------------------------------------------------------------------------
  
  //For ethernet
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  //---------------------------------------------------------------------------------------
  
  //For relay pins
  pinMode(ChgRlyCon, OUTPUT);
  digitalWrite(ChgRlyCon, HIGH);
  pinMode(TempCon, OUTPUT);
  digitalWrite(TempCon, HIGH);
  //---------------------------------------------------------------------------------------
  
    
          
  

//--------------------------------------------------------------------------------------------  

 
}


//-------------------------------------------------------------------------------------------
 
void loop() {
  
  unsigned long currentTime = millis();

  if(currentTime - interval_temp >= starttime_temp){
    loop_temp();
    interval_temp = currentTime;
  }
  
  if(currentTime - interval_batt >= starttime_batt){
    loop_batt();
    interval_batt = currentTime;
  }
    
  if(currentTime - interval_gsm >= starttime_gsm){
    loop_gsm();
    interval_gsm = currentTime;
  }
  
  if(currentTime - interval_web >= starttime_web){
    loop_web();
    interval_web = currentTime;
  }
  
}

  
//----TEMP SENSOR LOOP------------------------------------------------------------------------ 
void loop_temp(){   
   
    sensors.requestTemperatures(); // Send the command to get temperatures
    temp = sensors.getTempCByIndex(0);
    sensors.requestTemperatures(); // Send the command to get temperatures
  temp = sensors.getTempCByIndex(0);

  if( temp >= 35){
    digitalWrite(TempCon, HIGH);
    if(passFlag == 0){
    init_GSM();
    send_msg("***********", "AIRCON HAS BEEN TURNED ON");
    passFlag++;
    }
    }
  if (temp <= 34){
    digitalWrite(TempCon, LOW);
    if(passFlag1 == 0){
    init_GSM();
    send_msg("***********", "AIRCON HAS BEEN TURNED OFF");
     passFlag1++;
    } 
    
    }
    
    

}
//---------------------------------------------------------------------------------------------- 


//----GSM SERIAL INITIATION---------------------------------------------------------------------  
void loop_gsm(){   
    if (mySerial.available())
    Serial.write(mySerial.read());
    if (Serial.available())
    mySerial.write(Serial.read());
// listen for incoming clients
}
//----------------------------------------------------------------------------------------------

//---WEB SERVER---------------------------------------------------------------------------------
void loop_web(){
 
  EthernetClient client = server.available();
  if (client) {
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
       char c = client.read();
       //read char by char HTTP request
        linebuf[charcount]=c;
        if (charcount<sizeof(linebuf)-1) charcount++;
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          dashboardPage(client);
          break;
        }
        if (c == '\n') {
          if (strstr(linebuf,"GET /ACON") > 0){
               digitalWrite(TempCon, HIGH);
               init_GSM();
               send_msg("***********", "AC HAS BEEN TURNED ON BY ADMIN");
               
          }
          else if (strstr(linebuf,"GET /ACOFF") > 0){
            digitalWrite(TempCon, LOW);
            init_GSM();
            send_msg("***********", "AC HAS BEEN TURNED OFF BY ADMIN");
            
          }
          
          if (strstr(linebuf,"GET /DCON") > 0){
               digitalWrite(ChgRlyCon, HIGH);
               init_GSM();
               send_msg("***********", "CHARGING THE BATTERY HAS BEEN CONNECTED BY ADMIN");
               
          }
          
          if (strstr(linebuf,"GET /DCOFF") > 0){
               digitalWrite(ChgRlyCon, LOW);
               init_GSM();
               send_msg("***********", "CHARGING THE BATTERY HAS BEEN DISCONNECTED BY ADMIN");
         
          }
         
          currentLineIsBlank = true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;          
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
      }
    }
  }
    // give the web browser time to receive the data
    delay(1);
  }
 } 


//----VOLTAGE SENSOR LOOP----------------------------------------------------------------------

void loop_batt(){

  adc_value = analogRead(SIGNAL_PIN);
 
  // Determine voltage at ADC input
  adc_voltage  = (adc_value * ref_voltage) / 1024.0;
 
  // Calculate voltage at divider input
  in_voltage = adc_voltage / (R2 / (R1 + R2)) ;
  
    
    //--------------------------- bms 0, batt lt 13.4v--------------
  if(in_voltage >= 15){
    digitalWrite(ChgRlyCon, LOW);
    if(passFlag2 == 0){
    init_GSM();
    send_msg("***********", "CHARGING THE BATTERY HAS BEEN DISCONNECTED");
    passFlag2++;
   }
  }
//--------------------------- bms 0, batt is charged at 13.4V -------
    if(in_voltage <= 6){
    digitalWrite(ChgRlyCon, HIGH);
    if(passFlag3 == 0){
    init_GSM();
    send_msg("***********", "CHARGING THE BATTERY HAS BEEN CONNECTED");
    passFlag3++;
    }
    }
  
}

//---SEND GSM STRING----

void send_msg(char *number, char *msg)
{
  char at_cmgs_cmd[30] = {'\0'};
  char msg1[160] = {'\0'};
  char ctl_z = 0x1A;

  sprintf(msg1, "%s%c", msg, ctl_z);
  sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);
  
  sendGSM(at_cmgs_cmd);
  delay(100);
  delay(100);
  delay(100);
  sendGSM(msg1);
  delay(100);
}

void sendGSM(char *string){
  mySerial.write(string);
  delay(90);
}

void clearString(char *strArray) {
  int j;
  for (j = 100; j > 0; j--)
    strArray[j] = 0x00;
}

void send_cmd(char *at_cmd, char clr){
  char *stat = '\0';
  while(!stat){
    sendGSM(at_cmd);
    delay(200);
    readSerialString(Rx_data);
    Serial.write(Rx_data);
    
    stat = strstr(Rx_data, "OK");
    Serial.println("Success");
    delay(50000);
  }
  if (clr){
    clearString(Rx_data);
    delay(200);
    stat = '\0';
  }
}

void init_GSM(){
  
 
  sendData("AT\r\n",1000,DEBUG); // AT

  sendData("AT+CMGF=1\r\n",1000,DEBUG); //AT+CMGF=1
  sendData("AT+CMGD=1\r\n",1000,DEBUG); //AT+CMGD=1

  delay(1000);
  delay(1000);
  delay(1000);
}

void readSerialString (char *strArray) {
  
  if(!mySerial.available()) {
    return;
  }
  
  while(mySerial.available()) {
    strArray[i] = mySerial.read();
    i++;
  }
}

String sendData(String command, const int timeout, boolean debug)
{
    String response = "";
    
    mySerial.print(command); 
    
    long int time = millis();
    
    while( (time+timeout) > millis())
    {
      while(mySerial.available())
      {
        
   
        char c = mySerial.read();
        response+=c;
      }  
    }
    
    if(debug)
    {
      Serial.print(response);
    }
    
    return response;
}


Thank you!

Welcome to the forum

You need to detect when the condition becomes true rather than when it is true

See the StateChangeDetection example in the IDE

1 Like

that should look like this

if( temp >= 35){
    digitalWrite(TempCon, HIGH);
    if(passFlag == 0){
    init_GSM();
    send_msg("***********", "AIRCON HAS BEEN TURNED ON");
    passFlag = 1;
    passFlag2 = 0;
    }
    }
  if (temp <= 34){
    digitalWrite(TempCon, LOW);
    if(passFlag1 == 0){
    init_GSM();
    send_msg("***********", "AIRCON HAS BEEN TURNED OFF");
     passFlag1 = 1;
     passFlag = 0;
    } 
    
    }

you never reset the flags back to 0 when the relay pin changes the status

I have done it for you for the Air Conditioning block

1 Like

Thank you so much for your prompt response. Ill try this. Thanks again.

Thank you for the advice. I did checked the StateChangeDetection example in the IDE and to be honest, i was confused. Thanks again. Ill study again. Sorry.

It worked! Thank you so much @KASSIMSAMJI!

Hello again everyone! Can i add something here that is not related to the topic i opened earlier? its about putting basic authentication on my codes sent earlier. I tried putting this example code and combined with mine but i cant make it work. The codes uploaded successfully but the webpage is not loading. Here is the example codes i used:

/*
* Web Server
*
* A simple web server with basic HTTP authentication
*
* Circuit:
* Ethernet shield attached to Arduino board
* Analog inputs attached to pins A0 through A5 (optional)
*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2, 111);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
// Open serial communications and wait for port to open:
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void SendOKpage(EthernetClient &client)
{
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");       
          }
          client.println("</html>");
}


void SendAuthentificationpage(EthernetClient &client)
{
          client.println("HTTP/1.1 401 Authorization Required");
          client.println("WWW-Authenticate: Basic realm=\"Secure Area\"");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<HTML>  <HEAD>   <TITLE>Error</TITLE>");
          client.println(" </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>");
}

char linebuf[80];
int charcount=0;
boolean authentificated=false;

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;
    authentificated=false;
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        linebuf[charcount]=c;
        if (charcount<sizeof(linebuf)-1) charcount++;
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          if (authentificated)
            SendOKpage(client);
          else
            SendAuthentificationpage(client);  
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
          if (strstr(linebuf,"Authorization: Basic")>0 && strstr(linebuf,"cGhwOm5laW4=")>0)
            authentificated=true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}




I guess my problem is about the client.println in my codes conflicting to this example.
Need your expert advice on how i can construct a basic authentication to my codes.

Thank you

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