SIM module continuously sending SMS messages after threshold reached

Hello,

I am using a Botletics™ SIM7000 LTE CAT-M1/NB-IoT + GPS Shield Kit in order to control a water auto sampler.

The current goal is to send an SMS message when a reed switch/float switch goes to an open state, indicating a full sample container, OR a flow sensor counts 300ml of liquid collected. I am using this flow sensor: Amazon.com

When the reed switch is actuated, it used to freeze the serial monitor and wouldn't send an SMS, but now it sends one SMS once it is open, and one after it is closed again, which is not ideal but I can work around it. The major problem is when the flow sensor counts the threshold amount of liquid. Once it counts over 300ml, it will continuously spam SMS messages, but I need it to only send one. I'd appreciate some tips to avoid this behavior. I have attached the code below

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;

const byte floatSwitchPin = 3;

char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

const int FLOATSWITCH = 2; // Use pin 2 to wake up the Uno/Mega

const char * phone_number = "+1800000006"; // Include country code, only numbers
const char * text_message = "FULL!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("test"));
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);

  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately


}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute

  totalMilliLitres += flowRate;
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (digitalRead(floatSwitchPin) == HIGH || totalMilliLitres > 300) {
    opened = false;

    while (!netStatus()) {
      Serial.println(F("Failed to connect to cell network, retrying..."));
      delay(2000); // Retry every 2s
    }
    Serial.println(F("Connected to cell network!"));

    // Send a text to your phone!
    if (!fona.sendSMS(phone_number, text_message)) {
      Serial.println(F("Failed to send text!"));
    }
    else {
      Serial.println(F("Sent text alert!"));
    }

    // Uncomment the section below if you are doing an HTTP request!
    /*
      // Disable data connection before attempting to enable
      if (!fona.enableGPRS(false)) {
      Serial.println(F("Failed to turn off"));
      }

      // Turn on data connection after connecting to network
      while (!fona.enableGPRS(true)) {
      Serial.println(F("Failed to enable GPRS, retrying..."));
      delay(2000); // Retry every 2s
      }
      Serial.println(F("Enabled GPRS!"));

      // Do an HTTP GET request
      // By posting to the web you can link it to things like IFTTT to get
      // email notifications, keep track of any extra data you might add
      // (temperature, GPS, door state, etc) and have fun with it!

      counter = 0; // This counts the number of failed attempts tries

      sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!

      while (counter < 3 && !fona.postData("GET", URL)) {
      Serial.println(F("Failed to post data, retrying..."));
      counter++; // Increment counter
      delay(1000);
      }
    */

    // Or do an HTTP POST request instead!
    /*
      sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
      body = "{burglar: true}"; // We're keeping it super simple for now!
      //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!

      while (counter < 3 && !fona.postData("POST", URL, body)) {
      Serial.println(F("Failed to complete HTTP POST..."));
      counter++;
      delay(1000);
      }
    */
  }
}

// Power on/off the module
void powerOn(bool state) {
  if (state) {
    Serial.println(F("Turning on SIM7000..."));
    digitalWrite(FONA_PWRKEY, LOW);
    delay(100); // Turn on module
    digitalWrite(FONA_PWRKEY, HIGH);
    delay(4500); // Give enough time for the module to boot up before communicating with it
  }
  else {
    Serial.println(F("Turning off SIM7000..."));
    fona.powerDown(); // Turn off module
  }
}

void moduleSetup() {
  fonaSS.begin(115200); // Default SIM7000 shield baud rate

  Serial.println(F("Configuring to 9600 baud"));
  fonaSS.println("AT+IPR=9600"); // Set baud rate
  delay(100); // Short pause to let the command run
  fonaSS.begin(9600);
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while (1); // Don't proceed if it couldn't find the device
  }

  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case SIM7000A:
      Serial.println(F("SIM7000A (American)")); break;
    case SIM7000C:
      Serial.println(F("SIM7000C (Chinese)")); break;
    case SIM7000E:
      Serial.println(F("SIM7000E (European)")); break;
    case SIM7000G:
      Serial.println(F("SIM7000G (Global)")); break;
    default:
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
}

bool netStatus() {
  int n = fona.getNetworkStatus();

  Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  if (n == 0) Serial.println(F("Not registered"));
  if (n == 1) Serial.println(F("Registered (home)"));
  if (n == 2) Serial.println(F("Not registered (searching)"));
  if (n == 3) Serial.println(F("Denied"));
  if (n == 4) Serial.println(F("Unknown"));
  if (n == 5) Serial.println(F("Registered roaming"));

  if (!(n == 1 || n == 5)) return false;
  else return true;

}

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}

Read a bit about state machines.

You basically need a variable that represents the state of your system.

The code monitors the possible events that get you from one state to another and you issue commands related to the state change at that point only. This way you will only send your sms once, when needed

Try:

if (digitalRead(floatSwitchPin) == HIGH || (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {

Thanks for the feedback, I did as you recommended and now after the serial monitor reaches 300ml, it only sends one sms. However, now when the floatswitch is open, it will continuously send SMS messages

I changed

if (digitalRead(floatSwitchPin) == HIGH || totalMilliLitres > 300) {
    opened = false;

    while (!netStatus()) {
      Serial.println(F("Failed to connect to cell network, retrying..."));
      delay(2000); // Retry every 2s
    }

to

  buttonState = digitalRead(FLOAT_SENSOR);
    if (buttonState != lastButtonState|| (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300)) {
      lastButtonState = buttonState;
      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
//#define FONA_DTR 8 // Connect with solder jumper
//#define FONA_RI 9 // Need to enable via AT commands
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX
//#define T_ALERT 12 // Connect with solder jumper
#define FLOAT_SENSOR 3
#define FLOW_SWITCH 2
#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;
//volatile bool buttonPressed = false;
const int BUTTON = 3;
//const int BUTTON = 2;
// NOTE: Keep the buffer sizes as small as possible, especially on
// Arduino Uno which doesn't have much computing power to handle
// large buffers. On Arduino Mega you shouldn't have to worry much.
char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOATSWITCH = 2; // Use pin 2 to wake up the Uno/Mega

const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message = "FULL!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.

int lastButtonState = 0;
int buttonState = 0;
int buttonPushCounter = 0;

void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);

  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  // Set the APN of the SIM card you're using. You may need to enable data connection
  // for the first time for it to take effect and connect to the network if you're having
  // issues.
  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

  // attachInterrupt(digitalPinToInterrupt(BUTTON), interruptHandler, RISING); // When switch closes (goes HIGH to LOW)
}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute

  totalMilliLitres += flowRate;
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);

  //if (digitalRead(floatSwitchPin) == HIGH || totalMilliLitres > 300) {
   // opened = false;
    buttonState = digitalRead(FLOAT_SENSOR);
    if (buttonState != lastButtonState|| (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300)) {
      lastButtonState = buttonState;
      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }


    }
  }

  // Power on/off the module
  void powerOn(bool state) {
    if (state) {
      Serial.println(F("Turning on SIM7000..."));
      digitalWrite(FONA_PWRKEY, LOW);
      delay(100); // Turn on module
      digitalWrite(FONA_PWRKEY, HIGH);
      delay(4500); // Give enough time for the module to boot up before communicating with it
    }
    else {
      Serial.println(F("Turning off SIM7000..."));
      fona.powerDown(); // Turn off module
    }
  }

  void moduleSetup() {
    fonaSS.begin(115200); // Default SIM7000 shield baud rate

    Serial.println(F("Configuring to 9600 baud"));
    fonaSS.println("AT+IPR=9600"); // Set baud rate
    delay(100); // Short pause to let the command run
    fonaSS.begin(9600);
    if (! fona.begin(fonaSS)) {
      Serial.println(F("Couldn't find FONA"));
      while (1); // Don't proceed if it couldn't find the device
    }

    type = fona.type();
    Serial.println(F("FONA is OK"));
    Serial.print(F("Found "));
    switch (type) {
      case SIM7000A:
        Serial.println(F("SIM7000A (American)")); break;
      case SIM7000C:
        Serial.println(F("SIM7000C (Chinese)")); break;
      case SIM7000E:
        Serial.println(F("SIM7000E (European)")); break;
      case SIM7000G:
        Serial.println(F("SIM7000G (Global)")); break;
      default:
        Serial.println(F("???")); break;
    }

    // Print module IMEI number.
    uint8_t imeiLen = fona.getIMEI(imei);
    if (imeiLen > 0) {
      Serial.print("Module IMEI: "); Serial.println(imei);
    }
  }

  bool netStatus() {
    int n = fona.getNetworkStatus();

    Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
    if (n == 0) Serial.println(F("Not registered"));
    if (n == 1) Serial.println(F("Registered (home)"));
    if (n == 2) Serial.println(F("Not registered (searching)"));
    if (n == 3) Serial.println(F("Denied"));
    if (n == 4) Serial.println(F("Unknown"));
    if (n == 5) Serial.println(F("Registered roaming"));

    if (!(n == 1 || n == 5)) return false;
    else return true;

  }

  void Flow()
  {
    count++; //Every time this function is called, increment "count" by 1
  }

  //void interruptHandler() {
  //delay(50); // Debouncing
  //  buttonPressed = true; // Set flag so code in loop() runs
  //}

Thank you, that may have solved the problem with the threshold, now it only sends one sms after reaching the threshold

what's your Arduino? using one with 2 hardware serial ports or more would help (like a MEGA) as software serial will block interrupts quite often when in use so you'll have contention with the flow meter

you need a critical section to mess around with the counter in the loop.

void loop() {
  // protect access to count with a critical section
  noInterrupts();
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();
  delay (1000);   //Wait 1 second

  // protect access to count with a critical section
  noInterrupts();
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  interrupts();

  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
...

PS/ don't share your phone number

After setup() has executed, @agz2007 's does not use the the software serial until one of the sensor conditions is triggered. After one of the sensor conditions is triggered, the SMS is sent and I suspect the Arduino has to be physically reset for the next measurement cycle. So I don't think hardware serial would help, if @agz2007 needs the circuit to continue to work this way.

Interrupts are not needed and should not be used here in my opinion. I also think the flow calculations may be incorrect. Certainly they are over-complicated.

I'm using a nano though I might switch to an esp32 in the future. I might have to consider a mega because off the top of my head I can think of three interrupts, one is triggered once the flow sensor begins sensing flow, an interrupt when the float switch is open or a threshold amount is reached, and an interrupt when a ds18b20 temp sensor reads below 0 degrees Celsius.

The reason I'm trying to implement interrupts is so that the sim module is only powered on once one of these three conditions exist, saving battery life in the long run as the set up will be powered by a 12v battery

Hello Paul,

You are correct, the math isn't accurate I just thought it would be a better representation using volume instead of counting pulses. The reason why I wanted to use interrupts is to power on the sim module when either the float switch is open, threshold is reached, ds18b20 sensor detects temp below 0 degrees Celsius, and whenever the flow sensor starts to count pulses to send data to a dashboard indicating how full the container is/to verify that liquid is actually being collected.

The idea was that the interrupts would power on the module and then power off after a certain delay to conserve battery life. But now I realize that if I did that, I wouldn't get real time temperature readings on the dashboard either.

Would it be helpful if instead of having the following in the loop, I instead changed the code to call for a void function and make different void functions for different states? like say I had voidfull(), voidtemp(), etc? I think that maybe it repeats because it is inside the loop, which is why it sends the SMS over and over again, is this accurate?

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (10000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute

  totalMilliLitres += flowRate;
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (digitalRead(floatSwitchPin) == HIGH || (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300)) {
    opened = false;

    while (!netStatus()) {
      Serial.println(F("Failed to connect to cell network, retrying..."));
      delay(2000); // Retry every 2s
    }
    Serial.println(F("Connected to cell network!"));

    // Send a text to your phone!
    if (!fona.sendSMS(phone_number, text_message)) {
      Serial.println(F("Failed to send text!"));
    }
    else {
      Serial.println(F("Sent text alert!"));
    }

There's no problem with that. Pulses represent volume. Each pulse represents 2.25ml. 133~134 pulses represent 300ml.

What's over-complicated is calculating flow rate. As far as I can see, you don't care about flow rate. The timing of those pulses is irrelavent to you. So just count the pulses, or increase the total volume by 2.25 each time a pulse is detected. When that count hits 133 or 134, or the volume exceeds 300ml, send the SMS.

That is a valid reason to use interrupts. In fact, put the Arduino back into sleep as soon as the interrupt has been dealt with to maximise battery saving. You can use watchdog timer interrupts to wake the Arduino every few milliseconds and check whether it's time to take a temperature reading, check the volume has reached the target or the level sensor has been triggered and it's time to send the SMS.

No, I don't think that would solve the problem in any way. You just need a bool variable to record when the SMS had been sent. The code can then check that variable before sending another SMS unnecessarily. Alternatively just put a while (false); after the SMS had been sent, to block loop() running until the Arduino is reset.

1 Like

Hi Paul,
thank you for your help. I was able to introduce state changes into the sketch and it is working as it should, it will send a single SMS message once the float switch goes LOW, and a single SMS message when detects 300mL

EDIT: I spoke too soon. It only send an sms when the float switch is open, it does nothing when total milliliters are above 300. Plz help

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;



char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOWSWITCH = 2; // Use pin 2 to wake up the Uno/Mega
const int  buttonPin = 3;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//int buttonState4 = 0;         // current state of the button
//int lastButtonState4 = 0;     // previous state of the button


const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message = "FULL!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately


}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalMilliLitres += flowRate;
  buttonState = digitalRead(buttonPin);
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH || (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300)) {
      opened = false;

      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }
      lastButtonState = buttonState;
      /* Uncomment the section below if you are doing an HTTP request!
        /*
        // Disable data connection before attempting to enable
        if (!fona.enableGPRS(false)) {
        Serial.println(F("Failed to turn off"));
        }

        // Turn on data connection after connecting to network
        while (!fona.enableGPRS(true)) {
        Serial.println(F("Failed to enable GPRS, retrying..."));
        delay(2000); // Retry every 2s
        }
        Serial.println(F("Enabled GPRS!"));

        // Do an HTTP GET request
        // By posting to the web you can link it to things like IFTTT to get
        // email notifications, keep track of any extra data you might add
        // (temperature, GPS, door state, etc) and have fun with it!

        counter = 0; // This counts the number of failed attempts tries

        sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!

        while (counter < 3 && !fona.postData("GET", URL)) {
        Serial.println(F("Failed to post data, retrying..."));
        counter++; // Increment counter
        delay(1000);
        }
      */

      /* Or do an HTTP POST request instead!
        /*
        sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
        body = "{burglar: true}"; // We're keeping it super simple for now!
        //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!

        while (counter < 3 && !fona.postData("POST", URL, body)) {
        Serial.println(F("Failed to complete HTTP POST..."));
        counter++;
        delay(1000);
        }
      */
    }
  }
}
  // Power on/off the module
  void powerOn(bool state) {
    if (state) {
      Serial.println(F("Turning on SIM7000..."));
      digitalWrite(FONA_PWRKEY, LOW);
      delay(100); // Turn on module
      digitalWrite(FONA_PWRKEY, HIGH);
      delay(4500); // Give enough time for the module to boot up before communicating with it
    }
    else {
      Serial.println(F("Turning off SIM7000..."));
      fona.powerDown(); // Turn off module
    }
  }

  void moduleSetup() {
    fonaSS.begin(115200); // Default SIM7000 shield baud rate

    Serial.println(F("Configuring to 9600 baud"));
    fonaSS.println("AT+IPR=9600"); // Set baud rate
    delay(100); // Short pause to let the command run
    fonaSS.begin(9600);
    if (! fona.begin(fonaSS)) {
      Serial.println(F("Couldn't find FONA"));
      while (1); // Don't proceed if it couldn't find the device
    }

    type = fona.type();
    Serial.println(F("FONA is OK"));
    Serial.print(F("Found "));
    switch (type) {
      case SIM7000A:
        Serial.println(F("SIM7000A (American)")); break;
      case SIM7000C:
        Serial.println(F("SIM7000C (Chinese)")); break;
      case SIM7000E:
        Serial.println(F("SIM7000E (European)")); break;
      case SIM7000G:
        Serial.println(F("SIM7000G (Global)")); break;
      default:
        Serial.println(F("???")); break;
    }

    // Print module IMEI number.
    uint8_t imeiLen = fona.getIMEI(imei);
    if (imeiLen > 0) {
      Serial.print("Module IMEI: "); Serial.println(imei);
    }
  }

  bool netStatus() {
    int n = fona.getNetworkStatus();

    Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
    if (n == 0) Serial.println(F("Not registered"));
    if (n == 1) Serial.println(F("Registered (home)"));
    if (n == 2) Serial.println(F("Not registered (searching)"));
    if (n == 3) Serial.println(F("Denied"));
    if (n == 4) Serial.println(F("Unknown"));
    if (n == 5) Serial.println(F("Registered roaming"));

    if (!(n == 1 || n == 5)) return false;
    else return true;

  }

  void Flow()
  {
    count++; //Every time this function is called, increment "count" by 1
  }

Ok so,

When totalMililitres is greater than 300, it will not send an sms. It will however, send an SMS when the floatswitch is open. So if total milliliters is less than 300 and floatswitch is open, it will send SMS. However, if total milliliters is greater than 300, AND the floatswitch is open, it will continuously send SMS, so I'm literally back to where i started

So instead of

 if (buttonState == HIGH || (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300)) {
      opened = false;

      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }
      lastButtonState = buttonState;
      /* Uncomment the section below if you are doing an HTTP request!
        /*
        // Disable data connection before attempting to enable
        if (!fona.enableGPRS(false)) {
        Serial.println(F("Failed to turn off"));
        }

        // Turn on data connection after connecting to network
        while (!fona.enableGPRS(true)) {
        Serial.println(F("Failed to enable GPRS, retrying..."));
        delay(2000); // Retry every 2s
        }
        Serial.println(F("Enabled GPRS!"));

        // Do an HTTP GET request
        // By posting to the web you can link it to things like IFTTT to get
        // email notifications, keep track of any extra data you might add
        // (temperature, GPS, door state, etc) and have fun with it!

        counter = 0; // This counts the number of failed attempts tries

        sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!

        while (counter < 3 && !fona.postData("GET", URL)) {
        Serial.println(F("Failed to post data, retrying..."));
        counter++; // Increment counter
        delay(1000);
        }
      */

      /* Or do an HTTP POST request instead!
        /*
        sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
        body = "{burglar: true}"; // We're keeping it super simple for now!
        //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!

        while (counter < 3 && !fona.postData("POST", URL, body)) {
        Serial.println(F("Failed to complete HTTP POST..."));
        counter++;
        delay(1000);
        }
      */
    }
  }

I removed the OR argument and made it into its own if statement, which seems to do the trick.

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;



char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOWSWITCH = 2; // Use pin 2 to wake up the Uno/Mega
const int  buttonPin = 3;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//int buttonState4 = 0;         // current state of the button
//int lastButtonState4 = 0;     // previous state of the button


const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message = "FULL!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately


}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalMilliLitres += flowRate;
  buttonState = digitalRead(buttonPin);
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      opened = false;

      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }
      lastButtonState = buttonState;
      /* Uncomment the section below if you are doing an HTTP request!
        /*
        // Disable data connection before attempting to enable
        if (!fona.enableGPRS(false)) {
        Serial.println(F("Failed to turn off"));
        }

        // Turn on data connection after connecting to network
        while (!fona.enableGPRS(true)) {
        Serial.println(F("Failed to enable GPRS, retrying..."));
        delay(2000); // Retry every 2s
        }
        Serial.println(F("Enabled GPRS!"));

        // Do an HTTP GET request
        // By posting to the web you can link it to things like IFTTT to get
        // email notifications, keep track of any extra data you might add
        // (temperature, GPS, door state, etc) and have fun with it!

        counter = 0; // This counts the number of failed attempts tries

        sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!

        while (counter < 3 && !fona.postData("GET", URL)) {
        Serial.println(F("Failed to post data, retrying..."));
        counter++; // Increment counter
        delay(1000);
        }
      */

      /* Or do an HTTP POST request instead!
        /*
        sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
        body = "{burglar: true}"; // We're keeping it super simple for now!
        //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!

        while (counter < 3 && !fona.postData("POST", URL, body)) {
        Serial.println(F("Failed to complete HTTP POST..."));
        counter++;
        delay(1000);
        }
      */
    }
  }
  if (totalMilliLitres > 300 && totalMilliLitres - flowRate <=300) {opened = false;

      while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }
      
      /* Uncomment the section below if you are doing an HTTP request!
        /*
        // Disable data connection before attempting to enable
        if (!fona.enableGPRS(false)) {
        Serial.println(F("Failed to turn off"));
        }

        // Turn on data connection after connecting to network
        while (!fona.enableGPRS(true)) {
        Serial.println(F("Failed to enable GPRS, retrying..."));
        delay(2000); // Retry every 2s
        }
        Serial.println(F("Enabled GPRS!"));

        // Do an HTTP GET request
        // By posting to the web you can link it to things like IFTTT to get
        // email notifications, keep track of any extra data you might add
        // (temperature, GPS, door state, etc) and have fun with it!

        counter = 0; // This counts the number of failed attempts tries

        sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!

        while (counter < 3 && !fona.postData("GET", URL)) {
        Serial.println(F("Failed to post data, retrying..."));
        counter++; // Increment counter
        delay(1000);
        }
      */

      /* Or do an HTTP POST request instead!
        /*
        sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
        body = "{burglar: true}"; // We're keeping it super simple for now!
        //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!

        while (counter < 3 && !fona.postData("POST", URL, body)) {
        Serial.println(F("Failed to complete HTTP POST..."));
        counter++;
        delay(1000);
        }
      */
    }
}
  // Power on/off the module
  void powerOn(bool state) {
    if (state) {
      Serial.println(F("Turning on SIM7000..."));
      digitalWrite(FONA_PWRKEY, LOW);
      delay(100); // Turn on module
      digitalWrite(FONA_PWRKEY, HIGH);
      delay(4500); // Give enough time for the module to boot up before communicating with it
    }
    else {
      Serial.println(F("Turning off SIM7000..."));
      fona.powerDown(); // Turn off module
    }
  }

  void moduleSetup() {
    fonaSS.begin(115200); // Default SIM7000 shield baud rate

    Serial.println(F("Configuring to 9600 baud"));
    fonaSS.println("AT+IPR=9600"); // Set baud rate
    delay(100); // Short pause to let the command run
    fonaSS.begin(9600);
    if (! fona.begin(fonaSS)) {
      Serial.println(F("Couldn't find FONA"));
      while (1); // Don't proceed if it couldn't find the device
    }

    type = fona.type();
    Serial.println(F("FONA is OK"));
    Serial.print(F("Found "));
    switch (type) {
      case SIM7000A:
        Serial.println(F("SIM7000A (American)")); break;
      case SIM7000C:
        Serial.println(F("SIM7000C (Chinese)")); break;
      case SIM7000E:
        Serial.println(F("SIM7000E (European)")); break;
      case SIM7000G:
        Serial.println(F("SIM7000G (Global)")); break;
      default:
        Serial.println(F("???")); break;
    }

    // Print module IMEI number.
    uint8_t imeiLen = fona.getIMEI(imei);
    if (imeiLen > 0) {
      Serial.print("Module IMEI: "); Serial.println(imei);
    }
  }

  bool netStatus() {
    int n = fona.getNetworkStatus();

    Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
    if (n == 0) Serial.println(F("Not registered"));
    if (n == 1) Serial.println(F("Registered (home)"));
    if (n == 2) Serial.println(F("Not registered (searching)"));
    if (n == 3) Serial.println(F("Denied"));
    if (n == 4) Serial.println(F("Unknown"));
    if (n == 5) Serial.println(F("Registered roaming"));

    if (!(n == 1 || n == 5)) return false;
    else return true;

  }

  void Flow()
  {
    count++; //Every time this function is called, increment "count" by 1
  }

I changed it again, this time instead of the SMS function being in the loop, its in a separate void function. Don't know how it works but it works. will only send SMS once after it reaches volume threshold or floatswitch is open, doesnt matter if you keep closing and opening the float switch, once it sends the SMS message it won't send another "full" warning until the arduino is reset

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;



char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOWSWITCH = 2; // Use pin 2 to wake up the Uno/Mega
const int  buttonPin = 3;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//int buttonState4 = 0;         // current state of the button
//int lastButtonState4 = 0;     // previous state of the button


const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message1 = "FULL!"; // Change to suit your needs
const char * text_message2 = "FREEZING!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately


}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalMilliLitres += flowRate;
  buttonState = digitalRead(buttonPin);
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      opened = false;
      lastButtonState = buttonState;
       FullSMS ();
      }
    }
  if (totalMilliLitres > 300 && totalMilliLitres - flowRate <=300) {
    opened = false;
    FullSMS();
  }

 
}

  // Power on/off the module
  void powerOn(bool state) {
    if (state) {
      Serial.println(F("Turning on SIM7000..."));
      digitalWrite(FONA_PWRKEY, LOW);
      delay(100); // Turn on module
      digitalWrite(FONA_PWRKEY, HIGH);
      delay(4500); // Give enough time for the module to boot up before communicating with it
    }
    else {
      Serial.println(F("Turning off SIM7000..."));
      fona.powerDown(); // Turn off module
    }
  }

  void moduleSetup() {
    fonaSS.begin(115200); // Default SIM7000 shield baud rate

    Serial.println(F("Configuring to 9600 baud"));
    fonaSS.println("AT+IPR=9600"); // Set baud rate
    delay(100); // Short pause to let the command run
    fonaSS.begin(9600);
    if (! fona.begin(fonaSS)) {
      Serial.println(F("Couldn't find FONA"));
      while (1); // Don't proceed if it couldn't find the device
    }

    type = fona.type();
    Serial.println(F("FONA is OK"));
    Serial.print(F("Found "));
    switch (type) {
      case SIM7000A:
        Serial.println(F("SIM7000A (American)")); break;
      case SIM7000C:
        Serial.println(F("SIM7000C (Chinese)")); break;
      case SIM7000E:
        Serial.println(F("SIM7000E (European)")); break;
      case SIM7000G:
        Serial.println(F("SIM7000G (Global)")); break;
      default:
        Serial.println(F("???")); break;
    }

    // Print module IMEI number.
    uint8_t imeiLen = fona.getIMEI(imei);
    if (imeiLen > 0) {
      Serial.print("Module IMEI: "); Serial.println(imei);
    }
  }

  bool netStatus() {
    int n = fona.getNetworkStatus();

    Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
    if (n == 0) Serial.println(F("Not registered"));
    if (n == 1) Serial.println(F("Registered (home)"));
    if (n == 2) Serial.println(F("Not registered (searching)"));
    if (n == 3) Serial.println(F("Denied"));
    if (n == 4) Serial.println(F("Unknown"));
    if (n == 5) Serial.println(F("Registered roaming"));

    if (!(n == 1 || n == 5)) return false;
    else return true;

  }

  void Flow()
  {
    count++; //Every time this function is called, increment "count" by 1
  }

 void FullSMS (){
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
       while (!netStatus()) {
        Serial.println(F("Failed to connect to cell network, retrying..."));
        delay(2000); // Retry every 2s
      }
      Serial.println(F("Connected to cell network!"));

      // Send a text to your phone!
      if (!fona.sendSMS(phone_number, text_message1)) {
        Serial.println(F("Failed to send text!"));
      }
      else {
        Serial.println(F("Sent text alert!"));
      }
 }

That is because of these nested if statements:

Code isn't magic, is just a very detailed list of instructions that get done one after the other. So looking at the two nested if statements, you can see it's not even going to check the millilitres unless the float switch has just changed.

Maybe try

  if (buttonState == HIGH && lastButtonState == LOW || totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {

The problem now is that you have repeated a lot of code. That's considered a "sin" among programmers! It's bad because it's wasteful and if you need to fix or upgrade that part of the code, you now have to do it in 2 places.

Thank you so much, that did the trick, That'll ease my mind about wasted memory. Now it sends the SMS once the treshold is reached, or when the float switch is opened. Id like to also ask about a similar problem regarding temperature. I'm using a DS18B20 temperature sensor to read the temperature inside the collection tank, and it should send an SMS whenever the temperature is below 30 degrees Fahrenheit/-1C. When I stick the sensor in a pint of ice-cream, temperature goes down as expected and it sends the SMS once its below 30, but it has the same issue where it will continuously send SMS while under 30. Would using this same method be effective for this issue?

totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {

this is the code I use for the temp sensor: I tried changing it to (tempF <= 30 ) but no luck

   if (tempF < 30 ) {
     Serial.println("F: ");
     Serial.print(tempF);
     opened = false;
     delay (1000);
     ColdSMS ();
     }

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;
// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;



char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOWSWITCH = 2; // Use pin 2 to wake up the Uno/Mega
const int  buttonPin = 3;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//int buttonState4 = 0;         // current state of the button
//int lastButtonState4 = 0;     // previous state of the button


const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message1 = "FULL!"; // Change to suit your needs
const char * text_message2 = "FREEZING!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
float tempC;
float tempF;

void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));


  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  //  Serial.print("Parasite power is: ");
  //  if (sensors.isParasitePowerMode()) Serial.println("ON");
  //  else Serial.println("OFF");

  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");

  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 9);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC);
  Serial.println();
}

void loop() {
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  printTemperature(insideThermometer); // Use a simple function to print out the data
  tempC = sensors.getTempCByIndex(0);
  tempF = (tempC * 1.8) + 32;
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino

  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalMilliLitres += flowRate;
  buttonState = digitalRead(buttonPin);
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (buttonState == HIGH && lastButtonState == LOW || totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {
    opened = false;
    lastButtonState = buttonState;
    FullSMS ();
  }

//  if (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {
//    opened = false;
//    FullSMS();
//   }
if (tempF < 30 ) {
  Serial.println("F: ");
  Serial.print(tempF);
  opened = false;
  delay (1000);
  ColdSMS ();
}

}

// Power on/off the module
void powerOn(bool state) {
  if (state) {
    Serial.println(F("Turning on SIM7000..."));
    digitalWrite(FONA_PWRKEY, LOW);
    delay(100); // Turn on module
    digitalWrite(FONA_PWRKEY, HIGH);
    delay(4500); // Give enough time for the module to boot up before communicating with it
  }
  else {
    Serial.println(F("Turning off SIM7000..."));
    fona.powerDown(); // Turn off module
  }
}

void moduleSetup() {
  fonaSS.begin(115200); // Default SIM7000 shield baud rate

  Serial.println(F("Configuring to 9600 baud"));
  fonaSS.println("AT+IPR=9600"); // Set baud rate
  delay(100); // Short pause to let the command run
  fonaSS.begin(9600);
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while (1); // Don't proceed if it couldn't find the device
  }

  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case SIM7000A:
      Serial.println(F("SIM7000A (American)")); break;
    case SIM7000C:
      Serial.println(F("SIM7000C (Chinese)")); break;
    case SIM7000E:
      Serial.println(F("SIM7000E (European)")); break;
    case SIM7000G:
      Serial.println(F("SIM7000G (Global)")); break;
    default:
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
}

bool netStatus() {
  int n = fona.getNetworkStatus();

  Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  if (n == 0) Serial.println(F("Not registered"));
  if (n == 1) Serial.println(F("Registered (home)"));
  if (n == 2) Serial.println(F("Not registered (searching)"));
  if (n == 3) Serial.println(F("Denied"));
  if (n == 4) Serial.println(F("Unknown"));
  if (n == 5) Serial.println(F("Registered roaming"));

  if (!(n == 1 || n == 5)) return false;
  else return true;

}

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}

void FullSMS () {
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
  while (!netStatus()) {
    Serial.println(F("Failed to connect to cell network, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Connected to cell network!"));

  // Send a text to your phone!
  if (!fona.sendSMS(phone_number, text_message1)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void ColdSMS () {
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  //pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
  while (!netStatus()) {
    Serial.println(F("Failed to connect to cell network, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Connected to cell network!"));

  // Send a text to your phone!
  if (!fona.sendSMS(phone_number, text_message2)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}
void printTemperature(DeviceAddress deviceAddress)
{
  // method 1 - slower
  //Serial.print("Temp C: ");
  //Serial.print(sensors.getTempC(deviceAddress));
  //Serial.print(" Temp F: ");
  //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

  // method 2 - faster
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
    return;
  }
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

I also tried to create a variable as a threshold but it still didn't work, keeps sending SMS once below the threshold. I set float tLimit =45.0; in the variables section and changed the temperature code to what is shown below with no luck

if ((tempF < tLimit) &&!opened) {
  Serial.println("F: ");
  Serial.print(tempF);
//  opened = false;
//  delay (1000);
  ColdSMS ();
}

Edit: I thought I made a mistake by writing "!opened", I removed the ! to just opened but that didn't work because now even though it is below the threshold, it wont send the SMS

edit #2: So I changed the code to this:

  if ((tempF < tLimit) && !opened) {
        opened = true;
    //  delay (1000);
    ColdSMS ();
    Serial.println("F: ");
    Serial.print(tempF);
  }

So now, it will ONLY send one text message once it is below the threshold. However, IF it is below the threshold, and if the float switch goes open or the volume is above its threshold, it will send the cold SMS along with the FULL sms. Any advice on this behavior?

Also would like to note that if the temp is below its threshold, and then it goes above its threshold, it wont send the cold sms along with the full sms so at least thats working

Please post the complete updated code.

Of course:


// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;
// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
bool opened = false;



char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

//const int FLOWSWITCH = 2; // Use pin 2 to wake up the Uno/Mega
const int  buttonPin = 3;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//int buttonState4 = 0;         // current state of the button
//int lastButtonState4 = 0;     // previous state of the button


const char * phone_number = "+18000000006"; // Include country code, only numbers
const char * text_message1 = "FULL!"; // Change to suit your needs
const char * text_message2 = "FREEZING!"; // Change to suit your needs

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate.
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
float tempC;
float tempF;
float tLimit = 45.0;
void setup() {
  Serial.begin(115200);
  //  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));


  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
  flowRate          = 0.0;
  totalMilliLitres  = 0;
  //pinMode(BUTTON, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  //  Serial.print("Parasite power is: ");
  //  if (sensors.isParasitePowerMode()) Serial.println("ON");
  //  else Serial.println("OFF");

  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");

  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 9);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC);
  Serial.println();
}

void loop() {
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  printTemperature(insideThermometer); // Use a simple function to print out the data
  tempC = sensors.getTempCByIndex(0);
  tempF = (tempC * 1.8) + 32;
  count = 0;      // Reset the counter so we start counting from 0 again
  //interrupts();   //Enables interrupts on the Arduino

  delay (1000);   //Wait 1 second
  // noInterrupts(); //Disable the interrupts on the Arduino
  // Only send SMS if the switch was closed
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalMilliLitres += flowRate;
  buttonState = digitalRead(buttonPin);
  Serial.println(flowRate);         //Print the variable flowRate to Serial
  Serial.println(totalMilliLitres);
  if (buttonState == HIGH && lastButtonState == LOW || totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {
    opened = false;
    lastButtonState = buttonState;
    FullSMS ();
  }

  //  if (totalMilliLitres > 300 && totalMilliLitres - flowRate <= 300) {
  //    opened = false;
  //    FullSMS();
  //   }

  if (tempF < tLimit && opened == false) {
    ColdSMS ();
    opened = true;
  }

}

// Power on/off the module
void powerOn(bool state) {
  if (state) {
    Serial.println(F("Turning on SIM7000..."));
    digitalWrite(FONA_PWRKEY, LOW);
    delay(100); // Turn on module
    digitalWrite(FONA_PWRKEY, HIGH);
    delay(4500); // Give enough time for the module to boot up before communicating with it
  }
  else {
    Serial.println(F("Turning off SIM7000..."));
    fona.powerDown(); // Turn off module
  }
}

void moduleSetup() {
  fonaSS.begin(115200); // Default SIM7000 shield baud rate

  Serial.println(F("Configuring to 9600 baud"));
  fonaSS.println("AT+IPR=9600"); // Set baud rate
  delay(100); // Short pause to let the command run
  fonaSS.begin(9600);
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while (1); // Don't proceed if it couldn't find the device
  }

  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case SIM7000A:
      Serial.println(F("SIM7000A (American)")); break;
    case SIM7000C:
      Serial.println(F("SIM7000C (Chinese)")); break;
    case SIM7000E:
      Serial.println(F("SIM7000E (European)")); break;
    case SIM7000G:
      Serial.println(F("SIM7000G (Global)")); break;
    default:
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
}

bool netStatus() {
  int n = fona.getNetworkStatus();

  Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  if (n == 0) Serial.println(F("Not registered"));
  if (n == 1) Serial.println(F("Registered (home)"));
  if (n == 2) Serial.println(F("Not registered (searching)"));
  if (n == 3) Serial.println(F("Denied"));
  if (n == 4) Serial.println(F("Unknown"));
  if (n == 5) Serial.println(F("Registered roaming"));

  if (!(n == 1 || n == 5)) return false;
  else return true;

}

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}

void FullSMS () {
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
  while (!netStatus()) {
    Serial.println(F("Failed to connect to cell network, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Connected to cell network!"));

  // Send a text to your phone!
  if (!fona.sendSMS(phone_number, text_message1)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void ColdSMS () {
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  //pinMode(buttonPin, INPUT);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
  while (!netStatus()) {
    Serial.println(F("Failed to connect to cell network, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Connected to cell network!"));

  // Send a text to your phone!
  if (!fona.sendSMS(phone_number, text_message2)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}
void printTemperature(DeviceAddress deviceAddress)
{
  // method 1 - slower
  //Serial.print("Temp C: ");
  //Serial.print(sensors.getTempC(deviceAddress));
  //Serial.print(" Temp F: ");
  //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

  // method 2 - faster
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
    return;
  }
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}