Distance Measurement System Using Arduino UNO and Ultrasonic Sensor

I am building an IoT system to measure the distance from two individual points by using two HC-SR04 ultrasonic sensors and two 16x2 I²C LCD displays to show each sensor’s reading separately.

Sensor 1 measures the distance, and the result is displayed on LCD 1. Sensor 2 measures the distance after a short delay, displayed on LCD 2. Both readings are also printed on the Serial Monitor for debugging and logging.

I have used Arduino UNO, two HC-SR04 ultrasonic sensors for measuring distances, two 16x2 LCD displays with I²C interface (PCF8574-based) to show each sensor’s distance readings independently.

Shared I²C communication lines (A4, A5) for both LCDs, with unique I²C addresses (0x27 and 0x20).

I am building an IoT system to measure the distance from two individual points by using two HC-SR04 ultrasonic sensors and two 16x2 I²C LCD displays to show each sensor’s reading separately.

Sensor 1 measures the distance, and the result is displayed on LCD 1. Sensor 2 measures the distance after a short delay, displayed on LCD 2. Both readings are also printed on the Serial Monitor for debugging and logging.

I have used Arduino UNO, two HC-SR04 ultrasonic sensors for measuring distances, two 16x2 LCD displays with I²C interface (PCF8574-based) to show each sensor’s distance readings independently.

Shared I²C communication lines (A4, A5) for both LCDs, with unique I²C addresses (0x27 and 0x20).

In the effort to design this system, I developed the below code. I have tested this code on Tinkercad platform for simulation. But this code shows error Tinkercard that "Invalid header file". Altough, I have verified that two system (left senor + left LCD) and (right sensor + right LC) works fine individually without any error by executing a sample code. I also confirmed that each component works individually by executing a sample code. But when I tried to combine the two systems (using the below mentioned code) I am getting error that "Invalid header file". I

Here, I am sharing the image of circuit diagram

The code I built which shows me the error:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// I2C LCD addresses
#define LCD_ADDR1 0x27   // LCD #1 (left)
#define LCD_ADDR2 0x20   // LCD #2 (right)

// LCD objects
LiquidCrystal_I2C lcd1(LCD_ADDR1, 16, 2);
LiquidCrystal_I2C lcd2(LCD_ADDR2, 16, 2);

// Ultrasonic pins
#define TRIG1 A2   // Sensor 1: TRIG=A2, ECHO=A3
#define ECHO1 A3
#define TRIG2 A0   // Sensor 2: TRIG=A0, ECHO=A1
#define ECHO2 A1

// Ping helper (with timeout)
unsigned long pingUS(uint8_t trig, uint8_t echo, unsigned long timeoutUS = 50000UL) {
  digitalWrite(trig, LOW);  delayMicroseconds(2);
  digitalWrite(trig, HIGH); delayMicroseconds(10);
  digitalWrite(trig, LOW);
  return pulseIn(echo, HIGH, timeoutUS);
}

void setup() {
  Serial.begin(9600);

  // Pins
  pinMode(TRIG1, OUTPUT); digitalWrite(TRIG1, LOW);
  pinMode(ECHO1, INPUT);
  pinMode(TRIG2, OUTPUT); digitalWrite(TRIG2, LOW);
  pinMode(ECHO2, INPUT);

  // I2C + LCDs
  Wire.begin(); delay(50);

  lcd1.begin(16, 2); lcd1.backlight(); lcd1.clear();
  lcd1.setCursor(0,0); lcd1.print("Sensor1 Dist:");
  lcd1.setCursor(0,1); lcd1.print("Sensor1 Dist:");

  lcd2.begin(16, 2); lcd2.backlight(); lcd2.clear();
  lcd2.setCursor(0,0); lcd2.print("Sensor2 Dist:");
  lcd2.setCursor(0,1); lcd2.print("Sensor2 Dist:");
}

void showReading(LiquidCrystal_I2C &lcd, float cm, float inch) {
  // cm line
  lcd.setCursor(9, 0);
  if (isnan(cm)) lcd.print("   ---   ");
  else { char b1[10]; dtostrf(cm, 6, 1, b1); lcd.print(b1); lcd.print("cm"); }

  // inch line
  lcd.setCursor(9, 1);
  if (isnan(inch)) lcd.print("   ---   ");
  else { char b2[10]; dtostrf(inch, 6, 1, b2); lcd.print(b2); lcd.print("in"); }
}

void loop() {
  // --- Sensor 1 (sequential) ---
  unsigned long us1 = pingUS(TRIG1, ECHO1);
  float cm1 = NAN, inch1 = NAN;
  if (us1 > 0) { cm1 = (us1 / 2.0f) / 29.1f; inch1 = (us1 / 2.0f) * 0.0133f; }

  // small gap to avoid cross-talk
  delay(60);

  // --- Sensor 2 ---
  unsigned long us2 = pingUS(TRIG2, ECHO2);
  float cm2 = NAN, inch2 = NAN;
  if (us2 > 0) { cm2 = (us2 / 2.0f) / 29.1f; inch2 = (us2 / 2.0f) * 0.0133f; }

  // Serial debug
  if (us1 == 0) Serial.print("S1: no ecaho   ");
  else { Serial.print("S1: "); Serial.print(cm1,1); Serial.print(" cm   "); }
  if (us2 == 0) Serial.println("S2: no echo");
  else { Serial.print("S2: "); Serial.print(cm2,1); Serial.println(" cm"); }

  // Update LCDs
  showReading(lcd1, cm1, inch1);   // Sensor 1 -> LCD 1
  showReading(lcd2, cm2, inch2);   // Sensor 2 -> LCD 2

  delay(150);
}

Did you upload incomplete code or does your code not have loop()?

My mistakes. I am uploading the correct code

Ultrasonic sensors do not work that way. You can compute the distance from the sensor to a reflective surface anywhere in the sensor’s cone of response, nothing else.

Distance to what? What are the "points"?

Please post a simple pencil and paper diagram illustrating the meaning of that phrase.

The most common cause of that error that I have seen seems to be calling a class method that doesn't exist or needs a different set of parameters than used in your code in the class' header file. That's not to say it couldn't be being caused by something else; it is so vague that it is absolutely useless.

All I can tell you is that your code compiles with no errors and only a single non serious warning (with the compile warning level turned all the way up) for an Uno R3 with the Arduino tools.

So you're not fighting a code error, you're fighting a TinkerCad error.

It compiles correctly in the IDE, I have no idea what's wrong with Tinkercad, I don't use it.

Regards

Thanks for confirming. Right now I have no access to Arduino UNO, that is why I am implementing the code on Tinkercard.

You can Compile the code in the Arduino ide to test without the need to upload to the UNO.

The error is in tinkercad. Wokwi allows it to function. (sorry. wokwi on my phone is not easy)


You have some allowed programming errors...

As the image shows, you are only printing from one sensor.

You create these objects...

LiquidCrystal_I2C lcd1(LCD_ADDR1, 16, 2);
LiquidCrystal_I2C lcd2(LCD_ADDR2, 16, 2);

But you call this...

  lcd.setCursor(9, 0);

It's true, it's rubbish.
After using us as beta testers for years and now acting pretentious, they could at least improve the mobile view.

If @urish is lurking... My phone is Android. Browser is Chrome. I find it difficult to connect and route wiring and use the joystick.