Arduino Roboterauto bauen: Bluetooth-Auto Schritt für Schritt
Arduino Roboterauto bauen: Teileliste und Kosten, L298N- und HC-05-Verkabelung, 18650-Akkus, Fahr-Code, Handy-Steuerung und Lösungen für Schieflauf und Resets.
Ein Arduino-Auto zu bauen ist eine der schönsten Möglichkeiten, Elektronik und Programmieren in einem einzigen Projekt zu lernen. Mit zwei Getriebemotoren, einem L298N-Motortreiber, zwei 18650-Akkus, einem HC-05-Bluetooth-Modul und einem Arduino Uno baust du an einem Wochenende ein Roboterauto, das du mit dem Handy steuerst. Dabei erlebst du selbst, warum Motoren nicht direkt an den Arduino gehören, warum die Wahl des Akkus so wichtig ist und wie ein paar Zeilen Code ein echtes Fahrzeug bewegen.
In dieser Anleitung bauen wir gemeinsam ein 2WD-Roboterauto (zwei Motoren) von Anfang bis Ende: Teileliste und Kostenpunkte, Montage des Chassis, Verkabelungstabellen, Code für vorwärts, rückwärts und Kurven sowie Bluetooth-Steuerung per Handy. Die zwei Probleme, an denen Einsteiger am häufigsten hängen bleiben, nämlich dass das Auto nicht geradeaus fährt und dass der Arduino beim Anlaufen der Motoren neu startet, bekommen jeweils einen eigenen Abschnitt mit konkreten Lösungen. In den letzten Abschnitten erfährst du, wie du dasselbe Auto mit einem ESP32 oder einem Raspberry Pi Pico steuerst und es zu einem Roboter erweiterst, der Hindernissen ausweicht oder einer Linie folgt.




Wie funktioniert ein Arduino-Roboterauto?
Ein Roboterauto lässt sich in vier Teile gliedern. Der Arduino ist das Gehirn: Er liest den Befehl vom Handy und entscheidet, welcher Motor in welche Richtung und wie schnell dreht. Der L298N-Motortreiber ist der Muskel: Er wandelt die schwachen 5-V-Signale des Arduino in den hohen Strom um, den die Motoren brauchen. Die Getriebemotoren drehen die Räder, und der Akkupack versorgt alles mit Energie. Diese Autos haben keine Lenkung; sie lenken, indem sich die beiden Räder unterschiedlich schnell oder in unterschiedliche Richtungen drehen. Das nennt man Differentialantrieb: Dreht das linke Rad vorwärts und das rechte rückwärts, dreht sich das Auto auf der Stelle nach rechts. Eine kleine, frei drehbare Lenkrolle vorne oder hinten hält das Fahrzeug im Gleichgewicht.

| Eigenschaft | Gelber TT-Motor (1:48) |
|---|---|
| Betriebsspannung | 3–6 V |
| Übersetzung | 1:48 (Kunststoffgetriebe) |
| Leerlaufdrehzahl | Etwa 90–120 U/min bei 3 V, 200–250 U/min bei 6 V |
| Leerlaufstrom | Etwa 150–160 mA |
| Blockierstrom | Etwa 1,1–1,5 A |
| Raddurchmesser (in Bausätzen) | 65 mm |
| Geschwindigkeit des Autos bei 6 V | Etwa 0,7 m/s (π × 0,065 m × 200 / 60) |
Die wichtigste Zeile der Tabelle ist der Blockierstrom: Wenn ein Rad gegen ein Hindernis drückt oder das Auto anfährt, zieht jeder Motor kurzzeitig mehr als 1 Ampere. Ein Arduino-Pin liefert dagegen höchstens 20–40 mA, deshalb werden Motoren immer über einen Treiber angeschlossen. Der L298N verliert dabei etwa 1,5–2,5 V; mit einem 7,4-V-Akkupack bleiben für die Motoren 5–6 V übrig, genau der ideale Bereich für TT-Motoren. Den inneren Aufbau des Treibers und das Prinzip der H-Brücke erklären wir ausführlich in Gleichstrommotor mit dem L298N steuern.
Teileliste
| Teil | Anzahl | Hinweis |
|---|---|---|
| 2WD-Acryl-Chassis-Bausatz für Roboterautos | 1 | Meist mit 2 TT-Motoren, 2 Rädern, Lenkrolle, Schalter, Motorhaltern und Schrauben |
| Arduino Uno R3 (Klon reicht) + USB-Kabel | 1 | Ein Nano geht auch; die Pin-Nummern sind gleich |
| L298N-Motortreibermodul | 1 | 2 A pro Kanal; steuert zwei Motoren unabhängig |
| Bluetooth-Modul HC-05 oder HC-06 | 1 | Für die Verbindung mit einem Android-Handy |
| 18650-Li-Ionen-Akku | 2 | Markenzellen, die mindestens 5 A liefern können |
| 18650-Batteriehalter für 2 Zellen (in Reihe) | 1 | Schaltet beide Zellen in Reihe und liefert 7,4 V |
| 18650-Ladegerät | 1 | Ein Ladegerät, das jede Zelle einzeln lädt |
| Jumperkabel (Stecker-Buchse und Buchse-Buchse) | 20+ | Zwischen Arduino, L298N und HC-05 |
| Widerstände 1 kΩ und 2 kΩ | 1 + 1 | Spannungsteiler für den RXD-Eingang des HC-05 |
| Keramikkondensator 100 nF | 2–4 | An die Motoranschlüsse; unterdrückt Störungen |
| Elektrolytkondensator 470–1000 µF (16 V oder mehr) | 1 | Empfohlen; am Versorgungseingang des L298N |
| Kabelbinder, doppelseitiges Klebeband, M3-Abstandsbolzen | Einige | Zum Befestigen von Platinen und Kabeln |
Die meisten Chassis-Bausätze enthalten auch einen Batteriehalter für 4 AA-Zellen; wie du gleich sehen wirst, ist dieser zusammen mit dem L298N zu schwach, deshalb stehen 18650-Akkus auf der Liste. Der HC-06 ist der einfachere Bruder des HC-05, der nur als Slave arbeitet, und reicht für die Steuerung eines Autos per Handy völlig aus. Die geschlitzten Kunststoffscheiben im Bausatz sind Encoderscheiben für einen Drehzahlsensor, mit dem du das Auto später exakt geradeaus fahren lassen kannst; wirf sie nicht weg, sondern leg sie vorerst beiseite.
Kosten: Wohin fließt das Budget?
Die Preise ändern sich je nach Händler und Wechselkurs ständig, deshalb nennen wir keine Zahlen; stattdessen zeigen wir, welche Posten das Budget ausmachen und wo du sparen kannst. Die Faustregel lautet: Elektronikmodule (L298N, HC-05, Widerstände) sind günstig, der Großteil des Budgets geht in das Board, den Chassis-Bausatz und vor allem in Akkus und Ladegerät. Beim Akku solltest du zuletzt sparen: Gute 18650-Zellen lassen sich hunderte Male laden und in jedem weiteren Roboterprojekt wiederverwenden.
| Posten | Preisniveau | Spartipp |
|---|---|---|
| Chassis-Bausatz (mit Motoren und Rädern) | Mittel | Ein Bausatz ist meist günstiger als Motoren, Räder und Lenkrolle einzeln |
| Arduino Uno | Mittel (Klon) – hoch (Original) | Zum Lernen reicht ein Klon; du kannst auch deinen vorhandenen Uno oder Nano nutzen |
| L298N-Motortreiber | Niedrig | Ein Modul steuert zwei Motoren; auch für 4WD reicht eines |
| HC-05 / HC-06 | Niedrig – mittel | Wenn du nur per Handy fährst, genügt ein HC-06 |
| 2× 18650-Akku + Ladegerät | Größter Posten | Sehr billige Zellen mit "9900 mAh" sind meist Fälschungen; spar hier nicht |
| Kabel, Widerstände, Kondensatoren, Schrauben | Niedrig | Das meiste steckt schon in Starter-Kits |
2WD oder 4WD?
| Eigenschaft | 2WD (2 Motoren + Lenkrolle) | 4WD (4 Motoren) |
|---|---|---|
| Kurvenfahrt | Dreht scharf und leicht auf der Stelle | Dreht durch seitliches Rutschen der Räder (Skid Steering); hat auf Teppich Mühe |
| Stromaufnahme | Etwa 0,3–0,6 A beim Fahren | Etwa doppelt so viel |
| Akkulaufzeit | Länger | Kürzer |
| Unebener Boden | Die Lenkrolle kann an Kanten hängen bleiben | Besserer Grip |
| Geradeauslauf | Die Lenkrolle kann das Auto beim Umschwenken ablenken | Stabiler |
| Anschluss am L298N | Jeder Motor an einem eigenen Kanal | Die zwei Motoren einer Seite parallel an einem Kanal |
| Geeignet für | Das erste Auto, Linienfolger | Draußen, schwerere Lasten |
Für dein erstes Auto empfehlen wir 2WD: Es ist günstiger, braucht weniger Strom, dreht leicht auf der Stelle und eignet sich besser für Folgeprojekte wie einen Linienfolger. Baust du ein 4WD-Auto, schließe die zwei Motoren jeder Seite parallel an dieselben OUT-Klemmen an und prüfe, dass beide in dieselbe Richtung drehen. Ein L298N-Kanal trägt dann den Strom von zwei Motoren; im normalen Fahrbetrieb ist das kein Problem, aber wenn die Räder blockieren, kann die Grenze von 2 A pro Kanal überschritten werden und der Überhitzungsschutz des Treibers schaltet die Motoren ab.
Stromversorgung: Warum zwei 18650-Akkus?
Die meisten Probleme mit Roboterautos kommen vom falschen Akku. Die richtige Quelle muss zwei Bedingungen gleichzeitig erfüllen: Sie muss den Motoren nach dem Verlust im L298N noch genug Spannung lassen, und sie darf nicht einbrechen, wenn die Motoren beim Anfahren mehrere Ampere ziehen. Zwei 18650-Li-Ionen-Zellen in Reihe (2S) liefern voll geladen 8,4 V und im Mittel 7,4 V und schaffen problemlos mehrere Ampere. Der Arduino Uno empfiehlt für seinen VIN-Eingang 7–12 V, also kann derselbe Pack sowohl die Motoren als auch den Arduino versorgen. Mit 2500-mAh-Zellen fährt ein 2WD-Auto, das beim Fahren mit Motoren und Platinen im Schnitt 0,8 A zieht, theoretisch etwa 3 Stunden; da du den Akku nie ganz leer fährst, sind 2–2,5 Stunden realistischer. Mit deinen eigenen Werten rechnest du im Tool Akkulaufzeit.

| Stromquelle | Spannung | Belastbarkeit | Für ein Roboterauto |
|---|---|---|---|
| 9-V-Blockbatterie | 9 V | Sehr gering | Ungeeignet; häufigste Ursache für Resets |
| 4× AA Alkaline | 6 V (bricht unter Last schnell ein) | Mittel | Schwach; nach dem L298N kommen nur etwa 4 V an den Motoren an |
| 4× AA NiMH (Akku) | 4,8 V | Gut | Mit dem L298N zu wenig Spannung |
| 2× 18650 Li-Ion (2S) | 7,4 V (voll 8,4 V) | Hoch (mehrere Ampere) | Beste Wahl |
| 3× 18650 Li-Ion (3S) | 11,1 V (voll 12,6 V) | Hoch | Zu viel für TT-Motoren; überschreitet die 12-V-Grenze des 5V-Jumpers |
| USB-Powerbank | 5 V | Gut | Nur zur separaten Versorgung des Arduino |
Statt zu raten, wie voll der Akku noch ist, kannst du es messen. Verbinde den Pluspol des Akkus (nach dem Schalter) über einen Spannungsteiler aus zwei 10-kΩ-Widerständen mit A0: Ein 8,4-V-Pack erscheint an A0 als 4,2 V und bleibt unter der 5-V-Messgrenze des Arduino. Der Teiler zieht nur etwa 0,4 mA und beeinflusst die Laufzeit nicht.
1// Pil + (anahtardan sonra) → 10 kΩ → A0 → 10 kΩ → GND / battery + (after the switch) → 10 kΩ → A0 → 10 kΩ → GND
2const float DIVIDER = 2.0; // iki eşit direnç gerilimi yarıya böler / two equal resistors halve the voltage
3
4void setup() {
5 Serial.begin(9600);
6}
7
8void loop() {
9 float v = analogRead(A0) * 5.0 / 1023.0 * DIVIDER;
10 Serial.print(F("Pil / Battery: "));
11 Serial.print(v, 2);
12 Serial.println(F(" V"));
13 if (v < 6.6) Serial.println(F("Sarj et / Charge now")); // hücre başına 3,3 V / 3.3 V per cell
14 delay(1000);
15}Montage Schritt für Schritt
- Zieh die Schutzfolie von den Acrylteilen ab. Wenn die Motoren ohne Kabel geliefert wurden, löte an jeden Motor zwei Kabel und sichere die Lötstellen mit Heißkleber; ein durch Vibration abgerissenes Motorkabel ist der häufigste Defekt.
- Befestige die Motoren mit den T-förmigen Acrylhaltern und den langen M3-Schrauben aus dem Bausatz an der Unterseite des Chassis. Die beiden Motorwellen müssen fluchten, und die Kabelanschlüsse der Motoren sollten nach innen zeigen.
- Wenn du die Encoderscheiben nutzen willst, steck sie jetzt auf die Innenseite der Motorwelle; mit montierten Rädern ist das schwierig.
- Montiere die Lenkrolle mit Abstandsbolzen mittig am anderen Ende des Chassis. Wähle die Bolzenhöhe so, dass das Chassis parallel zum Boden steht.
- Schieb die Räder passend zur D-förmigen Welle ganz auf; ein lockeres Rad lässt das Auto ständig abdriften.
- Befestige den Batteriehalter mit doppelseitigem Klebeband oder Klettband so, dass sein Gewicht nahe an der Radachse liegt. Liegt das meiste Gewicht auf der Lenkrolle, rutschen die Antriebsräder durch.
- Montiere Arduino und L298N mit Kunststoff-Abstandsbolzen auf dem oberen Deck. Der USB-Anschluss des Arduino muss gut erreichbar sein und der Kühlkörper des L298N frei an der Luft liegen; achte darauf, dass Metallschrauben keine Lötstellen unter den Platinen berühren.
- Schalte den Schalter in Reihe mit dem Pluskabel des Akkus; so kannst du das Auto ein- und ausschalten, ohne die Zellen herauszunehmen.
- Verdrille die beiden Kabel jedes Motors auf dem Weg zum L298N, halte alle Kabel kurz und bündele sie mit Kabelbindern. Prüfe vor dem Einsetzen der Zellen mit einem Multimeter, dass zwischen den Akkuanschlüssen kein Kurzschluss besteht.
Schaltplan und Verkabelung
Denk dir die Verkabelung in zwei Teilen: die Leistungsseite (Akku, Schalter, L298N, Motoren) und die Signalseite (die dünnen Kabel vom Arduino zum L298N und zum HC-05). Zieh die kleinen Jumper von den ENA- und ENB-Pins des L298N ab; diese Pins verbinden wir mit den PWM-Ausgängen des Arduino, um die Geschwindigkeit per Code einzustellen. Der 5V-Jumper des L298N bleibt dagegen gesteckt: Da der Pack unter 12 V liegt, versorgt der eigene Spannungsregler der Platine die Logik des Treibers.

| L298N-Klemme | Anschluss |
|---|---|
| OUT1, OUT2 | Linker Motor (bei 4WD die beiden linken Motoren parallel) |
| OUT3, OUT4 | Rechter Motor (bei 4WD die beiden rechten Motoren parallel) |
| 12V | Pluspol des Akkus über den Schalter |
| GND | Minuspol des Akkus und GND-Pin des Arduino (gemeinsame Masse) |
| 5V | Beim Arduino Uno unbelegt; versorgt beim ESP32 und Pico das Board |
| 5V-Jumper | Bleibt gesteckt (Akku unter 12 V) |
| ENA- und ENB-Jumper | Werden entfernt; die Pins gehen an PWM-Ausgänge des Arduino |
| Verbindung | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| L298N ENA (Tempo linker Motor) | D5 (PWM) | GPIO 25 | GP15 |
| L298N IN1 | D7 | GPIO 27 | GP14 |
| L298N IN2 | D8 | GPIO 33 | GP13 |
| L298N ENB (Tempo rechter Motor) | D6 (PWM) | GPIO 26 | GP10 |
| L298N IN3 | D9 | GPIO 32 | GP12 |
| L298N IN4 | D4 | GPIO 4 | GP11 |
| HC-05 TXD | D10 (SoftwareSerial RX) | Nicht nötig (Bluetooth integriert) | GP1 (UART0 RX) |
| HC-05 RXD | D11, über 1-kΩ/2-kΩ-Teiler | Nicht nötig | GP0 (UART0 TX), direkt |
| HC-05 VCC | 5V | Nicht nötig | 5V-Ausgang des L298N |
| Versorgung des Boards | VIN ← Akku-Plus nach dem Schalter | 5V (VIN) ← 5V-Ausgang des L298N | VSYS ← 5V-Ausgang des L298N |
| GND | Gemeinsam mit L298N-GND und Akku-Minus | Gemeinsam | Gemeinsam |
D5 und D6 haben wir bewusst als Tempo-Pins gewählt. Auf dem Uno schaltet die Servo-Bibliothek die PWM an den Pins 9 und 10 ab, die Funktion tone() die an den Pins 3 und 11. Liegen ENA und ENB auf 5 und 6, funktioniert deine Geschwindigkeitsregelung auch dann noch, wenn du später einen Servo oder einen Summer ergänzt. D2 und D3 bleiben für Encoder frei, weil sie Interrupts unterstützen. Die Pinbelegung deines Boards siehst du im Tool Pinout.
Erster Sketch: vorwärts, rückwärts, links und rechts
Bevor es an Bluetooth geht, testen wir Motoren und Verkabelung für sich allein. Das Herz des Codes ist die Funktion drive(links, rechts): Sie nimmt die Geschwindigkeit jedes Motors getrennt von -255 bis 255 entgegen; ein positiver Wert heißt vorwärts, ein negativer rückwärts, null heißt Stopp. Wie aus dem Geschwindigkeitswert eine Spannung wird, erklären wir in Was ist PWM?. Stell das Auto vor dem Hochladen so auf eine Schachtel, dass die Räder frei drehen; die 3 Sekunden Wartezeit in setup() geben dir dafür Zeit.
1// Sol motor / left motor: ENA=5, IN1=7, IN2=8 — Sağ motor / right motor: ENB=6, IN3=9, IN4=4
2const int ENA = 5, IN1 = 7, IN2 = 8;
3const int ENB = 6, IN3 = 9, IN4 = 4;
4
5const int SPEED = 180; // temel hız 0-255 / base speed 0-255
6const int TRIM = 0; // % düzeltme: + sol, - sağ motoru yavaşlatır / % trim: + slows left, - slows right
7
8void drive(int left, int right) { // her biri -255 … 255 / each -255 … 255
9 if (TRIM > 0) left = left * (100 - TRIM) / 100;
10 if (TRIM < 0) right = right * (100 + TRIM) / 100;
11 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
12 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
13 analogWrite(ENA, abs(left));
14 analogWrite(ENB, abs(right));
15}
16
17void forward() { drive(SPEED, SPEED); }
18void backward() { drive(-SPEED, -SPEED); }
19void turnLeft() { drive(-SPEED, SPEED); } // yerinde sola / spin left in place
20void turnRight() { drive(SPEED, -SPEED); } // yerinde sağa / spin right in place
21void stopCar() { drive(0, 0); }
22
23void setup() {
24 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
25 for (int p : pins) pinMode(p, OUTPUT);
26 stopCar();
27 delay(3000); // tekerlekleri kaldırmak için zaman / time to lift the wheels
28}
29
30void loop() {
31 forward(); delay(1500);
32 stopCar(); delay(500);
33 backward(); delay(1500);
34 stopCar(); delay(500);
35 turnLeft(); delay(600);
36 stopCar(); delay(500);
37 turnRight(); delay(600);
38 stopCar(); delay(2000);
39}| Bewegung | Linker Motor | Rechter Motor | Code |
|---|---|---|---|
| Vorwärts | Vorwärts | Vorwärts | drive(180, 180) |
| Rückwärts | Rückwärts | Rückwärts | drive(-180, -180) |
| Auf der Stelle links drehen | Rückwärts | Vorwärts | drive(-180, 180) |
| Auf der Stelle rechts drehen | Vorwärts | Rückwärts | drive(180, -180) |
| Weite Linkskurve | Langsam vorwärts | Vorwärts | drive(90, 180) |
| Stopp | Steht | Steht | drive(0, 0) |
Mit den Rädern in der Luft sollte das Auto nacheinander vorwärts, rückwärts, nach links und nach rechts fahren. Dreht ein Rad falsch herum, änderst du nicht den Code, sondern tauschst die beiden Kabel dieses Motors an der OUT-Klemme des L298N. Drehen beide Räder falsch, tausch die Kabel beider Motoren. Brummen die Motoren nur, ohne zu drehen, ist der Wert SPEED zu niedrig: Die meisten TT-Motoren brauchen einen PWM-Wert von mindestens etwa 80–120, um anzulaufen, und diese Schwelle steigt, je leerer der Akku wird.
Bluetooth-Steuerung per Handy (HC-05)
Der HC-05 arbeitet wie ein kabelloses serielles Kabel zwischen Handy und Arduino: Die App auf dem Handy sendet einen Buchstaben, der Arduino liest ihn und führt die passende Bewegung aus. Die meisten Steuer-Apps, die du im Play Store unter "Bluetooth RC Car" oder "Bluetooth RC Controller" findest, senden F für vorwärts, B für rückwärts, L für links, R für rechts und beim Loslassen einer Taste S für Stopp; manche nutzen außerdem G, I, H und J für die Diagonalen sowie 0–9 und q für die Geschwindigkeit. Pins, LED-Signale und AT-Befehle des Moduls findest du in HC-05 Bluetooth-Modul.

- Beim Hochladen des folgenden Sketches kann der Schalter des Autos aus bleiben; Arduino und HC-05 werden über USB versorgt. Blinkt die LED des HC-05 schnell, wartet das Modul auf eine Verbindung.
- Such den HC-05 in den Bluetooth-Einstellungen deines Android-Handys und kopple ihn mit der PIN 1234 (notfalls 0000).
- Öffne die Steuer-App, erteile die Berechtigungen für Bluetooth und Geräte in der Nähe und wähle den HC-05 aus der Geräteliste. Nach dem Verbinden blinkt die LED des Moduls alle zwei Sekunden zweimal kurz.
- Lass den Arduino per USB verbunden, öffne den seriellen Monitor mit 9600 Baud und drück die Tasten in der App. Der Buchstabe jeder Taste erscheint auf dem Bildschirm; sendet deine App andere Buchstaben, passe die case-Zeilen im Code an.
- Zieh das USB-Kabel ab, schalte den Schalter ein, stell das Auto auf den Boden und fahr los.
1#include <SoftwareSerial.h>
2
3SoftwareSerial bt(10, 11); // RX, TX → HC-05 TXD, RXD (RXD bölücüyle / RXD via divider)
4
5const int ENA = 5, IN1 = 7, IN2 = 8; // sol motor / left motor
6const int ENB = 6, IN3 = 9, IN4 = 4; // sağ motor / right motor
7const int TRIM = 0; // % düzeltme / % trim
8const unsigned long TIMEOUT = 600; // ms; 0 = kapalı / 0 = disabled
9
10int speed = 200; // 0-255
11unsigned long lastCmd = 0;
12
13void drive(int left, int right) {
14 if (TRIM > 0) left = left * (100 - TRIM) / 100;
15 if (TRIM < 0) right = right * (100 + TRIM) / 100;
16 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
17 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
18 analogWrite(ENA, abs(left));
19 analogWrite(ENB, abs(right));
20}
21
22void setup() {
23 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
24 for (int p : pins) pinMode(p, OUTPUT);
25 drive(0, 0);
26 Serial.begin(9600); // gelen harfleri görmek için / to see incoming letters
27 bt.begin(9600); // HC-05 veri modu hızı / HC-05 data mode baud rate
28}
29
30void loop() {
31 if (bt.available()) {
32 char c = bt.read();
33 Serial.println(c);
34 lastCmd = millis();
35 int half = speed / 2;
36 switch (c) {
37 case 'F': drive(speed, speed); break; // ileri / forward
38 case 'B': drive(-speed, -speed); break; // geri / backward
39 case 'L': drive(-speed, speed); break; // yerinde sola / spin left
40 case 'R': drive(speed, -speed); break; // yerinde sağa / spin right
41 case 'G': drive(half, speed); break; // ileri-sol / forward-left
42 case 'I': drive(speed, half); break; // ileri-sağ / forward-right
43 case 'H': drive(-half, -speed); break; // geri-sol / back-left
44 case 'J': drive(-speed, -half); break; // geri-sağ / back-right
45 case 'S': drive(0, 0); break; // dur / stop
46 case 'q': speed = 255; break; // tam hız / full speed
47 default:
48 if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240); // hız kademesi / speed level
49 }
50 }
51 if (TIMEOUT > 0 && millis() - lastCmd > TIMEOUT) drive(0, 0); // komut yoksa dur / no command: stop
52}| Buchstabe | Bewegung | Linker / rechter Motor |
|---|---|---|
| F | Vorwärts | +Tempo / +Tempo |
| B | Rückwärts | −Tempo / −Tempo |
| L | Links auf der Stelle | −Tempo / +Tempo |
| R | Rechts auf der Stelle | +Tempo / −Tempo |
| G, I | Vorwärts links, vorwärts rechts | Eine Seite mit halbem Tempo |
| H, J | Rückwärts links, rückwärts rechts | Eine Seite mit halbem Tempo |
| S | Stopp | 0 / 0 |
| 0–9, q | Geschwindigkeitsstufe | 0 → 100, 9 → 240, q → 255 |
Das TIMEOUT im Code ist eine Sicherheitsfunktion: Solche Apps senden denselben Buchstaben immer wieder, solange du die Taste hältst; kommt 600 ms lang kein Buchstabe an, nimmt der Code an, dass die Verbindung abgebrochen ist, und stoppt das Auto. So fährt das Auto nicht weiter auf die Wand zu, wenn das Handy außer Reichweite gerät oder die App sich schließt. Sendet deine App den Buchstaben pro Tastendruck nur einmal, bleibt das Auto nach 600 ms stehen; setze TIMEOUT dann auf 0, um die Funktion abzuschalten. Außerdem haben wir in loop() nirgends delay() verwendet; lange Wartezeiten verzögern die Befehle, warum, liest du in millis() statt delay().
Das Auto fährt nicht geradeaus: Ursachen und Lösung
Wenn das Auto langsam zur Seite driftet, obwohl beide Motoren für "vorwärts" denselben PWM-Wert bekommen, keine Sorge: Das ist das häufigste Problem bei Roboterautos. Billige Getriebemotoren drehen selbst bei gleicher Spannung unterschiedlich schnell; Unterschiede bei Getriebereibung, Bürsten und Magneten machen jeden Motor ein wenig anders. Kommen ein lockeres Rad, eine ständig umschwenkende Lenkrolle oder einseitig verteiltes Gewicht hinzu, sind 20–30 cm Abweichung auf 2 Metern ganz normal. Beseitige zuerst die mechanischen Ursachen und gleiche den Rest per Software aus.
| Symptom | Mögliche Ursache | Lösung |
|---|---|---|
| Driftet immer zur gleichen Seite | Die Motoren laufen unterschiedlich schnell | Korrektur per Software mit TRIM oder Encoder |
| Schert beim Anfahren aus und fährt dann gerade | Ein Motor läuft später an oder die Lenkrolle schwenkt um | Sanftanlauf; Kugelrolle statt Lenkrolle |
| Abweichung jedes Mal anders | Lockeres Rad, rutschender Reifen oder verbogener Motorhalter | Rad ganz auf die Welle schieben, Schrauben nachziehen |
| Dreht auf der Stelle statt vorwärts zu fahren | Die Kabel eines Motors sind vertauscht | Kabel dieses Motors an der OUT-Klemme tauschen |
| Abweichung wächst mit leerem Akku | Bei niedriger Spannung wird der Unterschied zwischen den Motoren größer | Akku laden; TRIM mit vollem Akku einstellen |
| Zieht beim Beschleunigen zur Seite | Gewicht liegt auf einer Seite | Akku und Platinen mittig nahe der Radachse platzieren |
Sind die mechanischen Probleme behoben, folgt der Feinabgleich per Software. Die Konstante TRIM im Code bremst den schnelleren Motor prozentual: Ein positiver Wert bremst den linken, ein negativer den rechten Motor. So gleichst du ab:
- Lade die Zellen voll; ein Abgleich mit vollem Akku liefert gleichbleibende Ergebnisse.
- Klebe einen geraden, 2 Meter langen Klebestreifen auf den Boden und stell das Auto an seinen Anfang, in Richtung des Streifens.
- Lass in loop() des ersten Sketches nur forward() und 3 Sekunden Wartezeit stehen und lass das Auto fahren.
- Driftet das Auto nach rechts, ist der linke Motor schneller: Erhöhe TRIM um 3; driftet es nach links, verringere TRIM um 3.
- Wiederhole das, bis die Abweichung auf 2 Metern nur noch wenige Zentimeter beträgt, und übernimm denselben TRIM-Wert in den Bluetooth-Sketch.
- Gleiche bei der Geschwindigkeit ab, die du am häufigsten nutzt; der Unterschied zwischen den Motoren ändert sich mit dem Tempo leicht.
Die nächste Stufe für perfekten Geradeauslauf und Streckenmessung ist der Encoder. Du steckst die Scheiben mit 20 Schlitzen aus dem Bausatz auf die Motorwellen und zählst jeden Schlitz mit einem Gabellichtschranken-Drehzahlsensor auf Basis des LM393. Verbinde die Sensorausgänge mit den interruptfähigen Pins D2 und D3 und vergleiche die Impulszahlen beider Räder: Liegt die linke Seite vorn, bremst du den linken Motor etwas. Diese einfache Proportionalregelung (P-Regler) hält das Auto unabhängig von Akkustand und Untergrund auf Kurs. Ein 65-mm-Rad legt pro Umdrehung etwa 20,4 cm zurück, jeder Impuls entspricht also rund 1 cm Weg. Wie Interrupts funktionieren, erklären wir in Arduino Interrupts.
Der Arduino startet neu, wenn die Motoren anlaufen
Startet der Arduino neu oder verliert der HC-05 die Verbindung (die LED blinkt wieder schnell), wenn das Auto anfährt, die Richtung wechselt oder gegen ein Hindernis stößt, liegt das Problem fast immer bei der Stromversorgung. Beim Anfahren können zwei Motoren zusammen 2–3 A ziehen; ein schwacher Akku schafft das nicht und seine Spannung bricht kurz ein. Der Prozessor des Uno setzt sich zur Sicherheit zurück, wenn seine Versorgung unter 2,7 V fällt (Brown-out). Dazu kommen elektrische Störungen der Motorbürsten und der Spannungsabfall in dünnen Kabeln. Hier die Lösungen, beginnend mit der wirksamsten:
- Akku wechseln: Nimm zwei geladene 18650-Zellen statt einer 9-V-Blockbatterie oder müder AA-Zellen; damit sind die meisten Probleme erledigt.
- Richtiger Versorgungsweg: Versorge den Arduino über VIN aus dem Akku; schließe den 5V-Ausgang des L298N nicht an VIN an.
- Motorkondensatoren: Löte einen 100-nF-Keramikkondensator zwischen die beiden Anschlüsse jedes Motors; er unterdrückt das Bürstenfeuer direkt an der Quelle.
- Pufferkondensator: Schließe einen 470–1000-µF-Elko an die 12V- und GND-Klemmen des L298N an (Plus an 12V). Er deckt den kurzen Strombedarf beim Anfahren.
- Sanftanlauf: Erhöhe die Geschwindigkeit wie unten schrittweise, statt sofort auf 255 zu springen; der Stromstoß wird kleiner.
- Erst stoppen, dann umkehren: Direkt von vorwärts auf rückwärts zu schalten treibt den Motorstrom auf den Höchstwert; halte vor jedem Richtungswechsel 100–200 ms an.
- Dicke, kurze Stromkabel: Verwende zwischen Akku und L298N keine Jumperkabel und kein Breadboard; nimm Kabel mit mindestens 0,5 mm² und Schraubklemmen.
- Getrennte Versorgung: Hält das Problem an, versorge den Arduino aus einer Powerbank und die Motoren aus dem Akku und verbinde die beiden GNDs.
1// Yumuşak kalkış: ilk koddaki drive() ile kullan / soft start: use with drive() from the first sketch
2void rampTo(int target) {
3 for (int s = 60; s < target; s += 20) {
4 drive(s, s);
5 delay(15); // yaklaşık 10 adımda tam hız / full speed in about 10 steps
6 }
7 drive(target, target);
8}
9
10// Kullanım: forward() yerine rampTo(SPEED) / usage: rampTo(SPEED) instead of forward()Roboterauto mit ESP32 und Raspberry Pi Pico
Der ESP32 hat klassisches Bluetooth eingebaut, deshalb brauchst du keinen HC-05: Die Bibliothek BluetoothSerial baut dieselbe serielle Verbindung zum Handy auf, und die Steuer-Apps von oben funktionieren unverändert. Die Eingänge des L298N werten alles über etwa 2,3 V als HIGH, daher reichen die 3,3-V-Signale des ESP32. Versorge das ESP32-Board über den 5V-Ausgang des L298N am 5V-Pin (VIN) des Boards; schließe den Akku nicht direkt an diesen Pin an. Dieser Code lässt sich für ESP32-S3 und ESP32-C3 nicht kompilieren, weil diese nur BLE haben.
1#include "BluetoothSerial.h"
2
3BluetoothSerial bt;
4
5const int ENA = 25, IN1 = 27, IN2 = 33; // sol motor / left motor
6const int ENB = 26, IN3 = 32, IN4 = 4; // sağ motor / right motor
7
8int speed = 200; // 0-255
9unsigned long lastCmd = 0;
10
11void drive(int left, int right) {
12 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
13 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
14 analogWrite(ENA, abs(left));
15 analogWrite(ENB, abs(right));
16}
17
18void setup() {
19 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
20 for (int p : pins) pinMode(p, OUTPUT);
21 drive(0, 0);
22 bt.begin("BlueGrays-Car"); // telefonda görünecek ad / name shown on the phone
23}
24
25void loop() {
26 if (bt.available()) {
27 char c = bt.read();
28 lastCmd = millis();
29 switch (c) {
30 case 'F': drive(speed, speed); break; // ileri / forward
31 case 'B': drive(-speed, -speed); break; // geri / backward
32 case 'L': drive(-speed, speed); break; // yerinde sola / spin left
33 case 'R': drive(speed, -speed); break; // yerinde sağa / spin right
34 case 'S': drive(0, 0); break; // dur / stop
35 case 'q': speed = 255; break; // tam hız / full speed
36 default:
37 if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240);
38 }
39 }
40 if (millis() - lastCmd > 600) drive(0, 0); // komut yoksa dur / no command: stop
41}Der normale Raspberry Pi Pico hat kein Bluetooth, also schließt du den HC-05 an die UART0-Pins an. Da der Pico mit 3,3 V arbeitet, ist diesmal kein Spannungsteiler nötig. Versorge den Pico über den VSYS-Pin und den HC-05 direkt aus dem 5V-Ausgang des L298N; im Akkubetrieb ohne USB liegt am VBUS-Pin keine Spannung an. Im Pico-Code wird die Geschwindigkeit in Prozent von -100 bis 100 angegeben:
1from machine import Pin, PWM, UART
2import time
3
4bt = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) # GP0 → HC-05 RXD, GP1 ← HC-05 TXD
5
6ena = PWM(Pin(15)); ena.freq(1000) # sol motor hızı / left motor speed
7enb = PWM(Pin(10)); enb.freq(1000) # sağ motor hızı / right motor speed
8in1, in2 = Pin(14, Pin.OUT), Pin(13, Pin.OUT)
9in3, in4 = Pin(12, Pin.OUT), Pin(11, Pin.OUT)
10
11def drive(left, right): # -100 … 100 (%)
12 in1.value(left > 0); in2.value(left < 0)
13 in3.value(right > 0); in4.value(right < 0)
14 ena.duty_u16(int(abs(left) * 655))
15 enb.duty_u16(int(abs(right) * 655))
16
17speed = 80
18last = time.ticks_ms()
19drive(0, 0)
20
21while True:
22 if bt.any():
23 c = bt.read(1)
24 last = time.ticks_ms()
25 if c == b'F': drive(speed, speed) # ileri / forward
26 elif c == b'B': drive(-speed, -speed) # geri / backward
27 elif c == b'L': drive(-speed, speed) # yerinde sola / spin left
28 elif c == b'R': drive(speed, -speed) # yerinde sağa / spin right
29 elif c == b'S': drive(0, 0) # dur / stop
30 elif c == b'q': speed = 100 # tam hız / full speed
31 elif c and 48 <= c[0] <= 57: # '0'…'9' hız kademesi / speed level
32 speed = 40 + (c[0] - 48) * 6
33 if time.ticks_diff(time.ticks_ms(), last) > 600:
34 drive(0, 0) # komut yoksa dur / no command: stopNächste Schritte: Rüste dein Auto auf
- Hindernisvermeidender Roboter: Ergänze vorne einen HC-SR04-Abstandssensor und einen Servomotor, der ihn nach links und rechts schwenkt; Details in der Anleitung Hindernisvermeidender Roboter.
- Linienfolger: Bau 2–3 TCRT5000-Infrarotsensoren unter die Front und folge einer schwarzen Linie auf dem Boden; siehe Linienfolger-Roboter.
- Joystick-Fernbedienung: Bau mit einem zweiten Arduino, einem Joystick-Modul und einem nRF24L01 eine echte Fernbedienung ohne Handy.
- Infrarot-Fernbedienung: Fahr mit den Tasten deiner TV-Fernbedienung; ordne die Codes aus IR-Empfänger und Fernbedienung den Fahrbefehlen zu.
- Fahren per WLAN: Lass einen ESP32 eine Steuerseite bereitstellen, die sich im Browser deines Handys öffnet; die Grundlagen stehen in ESP32 Webserver und WebSocket.
- Encoder und Strecke: Fahr mit Drehzahlsensoren genau 1 Meter und dreh exakt 90 Grad; das ist die Grundlage für Labyrinth-Roboter.
- Roboterarm: Setz einen kleinen Roboterarm mit Servos auf das Auto und transportiere Gegenstände.



Häufige Fehler und Lösungen
- Kein Motor dreht sich: Die GNDs sind nicht verbunden, der Schalter ist aus, die ENA- und ENB-Jumper wurden entfernt, aber die Pins nicht angeschlossen, oder der Akku ist leer.
- Die LED des L298N leuchtet, aber die Motoren brummen nur: Der PWM-Wert liegt unter der Anlaufschwelle oder die Akkuspannung ist zu niedrig; erhöhe das Tempo und lade den Akku.
- Der Sketch lässt sich nicht hochladen: Vielleicht sind Port oder Board falsch gewählt; hast du den HC-05 an die Pins 0 und 1 angeschlossen, trenne ihn beim Hochladen. Weitere Ursachen in Arduino Sketch lässt sich nicht hochladen.
- Das Handy sieht den HC-05, verbindet sich aber nicht: Das Modul ist mit einem anderen Handy verbunden, der App fehlt die Berechtigung "Geräte in der Nähe" oder die Kopplungs-PIN ist falsch.
- Das Auto reagiert verzögert: In loop() steckt ein delay() oder es wird zu viel auf den seriellen Monitor geschrieben; erledige Wartezeiten mit millis().
- Der Kühlkörper des L298N wird sehr heiß: Die Räder klemmen oder bei 4WD ist der Strom pro Kanal zu hoch; prüfe die mechanische Reibung.
- Das Auto zuckt beim Einschalten kurz: Beim Start sind die Pins für einen Moment undefiniert; setze die Pins in den ersten Zeilen von setup() als Ausgänge und rufe drive(0, 0) auf.
Ein Arduino-Roboterauto ist ein großartiger Einstieg, der Motorsteuerung, Energieversorgung, Funkkommunikation und Fehlersuche in einem Projekt vermittelt. Am Ende hast du ein Fahrgestell, das mit jedem neuen Sensor ein bisschen schlauer wird. In der BlueGrays-App findest du die Projekte Bluetooth-gesteuertes Auto mit L298N, hindernisvermeidender Roboter und Schwarz-Weiß-Untergrunderkennung mit TCRT5000 Schritt für Schritt mit Schaltplänen und Code.
Häufige Fragen
Was braucht man, um ein Arduino-Auto zu bauen, und was kostet es?
Für ein einfaches Bluetooth-Auto genügen ein 2WD-Chassis-Bausatz (2 TT-Motoren, Räder, Lenkrolle), ein Arduino Uno, ein L298N-Motortreiber, ein HC-05-Bluetooth-Modul, zwei 18650-Akkus mit Halter und einige Jumperkabel. Die Preise hängen vom Händler ab; die Module sind günstig, der Großteil des Budgets geht in Board, Chassis-Bausatz sowie Akkus und Ladegerät. Hast du schon ein Starter Kit, sinken die Kosten deutlich.
Welchen Akku nimmt man für ein Arduino-Roboterauto?
Am besten zwei 18650-Li-Ionen-Zellen in Reihe: Sie liefern 7,4 V, lassen den Motoren nach dem Verlust von etwa 2 V im L298N noch 5–6 V und liefern den hohen Anlaufstrom. Eine 9-V-Blockbatterie kann nicht genug Strom liefern und verursacht Resets, mit 4 AA-Zellen laufen die Motoren am L298N nur langsam.
Warum fährt mein Arduino-Auto nicht geradeaus?
Billige Getriebemotoren drehen selbst beim gleichen PWM-Wert unterschiedlich schnell, und lockere Räder, die Lenkrolle und ungleich verteiltes Gewicht verstärken die Abweichung. Beseitige zuerst die mechanischen Ursachen und bremse dann den schnelleren Motor mit einem Korrekturwert (Trim) im Code etwas ab. Für exakten Geradeauslauf brauchst du Encoder, die die Drehzahl beider Räder messen und angleichen.
Warum startet mein Arduino neu, wenn die Motoren anlaufen?
Die Motoren ziehen beim Anfahren mehrere Ampere, und die Spannung eines schwachen Akkus bricht kurz ein; der Prozessor des Uno setzt sich zurück, wenn seine Versorgung abfällt. Nimm geladene 18650-Zellen, setze 100-nF-Kondensatoren an die Motoranschlüsse und einen 470–1000-µF-Kondensator an den Eingang des L298N und erhöhe die Geschwindigkeit schrittweise. Bleibt das Problem, versorge den Arduino aus einer eigenen Quelle und verbinde die GNDs.
Funktioniert ein Bluetooth-Auto mit HC-05 mit dem iPhone?
Nein. HC-05 und HC-06 nutzen das serielle Port-Profil des klassischen Bluetooth, und iOS erlaubt normalen Apps diese Verbindung nicht. Für die Steuerung per iPhone brauchst du ein BLE-Modul wie den HM-10 oder einen ESP32 mit BLE; Android-Handys verbinden sich problemlos mit dem HC-05.
Kann ich statt des L298N ein L293D-Motorshield verwenden?
Ja. Das L293D-Motorshield wird auf den Arduino Uno gesteckt und kann vier Gleichstrommotoren ansteuern, was die Verkabelung bei 4WD-Autos vereinfacht. Sein Dauerstrom liegt aber nur bei etwa 0,6 A pro Kanal, daher kommt es bei blockierenden Motoren schneller an seine Grenzen als der L298N, und das Shield belegt viele Pins. Effizienter sind MOSFET-Treiber wie der TB6612FNG, die deutlich weniger Spannung verlieren.
Projekte, die du danach bauen kannst
Alle Projekte ansehen
Bluetooth-gesteuertes Auto mit L298N
4WD-Roboterauto-Projekt mit vier Motoren und Allradantrieb, das vom Telefon aus mit Arduino und HC-05 Bluetooth-Modul gesteuert werden kann. Insgesamt vier Räder werden gleichzeitig angetrieben, indem

Roboter zur Hindernisvermeidung
Wie wäre es, ein intelligentes Fahrzeug zu bauen, das seinen Weg selbst findet? Der Obstacle Avoiding Robot scannt dank des Ultraschallsensors vor ihm ständig seine Umgebung. Wenn er auf ein Hindernis

LED per Bluetooth mit dem Handy steuern
Ein Projekt zur drahtlosen Steuerung, das LEDs mit Befehlen, die vom Telefon mit dem Bluetooth-Modul HC-06 gesendet werden, ein- und ausschaltet. Lehrt den Bluetooth-Datenaustausch über serielle Kommu

TCRT5000 Schwarz-Weiß-Untergrunderkennung
Projekt, das die Farbe des Bodens mit dem Sensor TCRT5000 erkennt und eine rote LED auf schwarzem Boden und eine grüne LED auf weißem Boden aufleuchten lässt. Es lehrt die Logik zur Erkennung von Farb

TCRT5000 Abstandsmessung
Projekt, das die von einer Oberfläche reflektierte Lichtmenge mit dem TCRT5000-Infrarotsensor misst und als Analogwert auf dem I2C-LCD-Bildschirm anzeigt. Lehrt die Grundlagen der optischen Abstands-/

HC-SR04 Abstandsmessung (serielle Anzeige)
HC-SR04 Ultraschallsensor zur Abstandsmessung und Anzeige des Ergebnisses in cm auf dem seriellen Monitor. Er lehrt das Prinzip der Abstandsberechnung mit Schallwellen.

Parksensor mit HC-SR04
Parksensor-Projekt mit HC-SR04-Sensor, der bei Annäherung an ein Objekt den Signalton erhöht und mit LED warnt. Lehrt Feedback-Logik proportional zur Entfernung.

Verwendung von Servomotoren
Grundlegendes Anwendungsprojekt, das den Servomotor nacheinander in 0°-, 90°- und 180°-Winkel positioniert. Lehrt die Servo-Bibliothek und die Logik der Winkelsteuerung.

