Ultraschall-Einparkhilfe mit Arduino bauen: HC-SR04, LCD1602 & LED-Ampel

Beim Rückwärtseinparken jedes Mal die Luft anhalten? Bau dir eine eigene Einparkhilfe, die exakt anzeigt, wie viele Zentimeter noch bis zur Wand sind. Herzstück ist der HC-SR04 Ultraschallsensor: Er misst den Abstand berührungslos, ein LCD1602-Display zeigt die Distanz in Klartext und eine LED-Ampel wechselt von Grün über Gelb auf Rot. In diesem Tutorial baust du das komplette Gerät Schritt für Schritt auf – inklusive Piepton, der immer schneller wird, je näher du kommst.

Warum eine Einparkhilfe selbst bauen?

Serienmäßige Parksensoren stecken im Stoßfänger und lassen sich schlecht nachrüsten. Für die Garage, den Carport oder die Werkstatt brauchst du aber gar keine Elektronik im Auto: Ein einziger Ultraschallsensor an der Wand reicht, um dir jederzeit den Restabstand anzuzeigen. Das Projekt ist perfekt für Einsteiger, weil du dabei gleich drei Grundtechniken lernst – Abstände messen, Werte auf einem Display anzeigen und Schwellwerte in Aktionen umsetzen (LEDs und Ton). Und am Ende hängt ein Gerät an der Wand, das du wirklich jeden Tag benutzt.

ℹ️ Wie misst Ultraschall überhaupt? Der HC-SR04 sendet einen kurzen, für uns unhörbaren Schallimpuls aus und misst, wie lange das Echo bis zur Rückkehr braucht. Aus dieser Zeit und der Schallgeschwindigkeit (rund 343 m/s) berechnet der Arduino die Entfernung. Das funktioniert zuverlässig von etwa 2 cm bis 4 m.

So funktioniert das Gerät

Der HC-SR04 hängt mit vier Leitungen am Arduino und liefert alle 100 Millisekunden eine neue Messung. Der Arduino rechnet die gemessene Laufzeit in Zentimeter um und entscheidet dann anhand von Schwellwerten, was passiert: Bei großem Abstand leuchtet die grüne LED, im mittleren Bereich die gelbe, und wird es eng, schaltet die rote LED ein und der Piezo-Summer piept – umso schneller, je dichter du kommst. Parallel schreibt der Arduino den aktuellen Abstand auf das LCD1602, das über den I2C-Bus mit nur zwei Datenleitungen angebunden ist.

Das brauchst du

HC-SR04 Ultraschallsensor – misst den Abstand berührungslos
LCD1602 Display mit I2C – zeigt den Abstand in Zentimetern
UNO R3 Entwicklungsboard (USB-C) – die Steuerzentrale
3mm LEDs (Rot/Gelb/Grün) – die Abstands-Ampel
Widerstände 220–330 Ω – Vorwiderstände für die LEDs

1Verkabelung

Der HC-SR04 hat vier Pins: VCC, Trig, Echo und GND. Das LCD1602 mit I2C-Rückplatine kommt mit vier Leitungen aus und teilt sich mit nichts anderem den Bus. Die drei LEDs bekommen je einen Digitalpin über einen Vorwiderstand.

Bauteil / Pin Arduino UNO Hinweis
HC-SR04 VCC 5V Versorgung
HC-SR04 GND GND Masse
HC-SR04 Trig D9 Auslöse-Impuls
HC-SR04 Echo D10 Echo-Rückmeldung
LCD SDA A4 I2C-Daten
LCD SCL A5 I2C-Takt
LCD VCC / GND 5V / GND Versorgung
LED grün D5 (über 220 Ω) viel Abstand
LED gelb D6 (über 220 Ω) Vorsicht
LED rot D7 (über 220 Ω) Stopp
Summer + D8 Piepton (optional)

ℹ️ Warum ein Vorwiderstand? Ohne Widerstand zieht eine LED zu viel Strom und stirbt den schnellen Tod. Wie du den passenden Wert berechnest, erklärt der Guide LED-Vorwiderstand berechnen.

2Abstand messen und im Seriellen Monitor prüfen

Bevor Display und LEDs dazukommen, testen wir die reine Messung. Der folgende Sketch löst den Sensor aus, misst die Echo-Laufzeit mit pulseIn() und rechnet sie in Zentimeter um. Öffne den Seriellen Monitor bei 115200 Baud und halte die Hand vor den Sensor:

const int TRIG = 9;
const int ECHO = 10;

void setup() {
  Serial.begin(115200);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
}

float messeAbstand() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  long dauer = pulseIn(ECHO, HIGH, 30000);  // Timeout 30 ms
  if (dauer == 0) return -1;                // kein Echo
  return dauer * 0.0343 / 2.0;              // cm
}

void loop() {
  float cm = messeAbstand();
  if (cm < 0) Serial.println("kein Echo");
  else { Serial.print(cm, 1); Serial.println(" cm"); }
  delay(100);
}

Mehr zu den Grundlagen und typischen Fehlerquellen des Sensors findest du im HC-SR04-Tutorial.

3Den Abstand aufs LCD1602 bringen

Installiere über den Bibliotheksverwalter die LiquidCrystal_I2C. Findet der Sketch das Display nicht, ist die I2C-Adresse meist 0x27 oder 0x3F – prüfe sie im Zweifel mit einem I2C-Scanner.

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

LiquidCrystal_I2C lcd(0x27, 16, 2);
const int TRIG = 9, ECHO = 10;

float messeAbstand() {
  digitalWrite(TRIG, LOW); delayMicroseconds(2);
  digitalWrite(TRIG, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  long d = pulseIn(ECHO, HIGH, 30000);
  return d == 0 ? -1 : d * 0.0343 / 2.0;
}

void setup() {
  pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT);
  lcd.init();
  lcd.backlight();
}

void loop() {
  float cm = messeAbstand();
  lcd.setCursor(0, 0);
  lcd.print("Abstand:        ");
  lcd.setCursor(0, 1);
  if (cm < 0) { lcd.print("-- kein Echo    "); }
  else { lcd.print(cm, 1); lcd.print(" cm        "); }
  delay(150);
}

ℹ️ Warum die vielen Leerzeichen? Das LCD löscht Zeichen nicht von selbst. Schreibst du „8.5 cm“ nach „152.3 cm“, bleibt die alte „.3 cm“ stehen. Die angehängten Leerzeichen überschreiben Reste der vorigen Anzeige. Tiefer steigt das LCD1602-Tutorial ein.

4LED-Ampel und Piepton hinzufügen

Jetzt kommt das Herzstück der Einparkhilfe: die Auswertung in Zonen. Über 60 cm ist alles entspannt (grün), zwischen 20 und 60 cm heißt es aufpassen (gelb), unter 20 cm ist Schluss (rot). Der Summer piept im gelben Bereich langsam und im roten Bereich schnell – ganz wie im Auto:

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

LiquidCrystal_I2C lcd(0x27, 16, 2);
const int TRIG = 9, ECHO = 10;
const int LED_GRUEN = 5, LED_GELB = 6, LED_ROT = 7, SUMMER = 8;

unsigned long letzterPiep = 0;
bool piepAn = false;

float messeAbstand() {
  digitalWrite(TRIG, LOW); delayMicroseconds(2);
  digitalWrite(TRIG, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  long d = pulseIn(ECHO, HIGH, 30000);
  return d == 0 ? -1 : d * 0.0343 / 2.0;
}

void setup() {
  pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT);
  pinMode(LED_GRUEN, OUTPUT); pinMode(LED_GELB, OUTPUT);
  pinMode(LED_ROT, OUTPUT); pinMode(SUMMER, OUTPUT);
  lcd.init(); lcd.backlight();
}

void setzeAmpel(int g, int y, int r) {
  digitalWrite(LED_GRUEN, g);
  digitalWrite(LED_GELB, y);
  digitalWrite(LED_ROT, r);
}

void loop() {
  float cm = messeAbstand();
  int piepTakt = 0;   // 0 = aus

  lcd.setCursor(0, 0); lcd.print("Einparkhilfe    ");
  lcd.setCursor(0, 1);

  if (cm < 0) {
    setzeAmpel(LOW, LOW, LOW);
    lcd.print("-- warten --    ");
  } else if (cm > 60) {
    setzeAmpel(HIGH, LOW, LOW);
    lcd.print("OK  "); lcd.print(cm, 0); lcd.print(" cm     ");
  } else if (cm > 20) {
    setzeAmpel(LOW, HIGH, LOW);
    lcd.print("langsam "); lcd.print(cm, 0); lcd.print(" cm ");
    piepTakt = 400;
  } else {
    setzeAmpel(LOW, LOW, HIGH);
    lcd.print("STOP! "); lcd.print(cm, 0); lcd.print(" cm  ");
    piepTakt = 120;
  }

  // Piepton ohne delay() schalten
  if (piepTakt == 0) {
    noTone(SUMMER); piepAn = false;
  } else if (millis() - letzterPiep >= piepTakt) {
    letzterPiep = millis();
    piepAn = !piepAn;
    if (piepAn) tone(SUMMER, 2000); else noTone(SUMMER);
  }

  delay(60);
}

💡 Warum millis() statt delay()? Würdest du den Piepton mit delay() takten, stünde in dieser Zeit die Messung still und die Anzeige würde ruckeln. Mit millis() läuft alles flüssig parallel. Das Prinzip erklärt der Guide millis() statt delay().

5Messwerte glätten für eine ruhige Anzeige

Ultraschall-Messungen springen gelegentlich um ein paar Zentimeter. Damit die Anzeige nicht zappelt, mittelst du einfach die letzten fünf Messungen. Das macht die Einparkhilfe deutlich angenehmer ablesbar:

float glaetteAbstand() {
  const int N = 5;
  float summe = 0;
  int gueltig = 0;
  for (int i = 0; i < N; i++) {
    float m = messeAbstand();
    if (m > 0) { summe += m; gueltig++; }
    delay(15);
  }
  if (gueltig == 0) return -1;
  return summe / gueltig;   // Durchschnitt der gueltigen Messungen
}

Ersetze im Hauptprogramm einfach messeAbstand() durch glaetteAbstand(). Fehlmessungen (kein Echo) werden dabei automatisch aussortiert.

Praxistipps für den Einbau

  • Sensor auf Stoßfänger-Höhe: Montiere den HC-SR04 so, dass er die Fahrzeugfront trifft und nicht den Boden oder das Kennzeichen-Schild.
  • Schwellwerte anpassen: Die 60/20-cm-Grenzen sind ein Startpunkt. Miss deinen Wunschabstand aus und trage ihn in den Code ein.
  • Gehäuse nutzen: Ein einfaches Kunststoffgehäuse schützt die Elektronik in Garage und Carport vor Staub und Feuchtigkeit.
  • Feste Verdrahtung: Läuft alles, lohnt sich der Umzug vom Breadboard auf eine Lochrasterplatine.
  • Dauerbetrieb: Ein einfaches 5-V-USB-Netzteil versorgt den Aufbau rund um die Uhr.

Troubleshooting

⚠️ Anzeige springt oder zeigt Unsinn: Nutze die Glättung aus Schritt 5 und prüfe, ob der Sensor fest sitzt. Weiche, schräge oder sehr kleine Objekte reflektieren Ultraschall schlecht.

⚠️ LCD bleibt leer oder zeigt nur Blöcke: Falsche I2C-Adresse. Probiere 0x3F statt 0x27 und dreh notfalls das Kontrast-Poti auf der Display-Rückseite.

⚠️ Immer „kein Echo“: Trig und Echo vertauscht oder der Timeout zu kurz. Prüfe die Pinbelegung und ob VCC wirklich an 5 V liegt.

⚠️ Summer piept nur ganz leise: Ein aktiver Buzzer braucht keinen tone()-Befehl, ein passiver schon. Für tone() einen passiven Piezo verwenden.

⚠️ Alle LEDs leuchten schwach mit: Fehlender gemeinsamer GND zwischen Breadboard und Arduino. Eine durchgehende Masseleitung löst das.

🚀 Dein Einparkhilfe-Starterpaket

Alle Bauteile für dieses Projekt im Shop:

Fazit

Aus einem Ultraschallsensor, einem LCD und ein paar LEDs entsteht eine Einparkhilfe, die du täglich nutzt. Du hast gelernt, mit dem HC-SR04 Abstände zu messen, die Werte auf dem LCD1602 anzuzeigen, sie in eine Ampel-Logik mit drei Zonen zu übersetzen und einen mitlaufenden Piepton ohne delay() zu erzeugen. Mit der Messwert-Glättung wird die Anzeige schön ruhig.

Von hier aus kannst du weiterbauen: eine zweite Messrichtung für seitlichen Abstand, ein OLED statt LCD für Grafik, oder eine automatische Abschaltung nach ein paar Minuten Stillstand. Viel Spaß beim Einparken – ganz ohne angehaltene Luft!

Zurück zum Blog