Zum Inhalt springen

Code Struktur

Bisher haben wir unseren gesamten Code in der main.py geschrieben. Und die Bibliotheken für die Sensoren lagen im gleichen Ordner. Das funktioniert für kleine Projekte gut, aber wenn der Code wächst, wird es schnell unübersichtlich. In diesem Kapitel schauen wir uns an, wie wir unseren Code sinnvoll auf mehrere Dateien und Ordner aufteilen können.

Stellen Sie sich vor, Sie suchen einen Fehler in Ihrem Code. Wenn alle 300 Zeilen in einer einzigen main.py stecken, ist das wie die Suche nach einer Nadel im Heuhaufen.

Gute Code-Struktur bringt folgende Vorteile:

  • Übersichtlichkeit – Sie finden sofort, was Sie suchen.
  • Wiederverwendbarkeit – Einzelne Module können in anderen Projekten genutzt werden.
  • Teamarbeit – Mehrere Personen können gleichzeitig an unterschiedlichen Modulen arbeiten.
  • Testbarkeit – Einzelne Teile lassen sich gezielt testen.

Für ein Micromouse-Projekt empfehlen wir folgende Aufteilung:

micromouse/
├── main.py # Einstiegspunkt – startet das Programm
├── controller.py # State Machine & Hauptschleife
├── config.py # Zentrale Konfiguration (Pins, Konstanten)
├── lib/ # Drittanbieter-Treiber (unverändert übernommen)
│ ├── hcsr04.py
│ └── mpu6050.py
└── components/ # Eigene Logikklassen
├── motor.py # DCMotor – Motoransteuerung
└── sensor.py # UltrasonicSensor, IMUSensor, ...

Die Idee dahinter ist eine klare Trennung in drei Ebenen:

EbeneOrdnerInhalt
Steuerung/ (root)main.py, controller.py, config.py
Eigene Logikcomponents/Ihre eigenen Klassen für Motoren und Sensoren
Fremde Treiberlib/Unveränderte Bibliotheken von Drittanbietern

Die main.py ist die erste Datei, die nach dem Booten ausgeführt wird. Sie sollte so kurz wie möglich sein und nur das Nötigste tun:

  1. Den Controller importieren
  2. Eine Instanz erstellen
  3. Den Controller starten
main.py
from controller import Controller
robot = Controller()
robot.run()

Mehr gehört hier nicht rein. Die eigentliche Logik liegt in controller.py.


Alle Pin-Nummern, Schwellwerte und Konstanten gehören in eine zentrale Konfigurationsdatei. So müssen Sie bei einer Änderung der Verkabelung nur eine Datei anpassen.

config.py
# --- Motor Pins (IN1, IN2) ---
LEFT_MOTOR_PINS = (5, 18)
RIGHT_MOTOR_PINS = (19, 21)
# --- Sensor Pins (TRIGGER, ECHO) ---
FRONT_SENSOR_PINS = (26, 25)
# --- Schwellwerte ---
WALL_DISTANCE_CM = 15 # Ab wann gilt eine Wand als vorhanden?
BASE_SPEED = 40000 # Standard-Fahrgeschwindigkeit (0–65535)

Der Controller ist das Herzstück Ihres Roboters. Er kennt alle Komponenten und koordiniert ihr Zusammenspiel. Die Hauptschleife fragt in jedem Durchlauf den aktuellen Zustand ab und entscheidet, was als nächstes passiert – das nennt man eine State Machine.

controller.py
from components.motor import DCMotor
from components.sensor import UltrasonicSensor
from config import LEFT_MOTOR_PINS, RIGHT_MOTOR_PINS, FRONT_SENSOR_PINS
class Controller:
def __init__(self):
self.left_motor = DCMotor(*LEFT_MOTOR_PINS)
self.right_motor = DCMotor(*RIGHT_MOTOR_PINS)
self.sensor = UltrasonicSensor(*FRONT_SENSOR_PINS)
def run(self):
while True:
self._update()
def _update(self):
pass # Hier kommt die State Machine hin

Die DCMotor-Klasse für diese Datei haben Sie bereits im Kapitel Motoren ansteuern kennengelernt. Legen Sie sie einfach als components/motor.py auf Ihrem Gerät ab.


Alle eigenen Sensorklassen kommen in diese Datei. Sie importieren die rohen Treiber aus lib/ und fügen darüber eine saubere, einheitliche Schnittstelle hinzu – z.B. Fehlerbehandlung oder Einheitenumrechnung.

components/sensor.py
from lib.hcsr04 import HCSR04
from lib.mpu6050 import MPU6050
class UltrasonicSensor:
def __init__(self, trigger_pin, echo_pin):
self._sensor = HCSR04(trigger_pin=trigger_pin, echo_pin=echo_pin)
def distance_cm(self):
try:
return self._sensor.distance_cm()
except OSError:
return 999 # Kein Echo empfangen → Hindernis außer Reichweite
class IMUSensor:
def __init__(self, i2c):
self._imu = MPU6050(i2c)
def heading(self):
"""Gibt die aktuelle Ausrichtung in Grad zurück."""
return self._imu.heading()

In diesem Ordner landen alle Bibliotheken, die Sie von außen übernehmen – zum Beispiel hcsr04.py oder mpu6050.py. Sie werden unverändert auf das Gerät kopiert und von den Klassen in components/ genutzt.

lib/
├── hcsr04.py # Treiber für den Ultraschallsensor HC-SR04
└── mpu6050.py # Treiber für das Gyroskop/Beschleunigungssensor MPU-6050
Datei / OrdnerZuständigkeit
main.pyEinstiegspunkt, startet den Controller
controller.pyState Machine, Hauptschleife, koordiniert alle Komponenten
config.pyPins, Konstanten, Schwellwerte
components/motor.pyDCMotor – Geschwindigkeit und Richtung
components/sensor.pyEigene Sensorklassen mit sauberer Schnittstelle
lib/Unveränderte Drittanbieter-Treiber
  • Ich habe verstanden, dass diese Struktur eine Hilfe sein soll und nicht zwingend so umgesetzt werden muss.