Need a little Help with a function call to only run once in an Arduino Program

Hi Sir!

I have been working on a simple water level monitoring system which i have integrated with a sim900 gsm shield.
The setup uses Arduino Uno r3.

Everything works just fine, The program is recursive, it constantly gets input and provide output, the programming is done using simple nested if-else.

Problem: Every time the if condition is true it will call the functions, three functions for now, and continues to execute since it is in the loop function. The functions gets string input and sends text messages to the mobile number. The only problem is that when the condition becomes true it continuously starts sending messages until other conditions are met and then it starts sending messages according to other conditions.

What I want: It only calls the function which sends text messages only once in the program startup cycle but the program should run continuously.

I searched run once functions but my programming language is very limited, so i ask you Sir, to help me achieve what i want from it.

Thanking you in advance.

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
SoftwareSerial SIM900(0, 1);

int sump=A0;
int qut=A1;
int hlf=A2;
int thf=A3;
int ful=A4;
int motor=8;
int buz=7;
int s;
int q;
int h;
int t;
int f;
int i;     //motor status flag
int v=100; //comparison variable(needs some adjustment)
int b=0;   //buzzer flag
int m=0;   //motor flag
int c=0;   //sump flag
String outHello = " Hello Message Hello! Welcome to Water Monitoring System";
String outlow="Sump is Low";
String fourquarters="Water Level is Fourth Quarter";
String mobnumber = "+XXXXXXXXXXX"; 

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
smshello(); // sends hello message in first run, no condtions needed for it
pinMode(qut,INPUT);
pinMode(hlf,INPUT);
pinMode(qut,INPUT);
pinMode(ful,INPUT);
pinMode(sump,INPUT);
pinMode(motor,OUTPUT);
pinMode(buz,OUTPUT);
lcd.begin(16, 2);
digitalWrite(buz,LOW);

}


void loop()
{

i=digitalRead(motor);
s=analogRead(sump);
q=analogRead(qut);
h=analogRead(hlf);
t=analogRead(thf);
f=analogRead(ful);
lcd.clear();


if(f>v && t>v && h>v && q>v )
{
lcd.setCursor(0,0);
lcd.print(char(219));
lcd.print(char(219));
lcd.print(char(219));
lcd.print(char(219));
lcd.setCursor(5,0);
lcd.print("FULL");
m=0;
b=0;
}
else
{
if(f<v && t>v && h>v && q>v)
{
lcd.setCursor(0,0);
lcd.print(char(219));
lcd.print(char(219));
lcd.print(char(219));
lcd.print("_");
lcd.setCursor(5,0);
lcd.print("3/4th");
b=0;
}
else
{
if(f<v && t<v && h>v && q>v)
{
lcd.setCursor(0,0);
lcd.print(char(219));
lcd.print(char(219));
lcd.print("_");
lcd.print("_");
lcd.setCursor(5,0);
lcd.print("HALF");
m=1;
b=0;
}
else
if(f<v && t<v && h<v && q>v)
{
lcd.setCursor(0,0);
lcd.print(char(219));
lcd.print("_");
lcd.print("_");
lcd.print("_");
lcd.setCursor(5,0);
lcd.print("1/4th");
b=0;
sms4thquarter();// call messaging function to send message, but we want that functions should be called once as per conditions in every start up.
}
else
{
if(f<v && t<v && h<v && q<v)
{
lcd.setCursor(0,0);
lcd.print("_");
lcd.print("_");
lcd.print("_");
lcd.print("_");
lcd.setCursor(5,0);
lcd.print("LOW");
b=0;
}
else

{
digitalWrite(motor,LOW);
lcd.setCursor(0,0);
lcd.print("ERROR!");
b=1;
}
}}}
if(i==HIGH)
{
lcd.setCursor(0,1);
lcd.print("Motor ON");
}
else
{
lcd.setCursor(0,1);
lcd.print("Motor OFF");
}



if(s>v && m==1)
{
digitalWrite(motor,HIGH);
}
if(s<v)
{
digitalWrite(motor,LOW);
lcd.setCursor(11,0);
lcd.print("Low");
lcd.setCursor(11,1);
lcd.print("Sump");
c=1;
smssumplow();
}
if(s>v)
{
c=0;
}

if(m==0)
{
digitalWrite(motor,LOW);
}
}
void smshello()
{
 SIM900.begin(19200);
  delay(20000); // give time to log on to network.
  SIM900.print("AT+CMGF=1\r");
  delay(1000);
  SIM900.println("AT + CMGS = \"" + mobnumber +"\"");
  delay(1000);
  SIM900.print(outHello);
  delay(1000);
  SIM900.write((char)26); //ctrl+z
  delay(1000);
}
void smssumplow()
{
 SIM900.begin(19200);
  delay(1000); // give time to log on to network.
  SIM900.print("AT+CMGF=1\r");
  delay(1000);
  SIM900.println("AT + CMGS = \"" + mobnumber +"\"");
  delay(1000);
  SIM900.print(outlow);
  delay(1000);
  SIM900.write((char)26); //ctrl+z
  delay(1000);
}
void sms4thquarter()
{
 SIM900.begin(19200);
  delay(1000); // give time to log on to network.
  SIM900.print("AT+CMGF=1\r");
  delay(1000);
  SIM900.println("AT + CMGS = \"" + mobnumber +"\"");
  delay(1000);
  SIM900.print(fourquarters);
  delay(1000);
  SIM900.write((char)26); //ctrl+z
  delay(1000);
}

What I want: It only calls the function which sends text messages only once in the program startup cycle but the program should run continuously.

If you really only want to call the function once ever then call it in setup() or Only call the function if a flag variable is set to false. Start with it set to false then in the function set it to true.

As I mentioned I have a very limited knowledge about it can you please tell what exactly needs to be added or changed, the flag variable? very new to arduino and C

Calling it in setup function will run it once but the program needs to run continuously and this will stop the execution.

Thanks

Apply this example to your program

boolean alreadyRun = false;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  if (alreadyRun == false)
  {
    aFunction();
  }
  Serial.println("Still running loop()");
  delay(1000);
}

void aFunction()
{
  Serial.println("In a function");
  alreadyRun = true;
}

the program needs to run continuously and this will stop the execution.

I don't understand what you mean by this.

"the program needs to run continuously and this will stop the execution"

I mean from this sentence, that The whole program should not stop and it should execute, when for the first time the condition is true, it shall call the function only once, since it is in the loop function and it is needed to be in the loop function to run simultaneously, I was looking for a way to track the function call and limit its call to only once, until the hardware is reset, I hope you understand now.

Thanks for your help.

I was looking for a way to track the function call and limit its call to only once

The example I posted does that.

Hi, I know this is an old post I have come across it while looking for a better way to to do the run once problem, the way I do this is by turning a int on and off

int running = 0

void loop{

if (running = 0 ) {

code to run

running +;+

}

else if (running = 1) { next bit of code in the loop.

}

}

then once the conditions have all be met you can return the int running back to 0 so that next time the condition is met again it will send the message.

you can also have this stored in the EEPROM so that if power fails and system reboots you will not get repeat messages.

this may be the wrong way to do this or the long way, but it works for me...

it works for me…

I am willing to bet that it doesn’t

if (running = 0 )

That will not do what you want, unless you want to set running to zero, that is.

running +;+

Interesting