Arduino Radar bauen: Ultraschall-Scanner mit HC-SR04 & Servo (SG90) + Processing-Anzeige
Ein Ultraschallsensor misst Abstand – aber immer nur geradeaus. Setzt du ihn auf einen kleinen Servo, der ihn hin und her schwenkt, entsteht daraus ein echtes Radar: Der HC-SR04 tastet Grad fuer Grad einen Halbkreis ab, dein Arduino schickt Winkel und Abstand an den PC, und ein kleines Processing-Programm zeichnet daraus den klassischen gruenen Radarschirm mit rotierendem Sweep. In diesem Tutorial baust du den Aufbau von Grund auf: Servo-Sweep, saubere Ultraschallmessung, ein kompaktes Datenprotokoll und die fertige Radar-Visualisierung – wahlweise am PC oder direkt auf einem OLED-Display.
Wie aus Sensor + Servo ein Radar wird
Das Prinzip ist verblueffend einfach: Der HC-SR04 sendet einen Ultraschall-Impuls und misst die Zeit, bis das Echo zurueckkommt – daraus ergibt sich die Entfernung. Er "sieht" dabei aber nur in einem schmalen Kegel nach vorne. Montierst du ihn auf einen SG90-Servo und drehst diesen langsam von 0° bis 180°, misst du bei jedem Winkel den Abstand. Kombinierst du Winkel und Entfernung, hast du fuer jeden Punkt im Halbkreis eine Koordinate – genau das, was ein Radar anzeigt.
Der Arduino uebernimmt das Schwenken und Messen und schickt die Wertepaare per USB an den PC. Dort rechnet ein Processing-Sketch die Polarkoordinaten (Winkel + Distanz) in Bildschirmpunkte um und malt den vertrauten Radarschirm. Das Ergebnis sieht aus wie aus einem U-Boot-Film – kostet aber nur eine Handvoll Bauteile.
ℹ️ Grenzen ehrlich benannt: Ultraschall ist kein Laser. Die Winkelaufloesung ist grob (der Schallkegel ist breit), und sehr schraege oder schallschluckende Flaechen (Stoff, Schaumstoff) werden schlecht erkannt. Fuer praezise, punktgenaue Messungen ist ein VL53L0X Laser-Sensor die Oberklasse – fuer ein cooles, gut sichtbares Radar ist der HC-SR04 aber perfekt.
Das brauchst du
1Verkabelung
Der HC-SR04 hat vier Pins (VCC, Trig, Echo, GND), der Servo drei (Plus, Minus, Signal). Wir nutzen Trig an D9, Echo an D10 und das Servo-Signal an D11.
| Bauteil / Pin | Arduino UNO | Hinweis |
|---|---|---|
| HC-SR04 VCC | 5V | Sensor braucht 5 V |
| HC-SR04 Trig | D9 | Trigger-Impuls |
| HC-SR04 Echo | D10 | Echo-Rueckmeldung |
| HC-SR04 GND | GND | gemeinsame Masse |
| Servo Signal (orange) | D11 | PWM-Steuersignal |
| Servo Plus (rot) | 5V | bei groesseren Servos extern versorgen |
| Servo Minus (braun) | GND | Masse mit Arduino verbinden |
⚠️ Servo-Zappeln am USB: Zieht der Servo im Anlauf viel Strom, bricht die 5-V-Schiene kurz ein – der Sensor liefert dann Mist oder der UNO resettet. Beim leichten SG90 am USB meist unkritisch. Beim MG996R gehoert der Servo an eine eigene 5-V-Quelle – wie du die sauber bereitstellst, zeigt der Guide zu Step-Down-Reglern. Wichtig: gemeinsame Masse nicht vergessen.
2Bausteine testen: Messung & Sweep
Bevor wir alles kombinieren, pruefen wir beide Teile einzeln. Zuerst eine saubere Abstandsmessung als Funktion – mit pulseIn-Timeout, damit ein fehlendes Echo den Ablauf nicht blockiert:
#define TRIG 9
#define ECHO 10
long messeAbstandCm() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
// Timeout 25 ms = ca. 4 m Reichweite
long dauer = pulseIn(ECHO, HIGH, 25000);
if (dauer == 0) return 400; // kein Echo -> Maximalwert
long cm = dauer * 0.0343 / 2; // Schallgeschwindigkeit
return cm;
}
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
Serial.begin(115200);
}
void loop() {
Serial.print(messeAbstandCm());
Serial.println(" cm");
delay(200);
}
Und der Servo-Sweep, der langsam von 0° auf 180° und zurueck faehrt (Bibliothek Servo ist bei der Arduino IDE dabei):
#include <Servo.h>
Servo radarServo;
void setup() {
radarServo.attach(11);
}
void loop() {
for (int w = 0; w <= 180; w++) {
radarServo.write(w);
delay(15);
}
for (int w = 180; w >= 0; w--) {
radarServo.write(w);
delay(15);
}
}
Laeuft beides einzeln, kann nichts mehr schiefgehen. Mehr zu Servo-Ansteuerung und Sweep-Feinheiten findest du im Servo-Tutorial.
3Der komplette Radar-Sketch
Jetzt fuegen wir beides zusammen: Der Servo schwenkt schrittweise, bei jedem Winkel wird gemessen, und Arduino sendet das Paar im Format winkel,abstand. – der Punkt am Ende ist unser Trennzeichen, an dem Processing die Datensaetze auseinanderschneidet.
#include <Servo.h>
#define TRIG 9
#define ECHO 10
Servo radarServo;
long messeAbstandCm() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long dauer = pulseIn(ECHO, HIGH, 25000);
if (dauer == 0) return 400;
return dauer * 0.0343 / 2;
}
void sendePaar(int winkel) {
long abstand = messeAbstandCm();
Serial.print(winkel);
Serial.print(",");
Serial.print(abstand);
Serial.print("."); // Satz-Ende fuer Processing
}
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
radarServo.attach(11);
Serial.begin(115200);
}
void loop() {
for (int w = 0; w <= 180; w++) {
radarServo.write(w);
delay(20); // Servo Zeit zum Bewegen geben
sendePaar(w);
}
for (int w = 180; w >= 0; w--) {
radarServo.write(w);
delay(20);
sendePaar(w);
}
}
💡 Warum das Trennzeichen wichtig ist: Serielle Daten kommen als kontinuierlicher Zeichenstrom an. Das , trennt Winkel von Abstand, der . markiert das Ende eines Datensatzes. Processing wartet auf den Punkt und weiss dann: Der Satz ist vollstaendig und darf ausgewertet werden. Dieses Prinzip – festes Protokoll mit klarem Endezeichen – macht jede serielle Verbindung robust.
4Die Radar-Anzeige in Processing
Processing ist eine kostenlose, Arduino-aehnliche Programmierumgebung fuer Grafik – die Syntax kennst du also schon. Lade Processing herunter, oeffne einen neuen Sketch und passe in der Zeile myPort den COM-Port an den deines Arduino an (derselbe wie in der Arduino IDE). Wichtig: Der Serielle Monitor der Arduino IDE muss geschlossen sein, sonst ist der Port belegt.
// Processing-Sketch: Ultraschall-Radar
import processing.serial.*;
Serial myPort;
String daten = "";
int winkel = 0;
int abstand = 0;
void setup() {
size(800, 450);
// COM-Port anpassen! Serial.list() zeigt alle Ports
myPort = new Serial(this, Serial.list()[0], 115200);
myPort.bufferUntil('.'); // bis zum Trennzeichen sammeln
}
void draw() {
// Nachleuchten simulieren: halbtransparent uebermalen
noStroke();
fill(0, 20);
rect(0, 0, width, height);
drawGitter();
drawStrahl();
drawObjekt();
}
void drawGitter() {
stroke(0, 255, 0);
noFill();
translate(width/2, height - 40); // Nullpunkt unten mittig
// Halbkreis-Ringe
for (int r = 100; r <= 380; r += 90) {
arc(0, 0, r*2, r*2, PI, TWO_PI);
}
// Winkellinien alle 30 Grad
for (int a = 0; a <= 180; a += 30) {
float x = cos(radians(a)) * 380;
float y = -sin(radians(a)) * 380;
line(0, 0, x, y);
}
}
void drawStrahl() {
stroke(0, 255, 0);
strokeWeight(3);
float x = cos(radians(winkel)) * 380;
float y = -sin(radians(winkel)) * 380;
line(0, 0, x, y);
strokeWeight(1);
}
void drawObjekt() {
if (abstand > 0 && abstand < 200) {
float pixel = map(abstand, 0, 200, 0, 380);
float x = cos(radians(winkel)) * pixel;
float y = -sin(radians(winkel)) * pixel;
stroke(255, 60, 60);
strokeWeight(8);
point(x, y);
strokeWeight(1);
}
}
// wird bei jedem '.' aufgerufen
void serialEvent(Serial p) {
daten = p.readStringUntil('.');
if (daten == null) return;
daten = trim(daten.replace(".", ""));
int komma = daten.indexOf(',');
if (komma > 0) {
winkel = int(daten.substring(0, komma));
abstand = int(daten.substring(komma + 1));
}
}
Startest du den Processing-Sketch, siehst du den gruenen Radarschirm mit rotierendem Strahl. Kommt ein Objekt in Reichweite, blitzt ein roter Punkt an der passenden Stelle auf – und verblasst dank der halbtransparenten Uebermalung langsam wieder, genau wie beim echten Radar.
5Ohne PC: Radar auf dem OLED
Willst du das Radar mobil und ohne Laptop betreiben, zeichnest du den Sweep direkt auf ein OLED-Display. Das Prinzip ist identisch – nur rechnest du die Polarkoordinaten jetzt auf dem Arduino und zeichnest per Adafruit_GFX. Der Kern der Zeichenroutine:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
// Nullpunkt unten mittig auf dem 128x64-Display
const int cx = 64;
const int cy = 62;
const int rMax = 58;
void zeichneRadar(int winkel, int abstandCm) {
display.clearDisplay();
// Halbkreis-Rahmen
display.drawCircle(cx, cy, rMax, SSD1306_WHITE);
display.drawFastHLine(cx - rMax, cy, rMax * 2, SSD1306_WHITE);
// Sweep-Strahl
int sx = cx + cos(radians(winkel)) * rMax;
int sy = cy - sin(radians(winkel)) * rMax;
display.drawLine(cx, cy, sx, sy, SSD1306_WHITE);
// Objekt (nur bis 100 cm anzeigen)
if (abstandCm > 0 && abstandCm < 100) {
int p = map(abstandCm, 0, 100, 0, rMax);
int ox = cx + cos(radians(winkel)) * p;
int oy = cy - sin(radians(winkel)) * p;
display.fillCircle(ox, oy, 2, SSD1306_WHITE);
}
display.display();
}
Diese Funktion rufst du in der Sweep-Schleife statt (oder zusaetzlich zu) sendePaar() auf. Wie du das OLED grundsaetzlich einrichtest und mit radians() rechnest, steht im OLED-SSD1306-Tutorial.
ℹ️ Speicher im Blick behalten: Der SSD1306-Framebuffer belegt schon 1 KB RAM – auf dem UNO mit 2 KB wird es mit vielen zusaetzlichen Variablen eng. Haelt dein Sketch Nachleuchten oder viele Objekte fest, lohnt der Umstieg auf einen ESP32 mit deutlich mehr RAM.
Troubleshooting
⚠️ Processing zeigt nichts / Port-Fehler: Der Serielle Monitor der Arduino IDE ist noch offen und blockiert den Port. Schliessen – immer nur ein Programm darf den COM-Port nutzen. Ausserdem Serial.list()[0] auf den richtigen Port anpassen.
⚠️ Baudrate stimmt nicht: Arduino und Processing muessen beide auf 115200 stehen, sonst kommt nur Zeichensalat an.
⚠️ Werte springen wild / UNO resettet: Der Servo zieht zu viel Strom aus der 5-V-Schiene. SG90 am USB testen, groessere Servos extern versorgen und Masse verbinden.
⚠️ Messung immer 400 cm: Trig/Echo vertauscht oder ein Kabel lose. Erst den reinen Mess-Sketch aus Schritt 2 pruefen.
⚠️ Radar "ruckelt": Der Servo braucht Zeit zum Bewegen. Erhoehe das delay() nach radarServo.write() leicht, damit der Sensor erst nach dem Anfahren des Winkels misst.
⚠️ Objekte tauchen am falschen Winkel auf: Sensor sitzt nicht mittig/gerade auf dem Servohorn. Mechanisch ausrichten, sodass 90° wirklich geradeaus zeigt.
🚀 Dein Radar-Starterpaket
Alle Bauteile fuer den Ultraschall-Scanner im Shop:
- HC-SR04 Ultraschallsensor – die Radarantenne (2er-Set)
- SG90 Micro-Servo – schwenkt den Sensor durch den Halbkreis
- UNO R3 Entwicklungsboard (USB-C) – Steuerzentrale des Radars
- 1,3 Zoll OLED-Display – Radar-Anzeige ohne PC
- MG996R Servo (Metallgetriebe) – mehr Drehmoment fuer groessere Aufbauten
- Breadboard 400 Kontakte – fuer den Testaufbau
Fazit
Aus einem HC-SR04 und einem SG90-Servo entsteht mit wenig Aufwand ein echtes Ultraschall-Radar. Du hast beide Bauteile einzeln getestet, zu einem Sweep-Sketch verbunden, ein robustes Datenprotokoll mit Trennzeichen entworfen und den klassischen gruenen Radarschirm in Processing zum Leben erweckt – oder wahlweise direkt auf dem OLED, ganz ohne PC.
Das Projekt ist ein perfekter Einstieg in zwei grosse Themen zugleich: Sensor-Fusion (Winkel plus Distanz) und die Kommunikation zwischen Mikrocontroller und PC-Grafik. Von hier aus kannst du das Radar auf einen fahrenden Roboter setzen, Objekte tracken oder mit einem Laser-Sensor die Aufloesung verbessern. Viel Spass beim Scannen!