problem with CM mesuring ! ultrasonic

I finished the code for water-level device and everything work great…
I want to put more data on the display the first line (0,0) for bars, the second will be the measuring in CM (0,1)
bars work great but still have problem with CM reading
this is my code

#include <LiquidCrystal.h>
#define ECHOPIN 3             // Pin to receive echo pulse
#define TRIGPIN 4              // Pin to send trigger pulse
#define STATUSPIN 13        // Use for troubleshooting
int highWater = 30;            // high
int lowWater = 95;             // low
byte symbol[8] = {        
  B00000, 
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
};
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    
// Utility function for flashing STATUS-PIN
void flashLed(int pin, int times, int wait) {
  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);
    if (i + 1 < times) {
      delay(wait);
    }
  }
}
void setup() {
  lcd.begin(16,2);
  lcd.print("   AQUA LEVEL ");
  lcd.createChar(0, symbol);
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
  delay(3000);       // Show application name for 3 seconds.
}
void loop() {
  // Measure distance
  digitalWrite(TRIGPIN, LOW);                  
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);                  
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);                   
  int distance = pulseIn(ECHOPIN, HIGH);        
  distance= distance/58;                        
  
  // Convert measured value to value between 0-16, to display on LCD
  // Use Arduino built-in map and constrain functions
  int scaledValue = map(constrain(distance, highWater, lowWater), lowWater, highWater, 0, 16);
  lcd.clear();
  lcd.setCursor(0,0);
  while (scaledValue > 0) {
     lcd.print((char)0);
     scaledValue--;
  }
  lcd.setCursor(0, 1);
  lcd.print(scaledValue);
  lcd.print(" cm - ");
   delay(3000);  // Wait 3 seconds before measuring again. We're no hurry! :P
}

update
ok i changed things in the code, but now showing weird number it says in the display 44CM ?! what is that supposed to be !! :fearful:

#include <LiquidCrystal.h>

#define ECHOPIN 3                            // Pin to receive echo pulse
#define TRIGPIN 4                            // Pin to send trigger pulse
#define STATUSPIN 13                        // Use for troubleshooting
int highWater = 30;        // These values allow to calculate % of full
int lowWater = 95;        // SRF04 hangs above water (lower distance = more water)

byte symbol[8] = {         // Custom character for LCD display
  B00000, 
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
};

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    // Assign pins

// Utility function for flashing STATUSPIN
void flashLed(int pin, int times, int wait) {

  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);

    if (i + 1 < times) {
      delay(wait);
    }
  }
}

void setup() {
  
  lcd.begin(16,2);
  lcd.print("   AQUA LEVEL ");
  lcd.createChar(0, symbol);
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);

  delay(3000);       // Show application name for 3 seconds.

}

void loop() {
 
 long hWatherCm;
  int litres;

 
  // Measure distance
  digitalWrite(TRIGPIN, LOW);                   // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);                  // Send a 10uS high to trigger ranging
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);                   // Send pin low again
  int distance = pulseIn(ECHOPIN, HIGH);        // Read in times pulse
  distance= distance/58;                        // divide by 58 gives cm.
  
  // Convert measured value to value between 0-16, to display on LCD
  // Use Arduino built-in map and constrain functions
  int scaledValue = map(constrain(distance, highWater, lowWater), lowWater, highWater, 0, 16);
  lcd.clear();
 
  lcd.setCursor(0,0);
  while (scaledValue > 0) {
     lcd.print((char)0);
     scaledValue--;
  }
 
  lcd.setCursor(0, 1);
 
 lcd.print(distance);
  lcd.print(" cm - ");

 // litres = SUPERFICE_BASE * (hWather / 100.0) * 1000
  
  lcd.print(litres);
  lcd.print(" 95 ");


   delay(3000);  // Wait 2 seconds before measuring again. We're in no hurry!
}

Info
the high of water tank 1M
the Length of water tank 2M
the width 1M
the highest water level can be 70CM
the lowest water level 5CM
last update
everything work now :slight_smile: i was confused about numbers that’s the right number
If some can help me to convert “distance” to Liters" that’s will be great :roll_eyes:

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) returns an unsigned long and you put it in an int distance. That can cause an overflow resulting in faulty math.

Try changing distance to an unsigned long and run again.

ast update everything work now :) i was confused about numbers that's the right number If some can help me to convert "distance" to Liters" that's will be great

use the map function!

liters = map(cm, 95, 30, 10, 140);

this assumes that at 95 cm measured there is 10 liters in the tank and at 30 cm measured there is 140 liters in the tank

if cm would be a floating point number you could get some decimals by using

liters = (cm - 95.0) * (140.0 - 10.0) / (30.0 - 95.0) + 95.0

liters = (cm - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

thanks :) first step seems easy but the second! :roll_eyes:

use the map function!

liters = map(cm, 95, 30, 10, 140);

this assumes that at 95 cm measured there is 10 liters in the tank and at 30 cm measured there is 140 liters in the tank

from what i know from mathematics my tank will contain 1400L so that will be like this (cm, 95, 30, 100, 1400); :roll_eyes: ok let me use that map and i will back

what are the inner sizes of the tank?

and what is the distance between tank and distance sensor. you should calibrate/measure that once

As you convert to centimetres first you loose quite some precision! Better do the math directly on the return value of pulsein

  unsigned long duration = pulseIn(ECHOPIN, HIGH);        // Read in times pulse

  int liters = map(duration, 5510, 1750, 100, 1400);     // 5510 and 1750 are to be calibrated.

Note that the map function now maps a larger range on a smaller range so you get steps of 1 litre !

When you first convert to cm stepsize would be 65 ->1300 = steps of 20 liters.

you make me confused! witch code now :) ! i used this code

// litres  
int litres;
litres = (highWater * lowWater * distance);
lcd.print(litres);
lcd.print(" L ");

but the number not make any sense 3928L !!

I used your code like this

// litres  
unsigned long duration = pulseIn(ECHOPIN, HIGH); 
int litres;
int liters = map(distance, 5510, 1750, 100, 1400); 
lcd.print(litres);
lcd.print(" L ");

not show anything 0L flashing UPDATE i edit the code like this

// litres  
int litres  = (ECHOPIN, HIGH); 
int liters = map(distance, 5510, 1750, 100, 1400); 
lcd.print(litres);
lcd.print(" L ");

it show 1L now! hmm let me think..

// litres unsigned long duration = pulseIn(ECHOPIN, HIGH); int litres; int liters = map(distance, 5510, 1750, 100, 1400); lcd.print(litres); lcd.print(" L ");

you read duration and map distance (which is never assigned a value)

what are the inner sizes of the tank?

narzan: you make me confused! witch code now :) ! i used this code

// litres  
int litres;
litres = (highWater * lowWater * distance);
lcd.print(litres);
lcd.print(" L ");

but the number not make any sense 3928L !!

you should multiply

litres = distance (==heigth) * Width * length

highWater and lowwater are also height's (limits) so it makes indeed no sense to multiply them.

stripped your code a bit, give it a try

#include <LiquidCrystal.h>

#define ECHOPIN 3                            // Pin to receive echo pulse
#define TRIGPIN 4                            // Pin to send trigger pulse
#define STATUSPIN 13                        // Use for troubleshooting
int highWater = 30;        // These values allow to calculate % of full
int lowWater = 95;        // SRF04 hangs above water (lower distance = more water)

byte symbol[8] = {         // Custom character for LCD display
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
};

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    // Assign pins

// Utility function for flashing STATUSPIN
void flashLed(int pin, int times, int wait)
{
  for (int i = 0; i < times; i++)
  {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);
    delay(wait);
  }
}

void setup()
{
  lcd.begin(16, 2);
  lcd.print("   AQUA LEVEL ");
  lcd.createChar(0, symbol);
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);

  delay(3000);       // Show application name for 3 seconds.
}

void loop() 
{
  // Measure duration
  digitalWrite(TRIGPIN, LOW);                   // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);                  // Send a 10uS high to trigger ranging
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);                   // Send pin low again
  unsigned long duration = pulseIn(ECHOPIN, HIGH);        // Read in times pulse

  // convert to litres
  int litres = map(duration, 5510, 1750, 100, 1400);
  
  // update display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(litres);

  delay(1000);
}

your last code not work showing weird numbers :roll_eyes: I changed the code to this

// litres  
int litres;
litres = (100 * (200 * distance))/(1000); 
lcd.print(litres);
lcd.print(" L ");

seems logic i think ::) display show this 48 CM - 960 L and 14 # bar i think that's work now

i think that's work now

Than I consider it solved.

but wrong equation :roll_eyes: depending on this |500x336

// CM 
int cm;
cm = (95)-(distance);
lcd.setCursor(0, 1); 
lcd.print(cm);
lcd.print(" CM - ");

// litres  
int litres;
litres = (100 * (200 * (95 - distance)))/(1000); 
lcd.print(litres);
lcd.print((char)1);
lcd.print("L");

litres = (100 * (200 * (95 - distance)))/(1000);

be aware that overflow can happen in this formula. Better simplify it to

litres = 20 * (95 - distance);

as you see it will make steps of 20 litres.

If you base the formula on the time pulsein returns

litres = 20 * (95 - distance*58) / 58;
litres = 20 * (95 - duration) / 58;
litres = (95 - duration) * 0,3448276;

Thanks allot robtillaart, i like this one

litres = 20 * (95 - distance);

“overflow” that’s exactly what happened with my formula
you solve it :slight_smile: thanks
everything work now

@ robtillaart,... +1.. as always.. Go to the expert. You have no idea how you've helped me since I joined this forum in 2013.

Doc