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
}