botletics / SIM7000-LTE-Shield

Botletics SIM7000 LTE CAT-M1/NB-IoT Shield for Arduino
https://www.botletics.com/products/sim7000-shield
GNU General Public License v3.0
477 stars 215 forks source link

LTE_Demo While statements blocking code #317

Open alejandrog1994 opened 1 year ago

alejandrog1994 commented 1 year ago

Hello,

I'm working on a project which builds heavily on the LTE_Demo in order to send SMS when sensors on as esp32 detect certain conditions. These SMS functions are meant to complement the project, not be completely reliant on them. An issue I'm having is that if fona fails to initialize, it wont proceed with the rest of the sketch, or if I try to post data to dweet and it fails, it stops the entire program. Not asking to be spoonfed code, but I'm really struggling to find a solution that allows for failure of the FONA functions without stopping the rest of the program. I would very much appreciate advice on how to overcome this obstacle, Thank you

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 20, 4);
#include <Wire.h>
#include <OneWireNg.h>
#include <DallasTemperature.h>
#include <ezButton.h>
#include <Adafruit_ADS1X15.h>
#include <MultiMap.h>
#define ONE_WIRE_BUS 4
/***********************************GPRS/SMS STUFF ****************************************/
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <HardwareSerial.h>
// For SIM7000 shield
#define FONA_PWRKEY 18
#define FONA_RST 5
#define FONA_TX 16 // ESP32 hardware serial RX2 (GPIO16)
#define FONA_RX 17 // ESP32 hardware serial TX2 (GPIO17)

#define SIMCOM_7000
#define PROTOCOL_HTTP_GET         // Generic
#define LED 2

HardwareSerial fonaSS(1);
Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

#define samplingRate 60000UL // The time in between posts, in millis
#define samplingRate2 3000UL // the time between sensor readouts
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;
unsigned long counter = 0;
unsigned long counter2 = 0;
/**** BOOL VARIABLES FOR SMS ALERTS ****/
bool bat = false;
bool opened = false;
bool cold = false;

char volBuff[12];
char tempBuff[12];
char batBuff[12];

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

/**** FLOAT SWITCH ****/
const int  buttonPin = 33;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

const char * phone_number = "+10000000000"; // Include country code, only numbe
/*****                  SMS ALERTS                     ********/
const char * text_message1 = " mL FULL!"; // Change to suit your needs
const char * text_messageV = volBuff;

const char * text_message3 = " % BATTERY LOW!";
const char * text_messageB = batBuff;

const char * text_message2 = "*F FREEZING!"; // Change to suit your needs
const char * text_messageF = tempBuff;

volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.

float tLimit = 45.0; //the amount of liquid in mL that the pump is supposed to collect during pump cycle
int Threshold;       //the threshold for amount of liquid collected before pump returns to OffState
bool ThresholdLimit = false; // flag for Threshold
/**********************************************************************************************************************************/

Adafruit_ADS1115 ads;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;

unsigned long startMillis;                      // Keeps track of millis() when the pumping cycle starts.
unsigned long currentMillis;                    // millis() of the current loop.

// constants for Arduino IO-Pins with SELF-explaining names
const byte samplingBtnPin = 12;
const byte primeBtnPin    = 13;
const byte purgeBtnPin    = 14;
const byte resetBtnPin    = 32;
ezButton button1(12);  // create ezButton object that attach to pin 12;
ezButton button2(32);  // create ezButton object that attach to pin 12;
const byte DRV8876_IN1_PIN    = 26;
const byte DRV8876_IN2_PIN    = 27;

int flowPin = 25;    //This is the input pin on the Arduino, flow switch
float calibrationFactor = 150;                    //calibration factor for sampling is 150, need to make if else statement for it
float tempC;
float tempF;
int percent;

/**************************************************** Battery stuf **************************************************/
int R1 = 27, R2 = 10; // 10k and 27k ; the resistor ratio
float dividerRatio; // pre-calculate in setup
float calFactor = 1.01; // calibrate  if needed
int in[] = {
  10000, 12000, 12500, 12800, 12900, 13000, 13100, 13200, 13300, 13400, 13600, 14600, 14900
};                                                                                         // [13] IN holds the mV inputs
int out [] = {
  0, 9, 14, 17, 20, 30, 40, 70, 90, 99, 100, 110, 120
};                                                                                       // [13] OUT holds the percentage outputs
float bLimit = 20; // the lower limit of the percentage, if battery percent falls below 20, lowbatsMs is sent
int Val;  // holds input and output values for multimap
float vLimit = 45.0;
/*********************************************************************************************************************/

volatile byte pulseCount;                       // counts the pulses of flow sensor
float flowRate;
unsigned int flowMilliLitres;                  //totaltotalMilliLitres used for the interrupts
unsigned long totalMilliLitres;
unsigned long oldTime;
unsigned long cloopTime;                      // to count pulses per second
unsigned long vol;                           //vol tracks total volume throughout loop

// constants for the states with SELF-explaining names
const byte OffState     = 0;
const byte PumpState    = 1;
const byte PausingState = 2;
const byte ReverseState = 3;
const byte RestState    = 4;
const byte FullState     = 5;
const byte PurgeState = 6;
byte state;

#define pressed HIGH
#define released LOW
#define closed HIGH
#define open LOW

// bool primeBtnPinHasBeenPressed = true;
bool purgeBtnPinHasBeenPressed = false;

void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

void setup() {
  Serial.begin(115200);
  lcd.begin();
  button1.setDebounceTime(100); // set debounce time to 50 milliseconds
  button2.setDebounceTime(50); // set debounce time to 50 milliseconds
  Serial.println("ESP32 PUMP");
  pinMode(primeBtnPin, INPUT_PULLUP);    // pinMode(5, INPUT);
  pinMode(purgeBtnPin, INPUT_PULLUP);    // pinMode(6, INPUT);
  pinMode(samplingBtnPin, INPUT_PULLUP); // pinMode(7, INPUT);
  pinMode(resetBtnPin , INPUT_PULLUP);

  pinMode(DRV8876_IN1_PIN, OUTPUT); // pinMode(A0, OUTPUT);
  pinMode(DRV8876_IN2_PIN, OUTPUT); // pinMode(A1, OUTPUT);

  pinMode(flowPin, INPUT_PULLUP);
  digitalWrite(flowPin, LOW);

  Threshold         = 300.0; //Threshold limit
  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0.0;
  totalMilliLitres  = 0;
  vol               = 0;
  cloopTime = currentMillis;
  attachInterrupt(digitalPinToInterrupt(flowPin), pulseCounter, FALLING);

  dividerRatio = (R1 + R2) / R1;
  ads.setGain(GAIN_ONE);
  ads.begin();
  /************************************************GRPS/SMS STUFF*************************************************/
#ifdef LED
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
#endif

  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state

  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  fona.setFunctionality(1); // AT+CFUN=1
  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

  // Perform first-time GPS/GPRS setup if the shield is going to remain on,
  // otherwise these won't be enabled in loop() and it won't work!
#ifndef turnOffShield

#if !defined(SIMCOM_3G) && !defined(SIMCOM_7500) && !defined(SIMCOM_7600)
  // Disable GPRS just to make sure it was actually off so that we can turn it on
  if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

  // Turn on GPRS
  while (!fona.enableGPRS(true)) {
    Serial.println(F("Failed to enable GPRS, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Enabled GPRS!"));
#endif
#endif
  /************************************************GRPS/SMS STUFF end*********************************************/

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

  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: ");

  if (Threshold < vol && ThresholdLimit == false)
  { // if the threshold (300mL) is less than vol, set Threshold limit to true
    ThresholdLimit = true;
  }

}

void loop() {
  button1.loop(); // MUST call the loop() function first
  button2.loop(); // MUST call the loop() function first
  int btn1State = button1.getState();
  int btn2State = button2.getState();
  //  if (digitalRead(primeBtnPin) == released) primeBtnPinHasBeenPressed = false;
  if (digitalRead(purgeBtnPin) == released) purgeBtnPinHasBeenPressed = true;

  currentMillis = millis();                   // Get the current value of millis().

  buttonState = digitalRead(buttonPin);

  if (digitalRead(samplingBtnPin) == released)
    if (state > OffState)                              // Are we already in a pumping cycle?
      state = OffState;
    else
      state = PumpState;

  //  delay(200);                         // Small delay to debounce the button.

  int adc0 = ads.readADC_SingleEnded(0);
  float battVoltage = ads.computeVolts(adc0) * dividerRatio * calFactor;
  float battVolt = battVoltage * 3.7;
  int battmV = (battVolt * 1000) + 30;
  Val = battmV;
  //  int percent;
  percent =  multiMap(Val, in, out, 13);
  //  delay(1000);
  dtostrf(percent, 1, 2, batBuff);
  dtostrf(tempF, 1, 2, tempBuff);
  dtostrf(vol, 1, 2, volBuff);
  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;
  lcd.setCursor(0, 3);
  lcd.print("B%");
  lcd.setCursor(3, 3);
  lcd.print(percent);
  lcd.setCursor(7, 3);
  lcd.print("TEMP:");
  lcd.setCursor(13, 3);
  lcd.print(tempF);

  if (percent < 100) { //if battery percent falls below 100, erase the third digit
    lcd.setCursor(5, 3);
    lcd.print(" ");
  }

  if (percent < 10) {
    lcd.setCursor(4, 3);  //if battery falls below 10 percent, erase second and third digit
    lcd.print("  ");
  }

  /*********************************  read sensor stats and print on serial monitor *************************/
  if (currentMillis - counter2 > samplingRate2) {
    Serial.println("-----------------------------------------------------------");
    Serial.print("Batt Volts: "); Serial.print(battVoltage, 3); Serial.print(" "); Serial.print("AIN0: "); Serial.print(adc0 ); Serial.print(" "); Serial.print(" BatVolt: "); Serial.println(battVolt, 3);
    Serial.print("Battery mV: "); Serial.print(battmV); Serial.print(" "); Serial.print("Battery level [%]: "); Serial.println(percent);
    Serial.println(sensors.getResolution(insideThermometer), DEC);
    Serial.print("Temp C: "); Serial.print(tempC); Serial.print(" "); Serial.print(" Temp F: "); Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
    Serial.print("FLOW ML: "); Serial.println(flowMilliLitres);
    if (ThresholdLimit == true) {
      Serial.print("THRESHOLD REACHED"); Serial.println(Threshold);
    } else
    {
      Serial.println("THRESHOLD NOT REACHED");
    }
    if (digitalRead(buttonPin) == HIGH) {
      Serial.println("FLOAT SWITCH OPEN!");
    }
    Serial.println("-----------------------------------------------------------");

    counter2 = millis();
    currentMillis = millis();
  }

  /****** flow rate math ********/
  if (currentMillis >= (cloopTime + 1000))
  {
    cloopTime = currentMillis;
    if (pulseCount != 0) {
      flowRate =  (pulseCount / calibrationFactor);
      //oldTime = millis();
      flowMilliLitres = (flowRate / 60) * 1000;
      totalMilliLitres += flowMilliLitres;
      vol              += flowMilliLitres;
      Serial.print(flowRate); Serial.println(" :L/min");
      Serial.print(totalMilliLitres); Serial.println(" :mL");
      lcd.setCursor(0, 1);
      lcd.print(flowRate);
      lcd.setCursor(5, 1);
      lcd.print(":L/min");
      lcd.setCursor(0, 2);
      lcd.print(vol);
      lcd.setCursor(6, 2);
      lcd.print(": mL");
      pulseCount = 0;
    }
    else {
      Serial.print(flowRate); Serial.println(" :L/min");
      Serial.print(vol); Serial.println(" :mL");
      lcd.setCursor(0, 1);
      lcd.print(flowRate);
      lcd.setCursor(6, 1);
      lcd.print(":L/min");
      lcd.setCursor(0, 2);
      lcd.print(vol);
      lcd.setCursor(6, 2);
      lcd.print(": mL");
      flowRate = 0;

    }
  }

  switch (state)                        // Check which state we are in.
  {

    case OffState:

      //    manualMode();
      if (digitalRead(primeBtnPin) == pressed) {

        pumpOff();
      }
      else {
        manualMode();
        break;
      }

      if (purgeBtnPinHasBeenPressed = true) {
        state = PurgeState;
      }
      else {
      break;
      }

      if (digitalRead(resetBtnPin) == released)   // keep this button in OffState case so that if accidently pressed it wont hurt anything
        resetData();

      startMillis = currentMillis;      // Keep resetting the start time of the pumping sequence.
      pumpOff();
      break;

    case PurgeState:
      if (digitalRead(purgeBtnPin) == pressed)
        state = OffState;
      else
        manualPurge();
      break;

    case PumpState:
      if (totalMilliLitres > vLimit || currentMillis - startMillis > 10000)        /// did we collect XmL? if not, go to next stage after X millis
        state = PausingState;
      else

        PumpForward();

      break;

    case PausingState:
      if (currentMillis - startMillis > 13000)   // Have we been in this state too long?
        state = ReverseState;
      else
        pumpOff();
      Serial.println("PAUSE!");
      lcd.setCursor(0, 0);
      lcd.print("PAUSED! ");

      break;

    case ReverseState:
      if (currentMillis - startMillis > 23000) // Have we been in this state too long?
        state = RestState;//state++;
      else
        PumpReverse();

      break;

    case RestState:
      if (currentMillis - startMillis > 30000)  // has it been X minutes?
      {

        state = FullState;
        startMillis = currentMillis;            // Reset the start time of the pumping sequence.
        totalMilliLitres = 0;                  //reset totalMilliLitres so it can start counting up from 0 again

      }
      else
        pumpOff();
      Serial.println("REST!");
      lcd.setCursor(0, 0);
      lcd.print("RESTING!");
      if (Threshold < vol && ThresholdLimit == false)
        ThresholdLimit = true;
      break;

    case FullState:
      if (ThresholdLimit = true ||  (digitalRead(buttonPin) == HIGH))
        state = OffState;

      else
        Serial.println(state);
      state = PumpState;
      break;
  }
  /***************************SMS ALERTS***************************************************/
  if (buttonState == HIGH && lastButtonState == LOW || vol > 300 && vol - flowMilliLitres <= 300) {
    opened = false;
    lastButtonState = buttonState;
    FullSMS ();
    pumpOff();
    lcd.setCursor(0, 0);
    lcd.print("FULL          ");
  }

  if (tempF < tLimit && cold == false) {
    ColdSMS ();
    cold = true;
  }
  else if (tempF > tLimit + 2.0 && cold == true) {
    cold = false;
  }
  if (percent < bLimit && bat == false) {
    batSMS ();
    bat = true;
  }
  /***************************SMS ALERTS END***************************************************/
  /**************************** DATA POST TO DWEET *********************************************/
  if (millis() - counter > samplingRate) {
    PostData ();
    counter = millis ();
  }
}

void Full() {
  lcd.setCursor (0, 0);
  lcd.print("FULL");
  digitalWrite(DRV8876_IN1_PIN, LOW);
  digitalWrite(DRV8876_IN2_PIN, LOW);
}

void manualMode() {
  digitalWrite(DRV8876_IN1_PIN, HIGH);  // comment is obsolete code epxlains ITSELF Turn on the pump (forward).
  digitalWrite(DRV8876_IN2_PIN, LOW);
  //  Serial.println("PUMPING!");
  lcd.setCursor(0, 0);
  lcd.print("PUMPING!");
}

void manualPurge() {
  digitalWrite(DRV8876_IN1_PIN, LOW);  // comment is obsolete code epxlains ITSELF Turn on the pump (forward).
  digitalWrite(DRV8876_IN2_PIN, HIGH);
  //  Serial.println("PUMPING!");
  lcd.setCursor(0, 0);
  lcd.print("PURGING!");
}

// senseful SUB-unit of code with a SELF-explaining name
void PumpForward() {
  digitalWrite(DRV8876_IN1_PIN, HIGH);  // comment is obsolete code epxlains ITSELF Turn on the pump (forward).
  digitalWrite(DRV8876_IN2_PIN, LOW);
  //  Serial.println("PUMPING!");
  lcd.setCursor(0, 0);
  lcd.print("PUMPING!");
}

void resetData() {
  currentMillis = millis();
  startMillis = currentMillis;
  cloopTime = currentMillis;
  totalMilliLitres = 0;
  flowRate = 0;
  vol = 0;
  flowMilliLitres = 0;
  //  ThresholdLimit = false;
  Serial.println("Data Reset");
  lcd.setCursor(0, 2);
  lcd.print(vol);
  lcd.setCursor(1, 2);
  lcd.print("    ");
  pulseCount = 0;
}
// senseful SUB-unit of code with a SELF-explaining name
void PumpReverse() {
  digitalWrite(DRV8876_IN1_PIN, LOW);  // comment is obsolete code epxlains ITSELF Reverse the pump.
  digitalWrite(DRV8876_IN2_PIN, HIGH);
  Serial.println("PURGING!");
  lcd.setCursor(0, 0);
  lcd.print("PURGING!");
}

// senseful SUB-unit of code with a SELF-explaining name
void pumpOff()
{
  digitalWrite(DRV8876_IN1_PIN, LOW);
  digitalWrite(DRV8876_IN2_PIN, LOW);
  lcd.setCursor(0, 0);
  lcd.print("PUMP OFF");
}

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;
  }

}

// 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);
  }
}

// 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() {
  // SIM7000 takes about 3s to turn on and SIM7500 takes about 15s
  // Press Arduino reset button if the module is still turning on and the board doesn't find it.
  // When the module is on it should communicate right after pressing reset

  // Software serial:
  fonaSS.begin(115200, SERIAL_8N1, FONA_TX, FONA_RX); // baud rate, protocol, ESP32 RX pin, ESP32 TX pin

  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, SERIAL_8N1, FONA_TX, FONA_RX); // Switch to 9600
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while (1); // Don't proceed if it couldn't find the device
  }

  // Hardware serial:
  /*
    fonaSerial->begin(115200); // Default SIM7000 baud rate

    if (! fona.begin(*fonaSerial)) {
    DEBUG_PRINTLN(F("Couldn't find SIM7000"));
    }
  */

  // The commented block of code below is an alternative that will find the module at 115200
  // Then switch it to 9600 without having to wait for the module to turn on and manually
  // press the reset button in order to establish communication. However, once the baud is set
  // this method will be much slower.
  /*
    fonaSerial->begin(115200); // Default LTE shield baud rate
    fona.begin(*fonaSerial); // Don't use if statement because an OK reply could be sent incorrectly at 115200 baud

    Serial.println(F("Configuring to 9600 baud"));
    fona.setBaudrate(9600); // Set to 9600 baud
    fonaSerial->begin(9600);
    if (!fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find modem"));
    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 SIM800L:
      Serial.println(F("SIM800L")); break;
    case SIM800H:
      Serial.println(F("SIM800H")); break;
    case SIM808_V1:
      Serial.println(F("SIM808 (v1)")); break;
    case SIM808_V2:
      Serial.println(F("SIM808 (v2)")); break;
    case SIM5320A:
      Serial.println(F("SIM5320A (American)")); break;
    case SIM5320E:
      Serial.println(F("SIM5320E (European)")); break;
    case SIM7000:
      Serial.println(F("SIM7000")); break;
    case SIM7070:
      Serial.println(F("SIM7070")); break;
    case SIM7500:
      Serial.println(F("SIM7500")); break;
    case SIM7600:
      Serial.println(F("SIM7600")); 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 FullSMS () {
  char message3[20];

  strcpy(message3, volBuff);
  strcat(message3, text_message1);

  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  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, message3)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void ColdSMS () {
  char message[20];

  strcpy(message, tempBuff);
  strcat(message, text_message2);
  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
  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, message)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void batSMS () {
  char message2[25];

  strcpy(message2, batBuff);
  strcat(message2, text_message3);
  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
  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, message2)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void PostData ()
{
  // If the shield was already on, no need to re-enable
#if defined(turnOffShield) && !defined(SIMCOM_3G) && !defined(SIMCOM_7500) && !defined(SIMCOM_7600)
  // Disable GPRS just to make sure it was actually off so that we can turn it on
  if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

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

  // Post something like temperature and battery level to the web API
  // Construct URL and post the data to the web API

  // Format the floating point numbers

  // Also construct a combined, comma-separated location array
  // (many platforms require this for dashboards, like Adafruit IO):
  //sprintf(locBuff, "%s,%s,%s,%s", speedBuff, latBuff, longBuff, altBuff); // This could look like "10,33.123456,-85.123456,120.5"

  // Construct the appropriate URL's and body, depending on request type
  // In this example we use the IMEI as device ID

#ifdef PROTOCOL_HTTP_GET
  // GET request

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

#if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)
  // You can adjust the contents of the request if you don't need certain things like speed, altitude, etc.
  sprintf(URL, "GET /dweet/for/%s?temp=%s&bat=%s&vol=%s HTTP/1.1\r\nHost: dweet.io\r\n\r\n",
          imei, tempBuff, batBuff, volBuff);

  // Try a total of three times if the post was unsuccessful (try additional 2 times)
  while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL)) { // Server, port, connection type, URL
    Serial.println(F("Failed to complete HTTP/HTTPS request..."));
    counter++; // Increment counter
    delay(1000);
  }
#else
  sprintf(URL, "http://dweet.io/dweet/for/%s?temp=%s&bat=%s&vol=%s", imei, tempBuff, batBuff, volBuff);

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

#elif defined(PROTOCOL_HTTP_POST)
  // You can also do a POST request instead

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

#if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)
  sprintf(body, "{\"lat\":%s,\"long\":%s}\r\n", latBuff, longBuff); // Terminate with CR+NL
  sprintf(URL, "POST /dweet/for/%s HTTP/1.1\r\nHost: dweet.io\r\nContent-Length: %i\r\n\r\n", imei, strlen(body));

  while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL, body)) { // Server, port, connection type, URL
    Serial.println(F("Failed to complete HTTP/HTTPS request..."));
    counter++; // Increment counter
    delay(1000);
  }
#else
  sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
  sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff);

  // Let's try a POST request to thingsboard.io
  // Please note this can me memory-intensive for the Arduino Uno
  // and may not work. You might have to split it up into a couple requests
  // and send part of the data in one request, and the rest in the other, etc.
  // Perhaps an easier solution is to swap out the Uno with an Arduino Mega.
  /*
    const char * token = "qFeFpQIC9C69GDFLWdAv"; // From thingsboard.io device
    sprintf(URL, "http://demo.thingsboard.io/api/v1/%s/telemetry", token);
    sprintf(body, "{\"lat\":%s,\"long\":%s,\"speed\":%s,\"head\":%s,\"alt\":%s,\"temp\":%s,\"batt\":%s}", latBuff, longBuff,
          speedBuff, headBuff, altBuff, tempBuff, battBuff);
    //  sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff); // If all you want is lat/long
  */

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

#endif

  //Only run the code below if you want to turn off the shield after posting data
#ifdef turnOffShield
  // Disable GPRS
  // Note that you might not want to check if this was successful, but just run it
  // since the next command is to turn off the module anyway
  if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

  // Turn off GPS
  if (!fona.enableGPS(false)) Serial.println(F("Failed to turn off GPS!"));

  // Power off the module. Note that you could instead put it in minimum functionality mode
  // instead of completely turning it off. Experiment different ways depending on your application!
  // You should see the "PWR" LED turn off after this command
  //  if (!fona.powerDown()) Serial.println(F("Failed to power down FONA!")); // No retries
  counter = 0;
  while (counter < 3 && !fona.powerDown()) { // Try shutting down
    Serial.println(F("Failed to power down FONA!"));
    counter++; // Increment counter
    delay(1000);
  }
#endif

  // Alternative to the AT command method above:
  // If your FONA has a PWRKEY pin connected to your MCU, you can pulse PWRKEY
  // LOW for a little bit, then pull it back HIGH, like this:
  //  digitalWrite(PWRKEY, LOW);
  //  delay(600); // Minimum of 64ms to turn on and 500ms to turn off for FONA 3G. Check spec sheet for other types
  //  delay(1300); // Minimum of 1.2s for SIM7000
  //  digitalWrite(PWRKEY, HIGH);

  // Shut down the MCU to save power
#ifndef samplingRate
  Serial.println(F("Shutting down..."));
  delay(5); // This is just to read the response of the last AT command before shutting down
  MCU_powerDown(); // You could also write your own function to make it sleep for a certain duration instead
#else
  //  // The following lines are for if you want to periodically post data (like GPS tracker)
  //  Serial.print(F("Waiting for ")); Serial.print(samplingRate); Serial.println(F(" seconds\r\n"));
  //  delay(samplingRate * 1000UL); // Delay

  // Only run the initialization again if the module was powered off
  // since it resets back to 115200 baud instead of 4800.
#ifdef turnOffShield
  fona.powerOn(FONA_PWRKEY); // Powers on the module if it was off previously
  moduleSetup();
#endif

#endif
}
botletics commented 1 year ago

That's a lot of code to look through, but the first thing that comes to mind is to delete this line:

while(1); // Don't proceed if it couldn't find the device

in the moduleSetup() function.

willburk97 commented 1 year ago

I think I revised it in my code to just try for a set number of millis and then move on. I'm using an older version of the repository and my code's pretty messy, sorry, but it's here: https://github.com/willburk97/CH4100_SIM7000

-Will


From: alejandrog1994 @.> Sent: Tuesday, December 6, 2022 9:34:50 PM To: botletics/SIM7000-LTE-Shield @.> Cc: Subscribed @.***> Subject: [botletics/SIM7000-LTE-Shield] LTE_Demo While statements blocking code (Issue #317)

Hello,

I'm working on a project which builds heavily on the LTE_Demo in order to send SMS when sensors on as esp32 detect certain conditions. These SMS functions are meant to complement the project, not be completely reliant on them. An issue I'm having is that if fona fails to initialize, it wont proceed with the rest of the sketch, or if I try to post data to dweet and it fails, it stops the entire program. Not asking to be spoonfed code, but I'm really struggling to find a solution that allows for failure of the FONA functions without stopping the rest of the program. I would very much appreciate advice on how to overcome this obstacle, Thank you

include

LiquidCrystal_I2C lcd(0x3F, 20, 4);

include

include

include

include

include

include

define ONE_WIRE_BUS 4

/***GPRS/SMS STUFF ****/

include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code

include

// For SIM7000 shield

define FONA_PWRKEY 18

define FONA_RST 5

define FONA_TX 16 // ESP32 hardware serial RX2 (GPIO16)

define FONA_RX 17 // ESP32 hardware serial TX2 (GPIO17)

define SIMCOM_7000

define PROTOCOL_HTTP_GET // Generic

define LED 2

HardwareSerial fonaSS(1); Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

define samplingRate 60000UL // The time in between posts, in millis

define samplingRate2 3000UL // the time between sensor readouts

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; unsigned long counter = 0; unsigned long counter2 = 0; / BOOL VARIABLES FOR SMS ALERTS / bool bat = false; bool opened = false; bool cold = false;

char volBuff[12]; char tempBuff[12]; char batBuff[12];

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

/ FLOAT SWITCH / const int buttonPin = 33; int buttonState = 0; // current state of the button int lastButtonState = 0; // previous state of the button

const char * phone_number = "+10000000000"; // Include country code, only numbe /* SMS ALERTS ****/ const char text_message1 = " mL FULL!"; // Change to suit your needs const char text_messageV = volBuff;

const char text_message3 = " % BATTERY LOW!"; const char text_messageB = batBuff;

const char text_message2 = "F FREEZING!"; // Change to suit your needs const char * text_messageF = tempBuff;

volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.

float tLimit = 45.0; //the amount of liquid in mL that the pump is supposed to collect during pump cycle int Threshold; //the threshold for amount of liquid collected before pump returns to OffState bool ThresholdLimit = false; // flag for Threshold /**/

Adafruit_ADS1115 ads; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress insideThermometer;

unsigned long startMillis; // Keeps track of millis() when the pumping cycle starts. unsigned long currentMillis; // millis() of the current loop.

// constants for Arduino IO-Pins with SELF-explaining names const byte samplingBtnPin = 12; const byte primeBtnPin = 13; const byte purgeBtnPin = 14; const byte resetBtnPin = 32; ezButton button1(12); // create ezButton object that attach to pin 12; ezButton button2(32); // create ezButton object that attach to pin 12; const byte DRV8876_IN1_PIN = 26; const byte DRV8876_IN2_PIN = 27;

int flowPin = 25; //This is the input pin on the Arduino, flow switch float calibrationFactor = 150; //calibration factor for sampling is 150, need to make if else statement for it float tempC; float tempF; int percent;

/**** Battery stuf **/ int R1 = 27, R2 = 10; // 10k and 27k ; the resistor ratio float dividerRatio; // pre-calculate in setup float calFactor = 1.01; // calibrate if needed int in[] = { 10000, 12000, 12500, 12800, 12900, 13000, 13100, 13200, 13300, 13400, 13600, 14600, 14900 }; // [13] IN holds the mV inputs int out [] = { 0, 9, 14, 17, 20, 30, 40, 70, 90, 99, 100, 110, 120 }; // [13] OUT holds the percentage outputs float bLimit = 20; // the lower limit of the percentage, if battery percent falls below 20, lowbatsMs is sent int Val; // holds input and output values for multimap float vLimit = 45.0; /*****/

volatile byte pulseCount; // counts the pulses of flow sensor float flowRate; unsigned int flowMilliLitres; //totaltotalMilliLitres used for the interrupts unsigned long totalMilliLitres; unsigned long oldTime; unsigned long cloopTime; // to count pulses per second unsigned long vol; //vol tracks total volume throughout loop

// constants for the states with SELF-explaining names const byte OffState = 0; const byte PumpState = 1; const byte PausingState = 2; const byte ReverseState = 3; const byte RestState = 4; const byte FullState = 5; const byte PurgeState = 6; byte state;

define pressed HIGH

define released LOW

define closed HIGH

define open LOW

// bool primeBtnPinHasBeenPressed = true; bool purgeBtnPinHasBeenPressed = false;

void pulseCounter() { // Increment the pulse counter pulseCount++; }

void setup() { Serial.begin(115200); lcd.begin(); button1.setDebounceTime(100); // set debounce time to 50 milliseconds button2.setDebounceTime(50); // set debounce time to 50 milliseconds Serial.println("ESP32 PUMP"); pinMode(primeBtnPin, INPUT_PULLUP); // pinMode(5, INPUT); pinMode(purgeBtnPin, INPUT_PULLUP); // pinMode(6, INPUT); pinMode(samplingBtnPin, INPUT_PULLUP); // pinMode(7, INPUT); pinMode(resetBtnPin , INPUT_PULLUP);

pinMode(DRV8876_IN1_PIN, OUTPUT); // pinMode(A0, OUTPUT); pinMode(DRV8876_IN2_PIN, OUTPUT); // pinMode(A1, OUTPUT);

pinMode(flowPin, INPUT_PULLUP); digitalWrite(flowPin, LOW);

Threshold = 300.0; //Threshold limit pulseCount = 0; flowRate = 0.0; flowMilliLitres = 0.0; totalMilliLitres = 0; vol = 0; cloopTime = currentMillis; attachInterrupt(digitalPinToInterrupt(flowPin), pulseCounter, FALLING);

dividerRatio = (R1 + R2) / R1; ads.setGain(GAIN_ONE); ads.begin(); /****GRPS/SMS STUFF*****/

ifdef LED

pinMode(LED, OUTPUT); digitalWrite(LED, LOW);

endif

pinMode(FONA_RST, OUTPUT); digitalWrite(FONA_RST, HIGH); // Default state

pinMode(FONA_PWRKEY, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); powerOn(true); // Power on the module moduleSetup(); // Establish first-time serial comm and print IMEI

fona.setFunctionality(1); // AT+CFUN=1 fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

// Perform first-time GPS/GPRS setup if the shield is going to remain on, // otherwise these won't be enabled in loop() and it won't work!

ifndef turnOffShield

if !defined(SIMCOM_3G) && !defined(SIMCOM_7500) && !defined(SIMCOM_7600)

// Disable GPRS just to make sure it was actually off so that we can turn it on if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

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

endif

endif

/****GRPS/SMS STUFF end*****/

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

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: ");

if (Threshold < vol && ThresholdLimit == false) { // if the threshold (300mL) is less than vol, set Threshold limit to true ThresholdLimit = true; }

}

void loop() { button1.loop(); // MUST call the loop() function first button2.loop(); // MUST call the loop() function first int btn1State = button1.getState(); int btn2State = button2.getState(); // if (digitalRead(primeBtnPin) == released) primeBtnPinHasBeenPressed = false; if (digitalRead(purgeBtnPin) == released) purgeBtnPinHasBeenPressed = true;

currentMillis = millis(); // Get the current value of millis().

buttonState = digitalRead(buttonPin);

if (digitalRead(samplingBtnPin) == released) if (state > OffState) // Are we already in a pumping cycle? state = OffState; else state = PumpState;

// delay(200); // Small delay to debounce the button.

int adc0 = ads.readADC_SingleEnded(0); float battVoltage = ads.computeVolts(adc0) dividerRatio calFactor; float battVolt = battVoltage 3.7; int battmV = (battVolt 1000) + 30; Val = battmV; // int percent; percent = multiMap(Val, in, out, 13); // delay(1000); dtostrf(percent, 1, 2, batBuff); dtostrf(tempF, 1, 2, tempBuff); dtostrf(vol, 1, 2, volBuff); 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; lcd.setCursor(0, 3); lcd.print("B%"); lcd.setCursor(3, 3); lcd.print(percent); lcd.setCursor(7, 3); lcd.print("TEMP:"); lcd.setCursor(13, 3); lcd.print(tempF);

if (percent < 100) { //if battery percent falls below 100, erase the third digit lcd.setCursor(5, 3); lcd.print(" "); }

if (percent < 10) { lcd.setCursor(4, 3); //if battery falls below 10 percent, erase second and third digit lcd.print(" "); }

/***** read sensor stats and print on serial monitor */ if (currentMillis - counter2 > samplingRate2) { Serial.println("-----------------------------------------------------------"); Serial.print("Batt Volts: "); Serial.print(battVoltage, 3); Serial.print(" "); Serial.print("AIN0: "); Serial.print(adc0 ); Serial.print(" "); Serial.print(" BatVolt: "); Serial.println(battVolt, 3); Serial.print("Battery mV: "); Serial.print(battmV); Serial.print(" "); Serial.print("Battery level [%]: "); Serial.println(percent); Serial.println(sensors.getResolution(insideThermometer), DEC); Serial.print("Temp C: "); Serial.print(tempC); Serial.print(" "); Serial.print(" Temp F: "); Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit Serial.print("FLOW ML: "); Serial.println(flowMilliLitres); if (ThresholdLimit == true) { Serial.print("THRESHOLD REACHED"); Serial.println(Threshold); } else { Serial.println("THRESHOLD NOT REACHED"); } if (digitalRead(buttonPin) == HIGH) { Serial.println("FLOAT SWITCH OPEN!"); } Serial.println("-----------------------------------------------------------");

counter2 = millis();
currentMillis = millis();

}

/** flow rate math ****/ if (currentMillis >= (cloopTime + 1000)) { cloopTime = currentMillis; if (pulseCount != 0) { flowRate = (pulseCount / calibrationFactor); //oldTime = millis(); flowMilliLitres = (flowRate / 60) * 1000; totalMilliLitres += flowMilliLitres; vol += flowMilliLitres; Serial.print(flowRate); Serial.println(" :L/min"); Serial.print(totalMilliLitres); Serial.println(" :mL"); lcd.setCursor(0, 1); lcd.print(flowRate); lcd.setCursor(5, 1); lcd.print(":L/min"); lcd.setCursor(0, 2); lcd.print(vol); lcd.setCursor(6, 2); lcd.print(": mL"); pulseCount = 0; } else { Serial.print(flowRate); Serial.println(" :L/min"); Serial.print(vol); Serial.println(" :mL"); lcd.setCursor(0, 1); lcd.print(flowRate); lcd.setCursor(6, 1); lcd.print(":L/min"); lcd.setCursor(0, 2); lcd.print(vol); lcd.setCursor(6, 2); lcd.print(": mL"); flowRate = 0;

}

}

switch (state) // Check which state we are in. {

case OffState:

  //    manualMode();
  if (digitalRead(primeBtnPin) == pressed) {

    pumpOff();
  }
  else {
    manualMode();
    break;
  }

  if (purgeBtnPinHasBeenPressed = true) {
    state = PurgeState;
  }
  else {
  break;
  }

  if (digitalRead(resetBtnPin) == released)   // keep this button in OffState case so that if accidently pressed it wont hurt anything
    resetData();

  startMillis = currentMillis;      // Keep resetting the start time of the pumping sequence.
  pumpOff();
  break;

case PurgeState:
  if (digitalRead(purgeBtnPin) == pressed)
    state = OffState;
  else
    manualPurge();
  break;

case PumpState:
  if (totalMilliLitres > vLimit || currentMillis - startMillis > 10000)        /// did we collect XmL? if not, go to next stage after X millis
    state = PausingState;
  else

    PumpForward();

  break;

case PausingState:
  if (currentMillis - startMillis > 13000)   // Have we been in this state too long?
    state = ReverseState;
  else
    pumpOff();
  Serial.println("PAUSE!");
  lcd.setCursor(0, 0);
  lcd.print("PAUSED! ");

  break;

case ReverseState:
  if (currentMillis - startMillis > 23000) // Have we been in this state too long?
    state = RestState;//state++;
  else
    PumpReverse();

  break;

case RestState:
  if (currentMillis - startMillis > 30000)  // has it been X minutes?
  {

    state = FullState;
    startMillis = currentMillis;            // Reset the start time of the pumping sequence.
    totalMilliLitres = 0;                  //reset totalMilliLitres so it can start counting up from 0 again

  }
  else
    pumpOff();
  Serial.println("REST!");
  lcd.setCursor(0, 0);
  lcd.print("RESTING!");
  if (Threshold < vol && ThresholdLimit == false)
    ThresholdLimit = true;
  break;

case FullState:
  if (ThresholdLimit = true ||  (digitalRead(buttonPin) == HIGH))
    state = OffState;

  else
    Serial.println(state);
  state = PumpState;
  break;

} /*SMS ALERTS*****/ if (buttonState == HIGH && lastButtonState == LOW || vol > 300 && vol - flowMilliLitres <= 300) { opened = false; lastButtonState = buttonState; FullSMS (); pumpOff(); lcd.setCursor(0, 0); lcd.print("FULL "); }

if (tempF < tLimit && cold == false) { ColdSMS (); cold = true; } else if (tempF > tLimit + 2.0 && cold == true) { cold = false; } if (percent < bLimit && bat == false) { batSMS (); bat = true; } /*SMS ALERTS END*****/ /**** DATA POST TO DWEET *****/ if (millis() - counter > samplingRate) { PostData (); counter = millis (); } }

void Full() { lcd.setCursor (0, 0); lcd.print("FULL"); digitalWrite(DRV8876_IN1_PIN, LOW); digitalWrite(DRV8876_IN2_PIN, LOW); }

void manualMode() { digitalWrite(DRV8876_IN1_PIN, HIGH); // comment is obsolete code epxlains ITSELF Turn on the pump (forward). digitalWrite(DRV8876_IN2_PIN, LOW); // Serial.println("PUMPING!"); lcd.setCursor(0, 0); lcd.print("PUMPING!"); }

void manualPurge() { digitalWrite(DRV8876_IN1_PIN, LOW); // comment is obsolete code epxlains ITSELF Turn on the pump (forward). digitalWrite(DRV8876_IN2_PIN, HIGH); // Serial.println("PUMPING!"); lcd.setCursor(0, 0); lcd.print("PURGING!"); }

// senseful SUB-unit of code with a SELF-explaining name void PumpForward() { digitalWrite(DRV8876_IN1_PIN, HIGH); // comment is obsolete code epxlains ITSELF Turn on the pump (forward). digitalWrite(DRV8876_IN2_PIN, LOW); // Serial.println("PUMPING!"); lcd.setCursor(0, 0); lcd.print("PUMPING!"); }

void resetData() { currentMillis = millis(); startMillis = currentMillis; cloopTime = currentMillis; totalMilliLitres = 0; flowRate = 0; vol = 0; flowMilliLitres = 0; // ThresholdLimit = false; Serial.println("Data Reset"); lcd.setCursor(0, 2); lcd.print(vol); lcd.setCursor(1, 2); lcd.print(" "); pulseCount = 0; } // senseful SUB-unit of code with a SELF-explaining name void PumpReverse() { digitalWrite(DRV8876_IN1_PIN, LOW); // comment is obsolete code epxlains ITSELF Reverse the pump. digitalWrite(DRV8876_IN2_PIN, HIGH); Serial.println("PURGING!"); lcd.setCursor(0, 0); lcd.print("PURGING!"); }

// senseful SUB-unit of code with a SELF-explaining name void pumpOff() { digitalWrite(DRV8876_IN1_PIN, LOW); digitalWrite(DRV8876_IN2_PIN, LOW); lcd.setCursor(0, 0); lcd.print("PUMP OFF"); }

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; }

}

// 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); } }

// 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() { // SIM7000 takes about 3s to turn on and SIM7500 takes about 15s // Press Arduino reset button if the module is still turning on and the board doesn't find it. // When the module is on it should communicate right after pressing reset

// Software serial: fonaSS.begin(115200, SERIAL_8N1, FONA_TX, FONA_RX); // baud rate, protocol, ESP32 RX pin, ESP32 TX pin

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, SERIAL_8N1, FONA_TX, FONA_RX); // Switch to 9600 if (! fona.begin(fonaSS)) { Serial.println(F("Couldn't find FONA")); while (1); // Don't proceed if it couldn't find the device }

// Hardware serial: /* fonaSerial->begin(115200); // Default SIM7000 baud rate

if (! fona.begin(*fonaSerial)) {
DEBUG_PRINTLN(F("Couldn't find SIM7000"));
}

*/

// The commented block of code below is an alternative that will find the module at 115200 // Then switch it to 9600 without having to wait for the module to turn on and manually // press the reset button in order to establish communication. However, once the baud is set // this method will be much slower. / fonaSerial->begin(115200); // Default LTE shield baud rate fona.begin(fonaSerial); // Don't use if statement because an OK reply could be sent incorrectly at 115200 baud

Serial.println(F("Configuring to 9600 baud"));
fona.setBaudrate(9600); // Set to 9600 baud
fonaSerial->begin(9600);
if (!fona.begin(*fonaSerial)) {
Serial.println(F("Couldn't find modem"));
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 SIM800L: Serial.println(F("SIM800L")); break; case SIM800H: Serial.println(F("SIM800H")); break; case SIM808_V1: Serial.println(F("SIM808 (v1)")); break; case SIM808_V2: Serial.println(F("SIM808 (v2)")); break; case SIM5320A: Serial.println(F("SIM5320A (American)")); break; case SIM5320E: Serial.println(F("SIM5320E (European)")); break; case SIM7000: Serial.println(F("SIM7000")); break; case SIM7070: Serial.println(F("SIM7070")); break; case SIM7500: Serial.println(F("SIM7500")); break; case SIM7600: Serial.println(F("SIM7600")); 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 FullSMS () { char message3[20];

strcpy(message3, volBuff); strcat(message3, text_message1);

pinMode(FONA_RST, OUTPUT); digitalWrite(FONA_RST, HIGH); // Default state pinMode(FONA_PWRKEY, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); 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, message3)) { Serial.println(F("Failed to send text!")); } else { Serial.println(F("Sent text alert!")); } }

void ColdSMS () { char message[20];

strcpy(message, tempBuff); strcat(message, text_message2); 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 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, message)) { Serial.println(F("Failed to send text!")); } else { Serial.println(F("Sent text alert!")); } }

void batSMS () { char message2[25];

strcpy(message2, batBuff); strcat(message2, text_message3); 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 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, message2)) { Serial.println(F("Failed to send text!")); } else { Serial.println(F("Sent text alert!")); } }

void PostData () { // If the shield was already on, no need to re-enable

if defined(turnOffShield) && !defined(SIMCOM_3G) && !defined(SIMCOM_7500) && !defined(SIMCOM_7600)

// Disable GPRS just to make sure it was actually off so that we can turn it on if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

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

endif

// Post something like temperature and battery level to the web API // Construct URL and post the data to the web API

// Format the floating point numbers

// Also construct a combined, comma-separated location array // (many platforms require this for dashboards, like Adafruit IO): //sprintf(locBuff, "%s,%s,%s,%s", speedBuff, latBuff, longBuff, altBuff); // This could look like "10,33.123456,-85.123456,120.5"

// Construct the appropriate URL's and body, depending on request type // In this example we use the IMEI as device ID

ifdef PROTOCOL_HTTP_GET

// GET request

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

if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)

// You can adjust the contents of the request if you don't need certain things like speed, altitude, etc. sprintf(URL, "GET /dweet/for/%s?temp=%s&bat=%s&vol=%s HTTP/1.1\r\nHost: dweet.io\r\n\r\n", imei, tempBuff, batBuff, volBuff);

// Try a total of three times if the post was unsuccessful (try additional 2 times) while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL)) { // Server, port, connection type, URL Serial.println(F("Failed to complete HTTP/HTTPS request...")); counter++; // Increment counter delay(1000); }

else

sprintf(URL, "http://dweet.io/dweet/for/%s?temp=%s&bat=%s&vol=%s", imei, tempBuff, batBuff, volBuff);

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

endif

elif defined(PROTOCOL_HTTP_POST)

// You can also do a POST request instead

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

if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)

sprintf(body, "{\"lat\":%s,\"long\":%s}\r\n", latBuff, longBuff); // Terminate with CR+NL sprintf(URL, "POST /dweet/for/%s HTTP/1.1\r\nHost: dweet.io\r\nContent-Length: %i\r\n\r\n", imei, strlen(body));

while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL, body)) { // Server, port, connection type, URL Serial.println(F("Failed to complete HTTP/HTTPS request...")); counter++; // Increment counter delay(1000); }

else

sprintf(URL, "http://dweet.io/dweet/for/%s", imei); sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff);

// Let's try a POST request to thingsboard.io // Please note this can me memory-intensive for the Arduino Uno // and may not work. You might have to split it up into a couple requests // and send part of the data in one request, and the rest in the other, etc. // Perhaps an easier solution is to swap out the Uno with an Arduino Mega. / const char token = "qFeFpQIC9C69GDFLWdAv"; // From thingsboard.io device sprintf(URL, "http://demo.thingsboard.io/api/v1/%s/telemetry", token); sprintf(body, "{\"lat\":%s,\"long\":%s,\"speed\":%s,\"head\":%s,\"alt\":%s,\"temp\":%s,\"batt\":%s}", latBuff, longBuff, speedBuff, headBuff, altBuff, tempBuff, battBuff); // sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff); // If all you want is lat/long */

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

endif

endif

//Only run the code below if you want to turn off the shield after posting data

ifdef turnOffShield

// Disable GPRS // Note that you might not want to check if this was successful, but just run it // since the next command is to turn off the module anyway if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

// Turn off GPS if (!fona.enableGPS(false)) Serial.println(F("Failed to turn off GPS!"));

// Power off the module. Note that you could instead put it in minimum functionality mode // instead of completely turning it off. Experiment different ways depending on your application! // You should see the "PWR" LED turn off after this command // if (!fona.powerDown()) Serial.println(F("Failed to power down FONA!")); // No retries counter = 0; while (counter < 3 && !fona.powerDown()) { // Try shutting down Serial.println(F("Failed to power down FONA!")); counter++; // Increment counter delay(1000); }

endif

// Alternative to the AT command method above: // If your FONA has a PWRKEY pin connected to your MCU, you can pulse PWRKEY // LOW for a little bit, then pull it back HIGH, like this: // digitalWrite(PWRKEY, LOW); // delay(600); // Minimum of 64ms to turn on and 500ms to turn off for FONA 3G. Check spec sheet for other types // delay(1300); // Minimum of 1.2s for SIM7000 // digitalWrite(PWRKEY, HIGH);

// Shut down the MCU to save power

ifndef samplingRate

Serial.println(F("Shutting down...")); delay(5); // This is just to read the response of the last AT command before shutting down MCU_powerDown(); // You could also write your own function to make it sleep for a certain duration instead

else

// // The following lines are for if you want to periodically post data (like GPS tracker) // Serial.print(F("Waiting for ")); Serial.print(samplingRate); Serial.println(F(" seconds\r\n")); // delay(samplingRate * 1000UL); // Delay

// Only run the initialization again if the module was powered off // since it resets back to 115200 baud instead of 4800.

ifdef turnOffShield

fona.powerOn(FONA_PWRKEY); // Powers on the module if it was off previously moduleSetup();

endif

endif

}

— Reply to this email directly, view it on GitHubhttps://github.com/botletics/SIM7000-LTE-Shield/issues/317, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJQ2DEQNYSG75MZ5GN2OIGLWL7ZUVANCNFSM6AAAAAASWH2K2E. You are receiving this because you are subscribed to this thread.Message ID: @.***>

alejandrog1994 commented 1 year ago

Thanks for the help, I did what you did by doing the following

// Turn on GPRS
  while (!fona.enableGPRS(true) &&(millis() < 30000)) {
    Serial.println(F("Failed to enable GPRS, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Enabled GPRS!"));
#endif
#endif

I added this same millis delay to the following functions

void FullSMS () {
  char message3[20];

  strcpy(message3, volBuff);
  strcat(message3, text_message1);

  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  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()&&(millis() < 30000)) {
    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, message3)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void ColdSMS () {
  char message[20];

  strcpy(message, tempBuff);
  strcat(message, text_message2);
  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
  while (!netStatus()&&(millis() < 30000)) {
    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, message)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void batSMS () {
  char message2[25];

  strcpy(message2, batBuff);
  strcat(message2, text_message3);
  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
  while (!netStatus()&&(millis() < 30000)) {
    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, message2)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }
}

void PostData ()
{
  // If the shield was already on, no need to re-enable
#if defined(turnOffShield) && !defined(SIMCOM_3G) && !defined(SIMCOM_7500) && !defined(SIMCOM_7600)
  // Disable GPRS just to make sure it was actually off so that we can turn it on
  if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

  // Turn on GPRS
  while (!fona.enableGPRS(true)&&(millis() < 30000)) {
    Serial.println(F("Failed to enable GPRS, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Enabled GPRS!"));
#endif

  // Post something like temperature and battery level to the web API
  // Construct URL and post the data to the web API

  // Format the floating point numbers

  // Also construct a combined, comma-separated location array
  // (many platforms require this for dashboards, like Adafruit IO):
  //sprintf(locBuff, "%s,%s,%s,%s", speedBuff, latBuff, longBuff, altBuff); // This could look like "10,33.123456,-85.123456,120.5"

  // Construct the appropriate URL's and body, depending on request type
  // In this example we use the IMEI as device ID

#ifdef PROTOCOL_HTTP_GET
  // GET request

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

#if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)
  // You can adjust the contents of the request if you don't need certain things like speed, altitude, etc.
  sprintf(URL, "GET /dweet/for/%s?temp=%s&bat=%s&vol=%s HTTP/1.1\r\nHost: dweet.io\r\n\r\n",
          imei, tempBuff, batBuff, volBuff);

  // Try a total of three times if the post was unsuccessful (try additional 2 times)
  while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL)) { // Server, port, connection type, URL
    Serial.println(F("Failed to complete HTTP/HTTPS request..."));
    counter++; // Increment counter
    delay(1000);
  }
#else
  sprintf(URL, "http://dweet.io/dweet/for/%s?temp=%s&bat=%s&vol=%s", imei, tempBuff, batBuff, volBuff);

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

#elif defined(PROTOCOL_HTTP_POST)
  // You can also do a POST request instead

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

#if defined(SIMCOM_3G) || defined(SIMCOM_7500) || defined(SIMCOM_7600)
  sprintf(body, "{\"lat\":%s,\"long\":%s}\r\n", latBuff, longBuff); // Terminate with CR+NL
  sprintf(URL, "POST /dweet/for/%s HTTP/1.1\r\nHost: dweet.io\r\nContent-Length: %i\r\n\r\n", imei, strlen(body));

  while (counter < 3 && !fona.postData("www.dweet.io", 443, "HTTPS", URL, body)) { // Server, port, connection type, URL
    Serial.println(F("Failed to complete HTTP/HTTPS request..."));
    counter++; // Increment counter
    delay(1000);
  }
#else
  sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
  sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff);

  // Let's try a POST request to thingsboard.io
  // Please note this can me memory-intensive for the Arduino Uno
  // and may not work. You might have to split it up into a couple requests
  // and send part of the data in one request, and the rest in the other, etc.
  // Perhaps an easier solution is to swap out the Uno with an Arduino Mega.
  /*
    const char * token = "qFeFpQIC9C69GDFLWdAv"; // From thingsboard.io device
    sprintf(URL, "http://demo.thingsboard.io/api/v1/%s/telemetry", token);
    sprintf(body, "{\"lat\":%s,\"long\":%s,\"speed\":%s,\"head\":%s,\"alt\":%s,\"temp\":%s,\"batt\":%s}", latBuff, longBuff,
          speedBuff, headBuff, altBuff, tempBuff, battBuff);
    //  sprintf(body, "{\"lat\":%s,\"long\":%s}", latBuff, longBuff); // If all you want is lat/long
  */

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

#endif

  //Only run the code below if you want to turn off the shield after posting data
#ifdef turnOffShield
  // Disable GPRS
  // Note that you might not want to check if this was successful, but just run it
  // since the next command is to turn off the module anyway
  if (!fona.enableGPRS(false)) Serial.println(F("Failed to disable GPRS!"));

  // Turn off GPS
  if (!fona.enableGPS(false)) Serial.println(F("Failed to turn off GPS!"));

  // Power off the module. Note that you could instead put it in minimum functionality mode
  // instead of completely turning it off. Experiment different ways depending on your application!
  // You should see the "PWR" LED turn off after this command
  //  if (!fona.powerDown()) Serial.println(F("Failed to power down FONA!")); // No retries
  counter = 0;
  while (counter < 3 && !fona.powerDown()) { // Try shutting down
    Serial.println(F("Failed to power down FONA!"));
    counter++; // Increment counter
    delay(1000);
  }
#endif

  // Alternative to the AT command method above:
  // If your FONA has a PWRKEY pin connected to your MCU, you can pulse PWRKEY
  // LOW for a little bit, then pull it back HIGH, like this:
  //  digitalWrite(PWRKEY, LOW);
  //  delay(600); // Minimum of 64ms to turn on and 500ms to turn off for FONA 3G. Check spec sheet for other types
  //  delay(1300); // Minimum of 1.2s for SIM7000
  //  digitalWrite(PWRKEY, HIGH);

  // Shut down the MCU to save power
#ifndef samplingRate
  Serial.println(F("Shutting down..."));
  delay(5); // This is just to read the response of the last AT command before shutting down
  MCU_powerDown(); // You could also write your own function to make it sleep for a certain duration instead
#else
  //  // The following lines are for if you want to periodically post data (like GPS tracker)
  //  Serial.print(F("Waiting for ")); Serial.print(samplingRate); Serial.println(F(" seconds\r\n"));
  //  delay(samplingRate * 1000UL); // Delay

  // Only run the initialization again if the module was powered off
  // since it resets back to 115200 baud instead of 4800.
#ifdef turnOffShield
  fona.powerOn(FONA_PWRKEY); // Powers on the module if it was off previously
  moduleSetup();
#endif

#endif
}

and I also did what botletics recommended by commenting out the line of code he mentions. Now the program runs without being stuck, but there functions which use the FONA are causing small issues. While they dont necessarily block the program, when the functions are triggered it freezes all other functions until the 30 seconds have passed. is there a way to modify the code to where if the SIM7000 is not found, the ESP32 will not do the functions that depend on the SIM7000? I'm thinking something like

 if fona is not found, dont do this 
  /***************************SMS ALERTS***************************************************/
  if (buttonState == HIGH && lastButtonState == LOW || vol > 3100 && vol - flowMilliLitres <= 3100) {
    opened = false;
    ThresholdLimit = true;
    lastButtonState = buttonState;
    FullSMS ();
    pumpOff();
    lcd.setCursor(0, 0);
    lcd.print("FULL          ");
  }

  if (tempF < tLimit && cold == false) {
    ColdSMS ();
    cold = true;
  }
  else if (tempF > tLimit + 2.0 && cold == true) {
    cold = false;
  }
  if (percent < bLimit && bat == false) {
    batSMS ();
    bat = true;
  }
  /***************************SMS ALERTS END***************************************************/
  /**************************** DATA POST TO DWEET *********************************************/
  if (millis() - counter > samplingRate) {
    PostData ();
    counter = millis ();
  }
}

please advise