Water Level Indicator Using SR04T-V3.0

Hello everyone!
I am new to this forum page
I was making a project that is smart level water indicator in which i am using arduino UNO and a 16x2 LiquidcrytsalI2C display and also a JSN SR04T-v3.0 Waterproof Ultrasonic sensor so i want to basically measure the water level in the tank and want to cut off from the motor when the level reaches 100% and so the main problem is i have written a code that i will also provide here but the readings are not accurate and the value differs , i want a help from this forum to please rectify my code or provide me a sampe code that works like the same
Thank You

The Code

#include <LiquidCrystal_I2C.h>
#include <NewPing.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the LCD with its address and dimensions
const int trigPin = 3; // Ultrasonic sensor trig pin
const int echoPin = 2; // Ultrasonic sensor echo pin
const int setVolume = 500; // Set value for tank volume in centimeters
const float tankHeight = 200.0; // Height of the tank in centimeters (adjust as needed)
bool kelvinDisplayed = false; // Flag to track if Kelvin Electronics animation has been displayed

NewPing sonar(trigPin, echoPin, tankHeight); // Initialize the NewPing instance with the sensor pins and tank height

void setup() {
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
Serial.begin(9600); // Initialize serial communication for debugging
}

void loop() {
// Check if Kelvin Electronics animation has been displayed
if (!kelvinDisplayed) {
// Slide "Kelvin Electronics" animation once
slideAnimation("Kelvin Electronics ");
kelvinDisplayed = true; // Set flag to true after displaying animation
}

// Measure distance using ultrasonic sensor and display PV, SV, and percentage values
measureAndDisplay();

}

void slideAnimation(String text) {
// Slide "Kelvin Electronics" animation once
for (int i = 0; i <= text.length() + 16; i++) {
// Clear the display buffer
lcd.clear();
// Calculate the starting position for the text
int startPos = max(0, i - 16); // Ensure text starts at column 0
String displayText = text.substring(startPos, min(i, text.length())); // Extract text to display
// Set cursor to the beginning of the first row
lcd.setCursor(0, 0);
// Print the text on the LCD
lcd.print(displayText);
// Delay for smooth scrolling
delay(150);
}
}

void measureAndDisplay() {
// Measure distance using ultrasonic sensor
unsigned int distance = sonar.ping_cm();
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");

// Calculate percentage of SV value
float svPercentage = (distance / tankHeight) * 100;

// Display PV (Set Value) and SV (Process Variable) in centimeters
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PV: ");
lcd.print(setVolume);
lcd.print("cm");

lcd.setCursor(0, 1);
lcd.print("SV: ");
lcd.print(distance);
lcd.print("cm");

// Display SV Percentage
lcd.setCursor(10, 1);
lcd.print("SV%: ");
lcd.print(svPercentage);
lcd.print("%");

// Delay before repeating the loop
delay(1000); // Adjust delay as needed

}

Here the Pv is fixed value and it is the set volume and SV is the value from the sensor and then i want to show the percentage level too

First you need to post your code so we can read it
In the IDE, go to the Menu, select Edit and click on Copy for Forum.
Then paste your code here.

A wiring diagram of how you have thing connected would also be a big help

#include <LiquidCrystal_I2C.h>
#include <NewPing.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the LCD with its address and dimensions
const int trigPin = 3; // Ultrasonic sensor trig pin
const int echoPin = 2; // Ultrasonic sensor echo pin
const int setVolume = 500; // Set value for tank volume in centimeters
const float tankHeight = 200.0; // Height of the tank in centimeters (adjust as needed)
bool kelvinDisplayed = false; // Flag to track if Kelvin Electronics animation has been displayed

NewPing sonar(trigPin, echoPin, tankHeight); // Initialize the NewPing instance with the sensor pins and tank height

void setup() {
    lcd.init();       // Initialize the LCD
    lcd.backlight();  // Turn on the backlight
    Serial.begin(9600); // Initialize serial communication for debugging
}

void loop() {
    // Check if Kelvin Electronics animation has been displayed
    if (!kelvinDisplayed) {
        // Slide "Kelvin Electronics" animation once
        slideAnimation("Kelvin Electronics ");
        kelvinDisplayed = true; // Set flag to true after displaying animation
    }

    // Measure distance using ultrasonic sensor and display PV, SV, and percentage values
    measureAndDisplay();
}

void slideAnimation(String text) {
    // Slide "Kelvin Electronics" animation once
    for (int i = 0; i <= text.length() + 16; i++) {
        // Clear the display buffer
        lcd.clear();
        // Calculate the starting position for the text
        int startPos = max(0, i - 16); // Ensure text starts at column 0
        String displayText = text.substring(startPos, min(i, text.length())); // Extract text to display
        // Set cursor to the beginning of the first row
        lcd.setCursor(0, 0);
        // Print the text on the LCD
        lcd.print(displayText);
        // Delay for smooth scrolling
        delay(150);
    }
}

void measureAndDisplay() {
    // Measure distance using ultrasonic sensor
    unsigned int distance = sonar.ping_cm();
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
    
    // Calculate percentage of SV value
    float svPercentage = (distance / tankHeight) * 100;

    // Display PV (Set Value) and SV (Process Variable) in centimeters
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("PV: ");
    lcd.print(setVolume);
    lcd.print("cm");

    lcd.setCursor(0, 1);
    lcd.print("SV: ");
    lcd.print(distance);
    lcd.print("cm");

    // Display SV Percentage
    lcd.setCursor(10, 1);
    lcd.print("SV%: ");
    lcd.print(svPercentage);
    lcd.print("%");

    // Delay before repeating the loop
    delay(1000); // Adjust delay as needed
}

Much bettor
Thanks

1 Like

i have connected my
Trig - Digital 3
Echo - digital 2
Gnd - Gnd
5V - 5V
Model - JSN SR04T-V3.0
If u want i can provide u the wiring for my I2C too

If the LCD works then it's not necessary.
Is this "Kelvin Electronics" animation necessary?
I see no mention of a motor in the code.

What are the dimentions of the tank?

Yes the animation is necessary at the starting only for a few seconds and the display works fine , right now i havent used a motor it will be in the phase 2 of the project, right now only the measurement of the water is important
The dimension are like it will be a 500 L tank and its a cylindrical tank

What is the diameter and height?

The dimension are 86x92cm

That may be a problem with the sensor you are using because it has a very wide sonic beam and you will get false echos from the wall of the tank
Try putting this statement in you code right before NewPing sonar(trigPin, echoPin, tankHeight);

#define TRIGGER_WIDTH 20

#include <LiquidCrystal_I2C.h>
#include <NewPing.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the LCD with its address and dimensions
const int trigPin = 3; // Ultrasonic sensor trig pin
const int echoPin = 2; // Ultrasonic sensor echo pin
const int setVolume = 500; // Set value for tank volume in centimeters
const float tankHeight = 200.0; // Height of the tank in centimeters (adjust as needed)
bool kelvinDisplayed = false; // Flag to track if Kelvin Electronics animation has been displayed
#define TRIGGER_WIDTH 20

NewPing sonar(trigPin, echoPin, tankHeight); // Initialize the NewPing instance with the sensor pins and tank height

void setup() {
    lcd.init();       // Initialize the LCD
    lcd.backlight();  // Turn on the backlight
    Serial.begin(9600); // Initialize serial communication for debugging
}

void loop() {
    // Check if Kelvin Electronics animation has been displayed
    if (!kelvinDisplayed) {
        // Slide "Kelvin Electronics" animation once
        slideAnimation("Kelvin Electronics ");
        kelvinDisplayed = true; // Set flag to true after displaying animation
    }

    // Measure distance using ultrasonic sensor and display PV, SV, and percentage values
    measureAndDisplay();
}

void slideAnimation(String text) {
    // Slide "Kelvin Electronics" animation once
    for (int i = 0; i <= text.length() + 16; i++) {
        // Clear the display buffer
        lcd.clear();
        // Calculate the starting position for the text
        int startPos = max(0, i - 16); // Ensure text starts at column 0
        String displayText = text.substring(startPos, min(i, text.length())); // Extract text to display
        // Set cursor to the beginning of the first row
        lcd.setCursor(0, 0);
        // Print the text on the LCD
        lcd.print(displayText);
        // Delay for smooth scrolling
        delay(150);
    }
}

void measureAndDisplay() {
    // Measure distance using ultrasonic sensor
    unsigned int distance = sonar.ping_cm();
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
    
    // Calculate percentage of SV value
    float svPercentage = (distance / tankHeight) * 100;

    // Display PV (Set Value) and SV (Process Variable) in centimeters
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("PV: ");
    lcd.print(setVolume);
    lcd.print("cm");

    lcd.setCursor(0, 1);
    lcd.print("SV: ");
    lcd.print(distance);
    lcd.print("cm");

    // Display SV Percentage
    lcd.setCursor(10, 1);
    lcd.print("SV%: ");
    lcd.print(svPercentage);
    lcd.print("%");

    // Delay before repeating the loop
    delay(1000); // Adjust delay as needed
}

i have made the changes but
iam getting distance as 0 cm

Some people have reported problems with the NewPing library
Try this code:
It does not have the LCD stuff but see if the accuracy is bettor

const int TRIG_PIN = 3;
const int ECHO_PIN = 2;
float speed_Of_Sound;
float distance_Per_uSec;  // Distance sound travels in one microsecond

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  digitalWrite(TRIG_PIN, LOW);
  
  Serial.begin(9600);
  
  speed_Of_Sound = 331.3; // Meters/sec
  // Calculate the distance that sound travels in one microsecond in centimeters
  distance_Per_uSec = speed_Of_Sound / 10000.0;
}

//===============================================================================
//  Main
//===============================================================================

void loop() {
  float duration, distanceCm, distanceIn;

  digitalWrite(TRIG_PIN, HIGH);       // Set trigger pin HIGH
  delayMicroseconds(20);              // Hold pin HIGH for 20 uSec
  digitalWrite(TRIG_PIN, LOW);        // Return trigger pin back to LOW again.
  duration = pulseIn(ECHO_PIN, HIGH); // Measure time in uSec for echo to come

  // convert the time data into a distance in centimeters and inches
  duration = duration / 2.0;  // Divide echo time by 2 to get time in one direction
  distanceCm = duration * distance_Per_uSec;
  distanceIn = distanceCm / 2.54;

  if (distanceCm <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print(duration, 0);
    Serial.print("uSec, ");
    Serial.print(distanceCm, 0);
    Serial.print("cm,  ");
    Serial.print(distanceIn, 0);
    Serial.print("in, ");
    Serial.println();
  }
  delay(1000);  // Delay between readings
}

the code u provide me is giving me this output

Sorry
duration should have been unsigned long

const int TRIG_PIN = 3;
const int ECHO_PIN = 2;
float speed_Of_Sound;
float distance_Per_uSec;  // Distance sound travels in one microsecond

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  digitalWrite(TRIG_PIN, LOW);
  
  Serial.begin(9600);
  
  speed_Of_Sound = 331.3; // Meters/sec
  // Calculate the distance that sound travels in one microsecond in centimeters
  distance_Per_uSec = speed_Of_Sound / 10000.0;
}

//===============================================================================
//  Main
//===============================================================================

void loop() {
  float distanceCm, distanceIn;
  unsigned long duration;

  digitalWrite(TRIG_PIN, HIGH);       // Set trigger pin HIGH
  delayMicroseconds(20);              // Hold pin HIGH for 20 uSec
  digitalWrite(TRIG_PIN, LOW);        // Return trigger pin back to LOW again.
  duration = pulseIn(ECHO_PIN, HIGH); // Measure time in uSec for echo to come

  // convert the time data into a distance in centimeters and inches
  duration = duration >> 1;  // Divide echo time by 2 to get time in one direction
  distanceCm = float(duration) * distance_Per_uSec;
  distanceIn = distanceCm / 2.54;

  if (distanceCm <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print(duration);
    Serial.print("uSec, ");
    Serial.print(distanceCm, 0);
    Serial.print("cm,  ");
    Serial.print(distanceIn, 0);
    Serial.print("in, ");
    Serial.println();
  }
  delay(1000);  // Delay between readings
}

heyyy it is giving me the same output of out of range when i see it in serial mnitor

But you say your original code using NewPing worked, just not accurate?

the code you provided me didnt work as i copy pasted ur code as it is still the same output

There is some problem with these sensors (don't know about your ver.3).
Have you tried NewPing library example with sensor out of container?

yes i have used
but can u help me providing any sample code that will be helpful

https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home