Water level sensor help needed

Hello there,

I am in process of making a remote water tank monitoring system. ( I have just installed frizzing and will update this topic later with the circuit diagram. I am very new to arduino (read 1 week since I have received my first Nano and started tinkering)

Suffice to say, from a hardware perspective all is working and correctly connected. as I get the SMS messages.

Textually, this is the function of the project.

Components Used.

LC1BD04
The water in the tank is monitored by means of a LC1BD04 sensor. This sensor sets a pin to High when the water is detected, and LOW when no water is detected. I have chosen for this sensor above the UltraSonic sensor and Pressure sensors for various reasons. suffice to say, I have thought this through.

SIM800L
This is used to send sms messages to me regarding the water level as measured by LC1BD04. it is connected to a laboratory power supply at the moment, and receiving sms messages, so power is not a problem.

DS1307
This RTC is used to send a message at a specific time. in this case 08:00 in the morning.

This is the idea.
The water is measured constantly. when there is a change in status of the water tank the LC1BD04 will set the pin value accordingly, and a sms is sent to a predefined number with SIM800. In addition to the status change messages, there will be a SMS sent every morning at a predefined time with the status of the tank at that point in time.

Here is the code that I have currently:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <RTClib.h>

SoftwareSerial mySerial(6, 5); // RX D6 closest to earth on GSM Module, TX

int prevPin10 = LOW;
int prevPin11 = LOW;
int prevPin12 = LOW;
int prevPin13 = LOW;

char phone_number[] = "+31615553214"; // Replace with your phone number
char message[150];

RTC_DS1307 rtc;

void setup() {
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);

  Serial.begin(9600);
  mySerial.begin(9600); // Initialize the software serial communication with the GSM module
  Wire.begin(); // Initialize the I2C bus
  rtc.begin(); // Initialize the RTC module
}

void loop() {//Read the digital pin values. If the PIN=HIGH then there is water.
  int pin10 = digitalRead(10);// This is the Quarter Pin. on the Hardware Pin 10
  int pin11 = digitalRead(11);// This is the Half Pin. on the Hardware Pin 11
  int pin12 = digitalRead(12);// This is the Three Quarter Pin. on the Hardware Pin 12
  int pin13 = digitalRead(13);// This is the full Pin. on the Hardware Pin 13
 
 //Debug infomration to get pin status
  //Serial.println(pin10);
  //Serial.println(pin11);
  //Serial.println(pin12);
  //Serial.println(pin13);
  //Serial.println("");
  
  if (pin13 == HIGH && pin12 == HIGH && pin11 == HIGH && pin10 == HIGH) {
    sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d] Tank is full", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  } else if (pin13 == LOW && pin12 == HIGH && pin11 == HIGH && pin10 == HIGH) {
    sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d] Tank is three quarter", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  } else if (pin13 == LOW && pin12 == LOW && pin11 == HIGH && pin10 == HIGH) {
    sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d] Tank half", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  } else if (pin13 == LOW && pin12 == LOW && pin11 == LOW && pin10 == HIGH) {
    sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d] Tank is quarter", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  } else if (pin13 == LOW && pin12 == LOW && pin11 == LOW && pin10 == LOW) {
    sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d] Tank is empty", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
   } else 
   {

   }
 //Serial.println(message);

 // Check if the status has changed,
  if (pin10 != prevPin10 || pin11 != prevPin11 || pin12 != prevPin12 || pin13 != prevPin13) {
    //sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d]", rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  Serial.println(message); // Print the message to the serial monitor

      // Send an SMS
    mySerial.println("AT+CMGF=1"); // Set the SMS mode to text mode
    delay(100);
    mySerial.print("AT+CMGS=\"");
    mySerial.print(phone_number);
    mySerial.println("\""); // Set the phone number
    delay(100);
    mySerial.println(message); // Set the SMS message
    delay(100);
    mySerial.println((char)26); // Send the SMS message
    delay(1000);

     //Check if the SMS was sent successfully
    if (mySerial.find("OK")) {
      Serial.println("Message sent successfully!");
    } else {
      Serial.println("Error sending message");
    }
//Set new Water level Values to default 
    prevPin10 = pin10;
    prevPin11 = pin11;
    prevPin12 = pin12;
    prevPin13 = pin13;

    Serial.println("Delay after SMS being sent for 10 Minutes");
    delay(600000); // Wait for 10 minutes before checking again
  }
    Serial.println("Delay for 20 Minutes on no change");
    delay(1200000);

// Check if it's 8 in the morning
DateTime now = rtc.now();
if ((now.hour() == 8 )) {
 //sprintf(message, "[%04d-%02d-%02d %02d:%02d:%02d]",  rtc.now().year(), rtc.now().month(), rtc.now().day(), rtc.now().hour(), rtc.now().minute(), rtc.now().second());
  Serial.println(message);

  
    // Send an SMS
    //mySerial.println("AT+CMGF=1"); // Set the SMS mode to text mode
    //delay(100);
    //mySerial.print("AT+CMGS=\"");
    //mySerial.print(phone_number);
    //mySerial.println("\""); // Set the phone number
    //delay(100);
    //mySerial.println(message); // Set the SMS message
    //delay(100);
    //mySerial.println((char)26); // Send the SMS message
    //delay(1000);

     //Check if the SMS was sent successfully
    if (mySerial.find("OK")) {
      Serial.println("Message sent successfully!");
    } else {
      Serial.println("Error sending message");
      Serial.println("Timestamp sms have just been sent");
    }
//Set new Water level Values to default 
    prevPin10 = pin10;
    prevPin11 = pin11;
    prevPin12 = pin12;
    prevPin13 = pin13;

 Serial.println("Delay after Daily SMS of 23 hours 58 min before checking Time again");
    delay(3540000); // Wait for 59 min minutes before checking again
  }
}

Problems I need help with.
This morning I did not get my morning message as expected. My nano was connected to the PC for power, but Arduino IDE was closed. AS soon as I connected the IDE I received a text, which seems to indicate hardware wise it seems to be functioning correctly,
1a. I only get the messages when the nano is connected by USB to the PC. could it be that the code is not stored in the Nano?
1b. it could also be that the Nano needs to have the serial monitor connected in order to process the code?

Notes for point 1. when the nano is connected to the IDE and it get to the specific time (08:00) the message is sent, and received.

  1. I want to ultimately connect this system to solar and batteries using 2 x 18650 lithium batteries in parallel to power the system. the challenge is that I need 7-12V for the Nano (the LC1BD04 definitely needs 5V to operate. The SIM800 needs 4V to operate. I have a solar panel (6V18W) that can charge the batteries in Parallel, so I need a DC DC boost converter to power the Nano and LC1BD04. can anyone recommend one that can be used?
1 Like

The code probably would get better if you were not using delays.

  • use the RTC to detect when to send the morning message
  • use millis() to monitor levels and level change from time to time

it won't look good. You'd better take a piece of paper, a ruler and a pencil and draw by hand using normalised components "looks" and putting labels next to the pins you use then take a picture and post the picture

Maybe because you have all the code to send SMS commented out

whahaa, perhaps you are correct. let me try that first

thank you J-m-L. I think Jim-p may have resolved the problem. :zipper_mouth_face:

yeah clearly that part is needed if you want to send the SMS :slight_smile:

I thought you had commented it out just for the purpose of playing around

may be an idea on how you could structure the code

#include <SoftwareSerial.h>
#include <RTClib.h>

SoftwareSerial sim800Serial(6, 5);                // RX D6 closest to earth on GSM Module, TX
RTC_DS1307 rtc;

const byte tank025Pin = 10;                   // This is the Quarter full Pin
const byte tank050Pin = 11;                   // This is the Half full Pin
const byte tank075Pin = 12;                   // This is the Three Quarter full Pin
const byte tank100Pin = 13;                   // This is the 100% full Pin
const size_t maxSMSLength = 150;

byte previousTankStatus = 0b11110000;         // the first time we compare it will trigger a difference and post a message
DateTime lastDailySMS(1900, 1, 1, 0, 0, 0);   // the first time we compare it will trigger a difference and post a message

void sendSMS(const char * text) {
  const char * phoneNumber = "+31615553214"; // Replace with your phone number
  char message[maxSMSLength + 1];             // +1 for the trailing null char
  DateTime now = rtc.now();
  snprintf(message, sizeof message, "[%04d-%02d-%02d %02d:%02d:%02d] %s",  now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second(), text);

  Serial.print(F("sending :"));
  Serial.println(message);
  Serial.print(F("to :"));
  Serial.println(phoneNumber);


  // Send an SMS
  char OKMessage[] = "OK";
  sim800Serial.begin(9600);                       // Initialize the software serial communication with the GSM module. start with a clean buffer
  sim800Serial.println("AT+CMGF=1"); // Set the SMS mode to text mode
  delay(100);
  sim800Serial.print("AT+CMGS=\"");
  sim800Serial.print(phoneNumber);
  sim800Serial.println("\""); // Set the phone number
  delay(100);
  sim800Serial.println(message); // Set the SMS message
  delay(100);
  sim800Serial.println((char)26); // Send the SMS message
  delay(1000);

  //Check if the SMS was sent successfully
  if (sim800Serial.find(OKMessage)) {
    Serial.println("Message sent successfully!");
  } else {
    Serial.println("Error sending message");
  }
  sim800Serial.end();                             // close the software serial line with the GSM module
}

void setStatusAndSendSMS(byte newTankStatus) {
  const char * msg = "";
  switch (newTankStatus) {
    case 0b1111: msg = "tank is at 100%";     break;
    case 0b0111: msg = "tank is at  75%";     break;
    case 0b0011: msg = "tank is at  50%";     break;
    case 0b0001: msg = "tank is at   0%";     break;
    default:     msg = "Please check sensor"; break;
  }

  sendSMS(msg);

  previousTankStatus = newTankStatus;
}

void setup() {
  pinMode(tank025Pin, INPUT);
  pinMode(tank050Pin, INPUT);
  pinMode(tank075Pin, INPUT);
  pinMode(tank100Pin, INPUT);

  Serial.begin(9600);
  Wire.begin();                               // Initialize the I2C bus
  rtc.begin();                                // Initialize the RTC module
}

void loop() {

  //Read the digital pin values. If the PIN=HIGH then there is water.
  // built a bit mask that will aggregate the different pins for easy storage and compare
  byte tankStatus = 0;
  tankStatus |= digitalRead(tank025Pin) == HIGH ? 0b0001 : 0b0000;
  tankStatus |= digitalRead(tank050Pin) == HIGH ? 0b0010 : 0b0000;
  tankStatus |= digitalRead(tank075Pin) == HIGH ? 0b0100 : 0b0000;
  tankStatus |= digitalRead(tank100Pin) == HIGH ? 0b1000 : 0b0000;

  // send a message only if there was a major change
  if (tankStatus != previousTankStatus) setStatusAndSendSMS(tankStatus);

  // now check if it's time for the daily update
  DateTime now = rtc.now();
  if ((lastDailySMS.year() != now.year()) || (lastDailySMS.month() != now.month()) || (lastDailySMS.day() != now.day())) {
    // message was not sent for today, check if it's 8am
    if (now.hour() == 8) {
      setStatusAndSendSMS(tankStatus);
      lastDailySMS = now;                       // record the message was sent for today
    }
  }
}

totally untried, typed here from your code

Holy shit. This will take me weeks to understand, but thank you. I will try the code tomorrow and give you some feedback…

Any chance i can get a bit a help, looking to do basically the same thing, but need to monitor 3 sensors for water containers in field. Looking to use cellular to connect to arduino. Just looking for guidance on which arduino/cellular unit to use if this is even possible? Looking at using 2 water temp sensors and one ambiant temp sensor. And maybe 1 output to turn light on if water temp is near freezing.

See how long the GSM takes to connect. It could be > 30 secs.

Don't use Fritzing, you will get nothing but complaints.
Draw circuit with something else.

how far apart are the units?
may be simpler and cheaper to link the units using LoRa point to point and just have one with a GSM modem regularly sending data to cloud
for example have a look at decimals-strings-and-lora/1059497

:+1: :+1: :+1:

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Thanks.. Tom.. :smiley::+1: :coffee: :australia:

Units will be anywhere from 1 - 2 miles apart

LoRa could work over those distances depending on the environment - what is it? e.g. urban with buildings, countryside with trees, etc? tests with an external antenna would be required
does the area have GSM network coverage? again tests required
if using GSM modems remember when transmitting they can require 2 or 3amps from the power supply
also the SIM800 only supports 2G which is being switched off (together with 3G) in many countries

It's for monitoring water for cattle and would be in fields with some bush around but mostly just open.

do you know if GSM works OK in the area?
have you tested a SIM800 in any of the sites?

GSM won't work as 2g/3g not available. Looking at either LoraWan or maybe Mkr Nb 1500
.
Just doing research on both. Any suggestions?

is 4G available?
not used the Mkr Nb 1500 but have used the MKR FOX 1200 which works OK with the Arduino IDE and associated libraries - maybe worth posting in the MKR 1500 forum?
Mkr Nb 1500 is a bit expensive (approx £80 in UK) compared with the TTGO LoRa32 SX1276 OLED (approx £20/£30 in UK) - the LoRa configuration could be cheaper using seperate ESP32 and LoRa modules but you then have the problem with interconnecting wires
if you go for LoRa check the frequencies for your country

Ok thanks for all the info. Will look into your suggestions