Issue with displaying the readings from ultrasonic to LCD

Hi everyone. I have a project that uses two HC-12 transceiver. So in the first module I have HC-12(sender) and ultrasonic sensor. While the other one is the receiver with HC-12 and LCD. The idea is to use it to monitor water tank level wirelessly. The problem is, the receiver module with LCD show the level in percentage inaccurately. For instance I am refilling the water tank the LCD goes 20%, 24%, 27%, 30% , 34%, and so on instead of 20, 21, 22, 23... .WHY the percentage increases with gaps the same thing happen when the water lvl is decreasing.

My project is similar to this one https://www.youtube.com/watch?v=0XvcTOI3-1Y&t=892s you can watch in 14 minutes mark, his LCD shows what I meant to my problem.

Receiver Code

//---------------------------- LIVE WATER TANK INDICATOR WITH DR PUMP RUN PROTECTION USING ARDUINO AND HC- 12 TRANSCIEVER----------------
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>   //DONT FORGET TO CHANGE THE IF CONDITION TO SUMP TANK

unsigned long previousMillis = 0; // Variable to store the last time the function was called
unsigned long delayTime = 5000;   // Delay time in milliseconds

LiquidCrystal_I2C lcd(0x27, 20, 4);
SoftwareSerial HC12(7, 8);

#define BUTTON_MUTE 13
#define calibrateBtn 12
const int reset = 2;
const int Relaypin = 10;
const int red_led =   6;
const int yellow_led = 5;
const int green_led = 4;
const int pmp_On = 9;
const int pmp_Off = 11;
const int SpmpSensorPin = A0;           // Upload again to updata Sump tank empty!

int data = 0;
int duration = 500;
int flag;
int addr = 0;
int addr2 = 1;
float MaxWaterLevel, EmptySpace, SonarReading, ActualReading, Temp;
int tankHeight;
int setHeight = 0;
int percentage = 0;
int caliBtnState = 0;
int buttonState = 1;
int previous_data = 0;
byte lastButtonState = 1; //Motingog sa pinaka una
byte buzState = LOW;
unsigned long previousTime = 0;
const unsigned long interval = 500;
bool ledState = false;


//++++++++++++++++++++++++++++++++++++++++++++++ TANK FRAME +++++++++++++++++++++++++++++++++++
byte FrameRight[8] = {
  0b00011, 0b00011, 0b00011, 0b00011, 0b00011, 0b00011, 0b00011, 0b00011
};

byte FrameRightCorner[8] = {
  0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00011, 0b00011
};

byte FrameLeft[8] = {
  0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000
};

byte FrameLeftCorner[8] = {
  0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11000, 0b11000
};

byte FrameTopp[8] = {
  0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111
};

//+++++++++++++++++++++++++++++++++++++++++++++++++ FILL BYTES +++++++++++++++++++++++++++++++++
byte Fill0[8] = {
  0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000
};

byte Fill1[8] = {
  0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111
};

byte Fill2[8] = {
  0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void RunHC12() {
  while (HC12.available ()) {
    data = HC12.read();
    if ((data < 200) or (data >= 0)) {
      previous_data = data;
    }
    if ((data > 201) or (data < 0)) {
      data = previous_data;
    }
  }
}
void setup() {
  Serial.begin(9600);
  HC12.begin(9600);
  lcd.init();     
  lcd.backlight(); 

  digitalWrite(reset, HIGH);

  pinMode(reset, OUTPUT);
  pinMode(calibrateBtn, INPUT_PULLUP);
  pinMode(red_led, OUTPUT);
  pinMode(yellow_led, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(pmp_Off, OUTPUT);
  pinMode(pmp_On, OUTPUT);
  pinMode(BUTTON_MUTE, INPUT_PULLUP);

  pinMode(Relaypin, OUTPUT); // Define the Relaypin as output pin

  lcd.createChar(0, FrameRight);
  lcd.createChar(1, FrameRightCorner);
  lcd.createChar(2, FrameLeft);
  lcd.createChar(3, FrameLeftCorner);
  lcd.createChar(6, Fill0);
  lcd.createChar(4, Fill1);
  lcd.createChar(5, Fill2);
  lcd.createChar(7, FrameTopp);

  lcd.setCursor(0, 1);
  lcd.print(F("AUTOMATED TANK LEVEL"));
  lcd.setCursor(1, 2);
  lcd.print(F("INDICATOR SYSTEM"));
  delay(4000);
  lcd.clear();

  for (int i = 0; i <= 10; i++) {
    lcd.setCursor(2, 0);
    lcd.print(F("Set tank height?"));

    lcd.setCursor(0, 1);
    lcd.print(F("(Y) Press'Set'"));
    lcd.setCursor(0, 2);
    lcd.print(F("(N) Ignore"));

    lcd.setCursor(0, 3);
    lcd.print(F("Expired in:"));
    lcd.print(10 - i);
    lcd.print(" sec  ");

    caliBtnState = digitalRead(calibrateBtn);
    if (caliBtnState == LOW) {
      lcd.clear();
      tankHeight = HC12.read();
      EEPROM.write(addr, tankHeight);
      break;
    }
    delay(1000);
  }
  tankHeight = EEPROM.read(addr);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print(F("Tank height:"));
  lcd.print((String)tankHeight + "cm  ");
  delay(3000);
  lcd.clear();

  MaxWaterLevel = 0.50 * tankHeight;
  EmptySpace = tankHeight - MaxWaterLevel;
}
void loop() {
  int SpmpsensorValue = analogRead(SpmpSensorPin);  // Read the analog sensor value
  int scaledValue = map(SpmpsensorValue, 0, 1023, 0, 255);  // Map the value to a new range
  float multiValueSpmp = scaledValue * 5.0;  // Scale the value to get the actual voltage value
  Serial.println(percentage);

  Temp = data - EmptySpace;
  ActualReading = MaxWaterLevel - Temp;
  percentage = ActualReading / MaxWaterLevel * 100;

  /*if (tankHeight == 153 || tankHeight == 255) {
    lcd.setCursor(2, 0);
    lcd.print(F("Please try again"));
    delay(3000);
    digitalWrite(reset, LOW);
  }*/
  if (multiValueSpmp >= 200) {
    lastButtonState = HIGH;
    FrameRightDisplay();
    RunHC12();

    lcd.setCursor(8, 1);
    lcd.print("Level: ");
    lcd.setCursor(8, 2);
    lcd.print((String)percentage + "%   ");
    if (percentage == 200 ) {
      percentage = 21;
      Level1();
    }
    if (percentage <= 20 || tankHeight == 153) {
      Level1();
      lcd.setCursor(13, 3);
      lcd.print("PMP:ON ");
      digitalWrite(Relaypin, HIGH);
      digitalWrite(pmp_On, HIGH);
      digitalWrite(pmp_Off, LOW);

      digitalWrite(red_led, HIGH);
      digitalWrite(yellow_led, LOW);
      digitalWrite(green_led, LOW);

      flag = 1;
      EEPROM.write(addr2, flag);
      flag = EEPROM.read(addr2);
    }
    else if (percentage > 20 && percentage <= 100) {
      flag = EEPROM.read(addr2);

      if (percentage > 20 && percentage <= 100 && flag == 1) {

        digitalWrite(Relaypin, HIGH);
        lcd.setCursor(13, 3);
        lcd.print("PMP:ON");
        digitalWrite(pmp_Off, LOW);
        digitalWrite(pmp_On, HIGH);

        if (percentage <= 20) {
          Level1();

          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);
        }
        else if (percentage > 20 && percentage <= 25) {
          Level2();

          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);
        }
        else if (percentage > 25 && percentage <= 50) {

          Level3();
          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);

        }
        else if (percentage > 50 && percentage <= 75) {

          Level4();

          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, HIGH);
          digitalWrite(green_led, LOW);
        }
        else if (percentage > 75 && percentage <= 95) {
          Level5();
          digitalWrite(red_led,   LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);

        }
        else if (percentage == 100) {
          Level6();
          lcd.setCursor(13, 3);
          lcd.print("PMP:OFF");

          digitalWrite(pmp_Off, HIGH);
          digitalWrite(pmp_On, LOW);

          digitalWrite(red_led,   LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);
        }
      }
      else if (percentage > 20 && percentage <= 100 && flag == 0 ) {

        digitalWrite(Relaypin, LOW); //relayyyyy pin hereee
        lcd.setCursor(11, 3);
        lcd.print("  PMP:OFF");
        digitalWrite(pmp_On, LOW);
        digitalWrite(pmp_Off, HIGH);

        if (percentage <= 10) {

          Level1();
          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);

        }
        else if (percentage > 20 && percentage <= 25) {
          Level2();

          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);

        }
        else if (percentage > 25 && percentage <= 50) {

          Level3();
          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);

        }
        else if (percentage > 50 && percentage <= 75) {

          Level4();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, HIGH);
          digitalWrite(green_led, LOW);

        }
        else if (percentage > 75 && percentage <= 95) {
          Level5();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);
        }
        else if ( percentage == 100) {
          Level6();

          lcd.setCursor(13, 3);
          lcd.print("PMP:OFF");

          digitalWrite(pmp_Off, HIGH);
          digitalWrite(pmp_On, LOW);

          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);
        }
      }
    }
    else if (percentage > 100) {
      delay (200);

      lcd.setCursor(13, 3);
      lcd.print("PMP:OFF");
      digitalWrite(Relaypin, LOW);

      digitalWrite(pmp_Off, HIGH);
      digitalWrite(pmp_On, LOW);

      digitalWrite(red_led, LOW);
      digitalWrite(yellow_led, LOW);
      digitalWrite(green_led, HIGH);

      flag = 0;
      EEPROM.write(addr2, flag) ;
      flag = EEPROM.read(addr2);
      
      Level6();
    }
  } else if (multiValueSpmp <= 200) {
    flag = EEPROM.read(addr2);
      if (flag == 1) {
        lcd.clear();
        RunHC12();
        digitalWrite(Relaypin, LOW);
        digitalWrite(pmp_On, LOW);
        digitalWrite(red_led, LOW);
        digitalWrite(yellow_led, LOW);
        digitalWrite(green_led, LOW);
        //Sumpt Tank Empty Message Goes HEREEEEE
        lcd.setCursor(4, 1);
        lcd.print(F("Source Empty"));
        lcd.setCursor(3, 2);
        lcd.print("Water Lvl: "); 
        lcd.setCursor(14, 2);
        lcd.print((String)percentage + "%   ");

        unsigned long currentTime = millis();
        if (currentTime - previousTime >= interval) {
        previousTime = currentTime;
          if (ledState) {
            ledState = false;
            digitalWrite(pmp_Off, HIGH);
          } else {
          ledState = true;
          digitalWrite(pmp_Off, LOW);
          }
        }
        //PUT THE ALARM TONE HERE WITH MUTE BUTTON
        while (lastButtonState != LOW) {
          RunHC12();
          buttonState = digitalRead(BUTTON_MUTE);
          lcd.setCursor(3, 2);
          lcd.print("Water Lvl: "); 
          lcd.setCursor(14, 2);
          lcd.print((String)percentage + "%   ");
          if (buttonState == LOW) {
            noTone(3);
            lastButtonState = buttonState;

          } else if (buttonState == HIGH) {
            alarm();
          }
        }
        delay(1000);
        lcd.clear();
      }
      else if (flag == 0) {
        RunHC12();
        FrameRightDisplay();
        digitalWrite(pmp_On, LOW);

        lcd.setCursor(8, 1);
        lcd.print("Level: ");
        lcd.setCursor(8, 2);
        lcd.print((String)percentage + "%  ");
        lcd.setCursor(11, 3);
        lcd.print("ST:EMPTY  ");

        unsigned long currentTime = millis();
        if (currentTime - previousTime >= interval) {
          previousTime = currentTime;
          if (ledState) {
            ledState = false;
            digitalWrite(pmp_Off, LOW);
          } else {
            ledState = true;
            digitalWrite(pmp_Off, HIGH);
          }
        }
        if (percentage <= 20) {
          Level1();
          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);
        } else if (percentage > 20 && percentage <= 25) {
          Level2();
          digitalWrite(red_led, HIGH);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, LOW);
        } else if (percentage > 25 && percentage <= 50) {
          Level3();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, HIGH );
          digitalWrite(green_led, LOW);
        } else if (percentage > 50 && percentage <= 75) {
          Level4();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, HIGH);
          digitalWrite(green_led, LOW);
        } else if (percentage > 75 && percentage <= 100) {
          Level5();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);
        } else if (percentage > 100) {
          Level6();
          digitalWrite(red_led, LOW);
          digitalWrite(yellow_led, LOW);
          digitalWrite(green_led, HIGH);
        }
    }
  }
}
void alarm() {
  tone(3, 1400, duration);
  delay(1000);
  tone(3, 800, duration);
  delay(1000);
}
//+++++++++++++++++++++++++++++++++++++++ FRAME ++++++++++++++++++++++++++++++++++++++
void FrameRightDisplay() {
  lcd.setCursor(1, 0); lcd.write(byte(7)); lcd.write(byte(7)); lcd.write(byte(7)); lcd.write(byte(7)); lcd.write(byte(7)); lcd.write(byte(7));
  lcd.setCursor(3, 0); lcd.write(byte(4)); lcd.write(byte(4));
  lcd.setCursor(0, 3); lcd.write(byte(0)); lcd.setCursor(0, 2); lcd.write(byte(0)); lcd.setCursor(0, 1); lcd.write(byte(0));
  lcd.setCursor(0, 0); lcd.write(byte(1));
  lcd.setCursor(7, 3); lcd.write(byte(2)); lcd.setCursor(7, 2); lcd.write(byte(2)); lcd.setCursor(7, 1); lcd.write(byte(2));
  lcd.setCursor(7, 0); lcd.write(byte(3));
}
//++++++++++++++++++++++++++++++++++++++++++ PROGRESS BAR ++++++++++++++++++++++++++++++
void Level1() {
  lcd.setCursor(1, 3); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4));
}
void Level2() {
  lcd.setCursor(1, 3); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 2); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6));
  lcd.setCursor(1, 1); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6));
}
void Level3() {
  lcd.setCursor(1, 2); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4));
  lcd.setCursor(1, 3); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
}
void Level4() {
  lcd.setCursor(1, 3); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 2); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 1); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6));
}
void Level5() {
  lcd.setCursor(1, 1); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4)); lcd.write(byte(4));
  lcd.setCursor(1, 3); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 2); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));

}
void Level6() {
  lcd.setCursor(1, 1); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 3); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
  lcd.setCursor(1, 2); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5)); lcd.write(byte(5));
}

Sender Code

#include <SoftwareSerial.h>
SoftwareSerial HC12(5, 4);

const int trigPin = 3;      // define the trigger pin
const int echoPin = 2;     // define the echo pin
int power = 6;


long scaledDist2 = 0;
int Time = 0;
const int numReadings = 10; // number of readings to average
int readings[numReadings];  // array to store the readings
int index = 0;              // index of the current reading
int total = 0;              // total of all the readings
int average = 0;            // average of the readings
int scaledDist1 = 0;     // scaled distance measurement

void setup() {
  HC12.begin(9600);
  Serial.begin(9600);       // initialize serial communication
  pinMode(trigPin, OUTPUT); // set the trigger pin as an output
  pinMode(echoPin, INPUT);  // set the echo pin as an input
  pinMode(power, OUTPUT);
  digitalWrite(power, 1);
}

void loop() {
   Time++;
  // trigger the ultrasonic sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(20);
  digitalWrite(trigPin, LOW);

  // measure the echo pulse duration
  long duration = pulseIn(echoPin, HIGH);

  // convert the duration to distance in cm
  long distance = duration / 29 / 2;

  // add the distance measurement to the readings array
  total = total - readings[index];
  readings[index] = distance;
  total = total + readings[index];

  // increment the index
  index = index + 1;

  // wrap around the index if necessary
  if (index >= numReadings) {
    index = 0;
  }
  average = total / numReadings;
  scaledDist1 = constrain(average, 0, 300);

  //Serial.println(scaledDist1);

  if(Time == 100){
      HC12.write(scaledDist1);
      Time = 0;
  }
  
  Serial.println(scaledDist1);

  if(scaledDist1 != scaledDist2){
      HC12.write(scaledDist1);
      scaledDist2 = scaledDist1;
  }

  delay(200);
}

Hello el11ven

We need some additional information.
Post your sketch, well formated, with well-tempered comments and in so called code tags "< code >" and a detailed circuit diagram to see how we can help.

Have a nice day and enjoy coding in C++.

The link to your code does not seem to work. It's anyway better to post the codes here in a post using code tags.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.