Um einen Motor über den Motortreiber L298 am ESP32 zu betreiben, benötigt man drei GPIO-Pins des ESP32, für ENA, IN1 und IN2. Für den Betrieb eines zweiten Motors wären dann noch drei weitere GPIO-Pins erforderlich, wir betrachten aber zunächst nur einen Motor.

Man verbindet die Pins mit den entsprechenden Eingängen des L298. Dieser wird extern mit Strom versorgt. Wir verbinden den Ground der externen Stromversorgung zudem mit Ground des ESP32.

Fritzing L298 am ESP32

Wir verwenden

  • Pin 4 für ENA
  • Pin 2 für IN1
  • Pin 15 für IN2

Der ESP32 wird hier per USB mit Strom versorgt.

In MicroPython erstellen wir eine Klasse Motor, die universell genutzt werden kann:

from  machine import Pin, PWM

class Motor:
    def __init__(self, ena_nr, in1_nr, in2_nr):
        self.ena = Pin(ena_nr, Pin.OUT)
        self.in1 = Pin(in1_nr, Pin.OUT)
        self.in2 = Pin(in2_nr, Pin.OUT)
        self.pwm_ena = PWM(self.ena)
        self.pwm_ena.freq(500) # 500 Hz funktioniert gut

    def set_speed(self,speed=100):
        if speed > 100:
            speed = 100
        if speed < 0:
            speed = 0
        duty = int(1023 * speed / 100)      
        self.pwm_ena.duty(duty) 

    def forward(self, speed=100):
        self.set_speed(speed)
        self.in1.value(1)
        self.in2.value(0)

    def backward(self,speed=100):
        self.set_speed(speed)        
        self.in1.value(0)
        self.in2.value(1)

    def stop(self):
        self.in1.value(0)
        self.in2.value(0)

Dem Konstruktor __init__ werden die GPIO-Pin-Nummern von ena, in1 und in2 übergeben. Die zugehörigen Pins werden als Ausgang konfiguriert. Auf dem ena-Pin wird PWM konfiguriert, siehe hierzu den Post über PWM.

Mit Aufruf der Methode forward bewegt sich der Motor durch Setzen der Werte für in1 und in2 vorwärts, beim Aufruf von backward bewegt er sich rückwärts. Dabei kann ein Geschwindigkeitswert zwischen 0 und 100 angegeben werden. Höhere, bzw. niedrige Werte führen zu einer Geschwindigkeit von 100 bzw. 0.

Beim Aufruf von stop hält der Motor an.

Die Klasse Motor kann wie folgt genutzt werden:

# Motor-Objekt erzeugen, die Pin-Nummern werden als Parameter übergeben
motor1 = Motor(ena_nr=4,in1_nr=2,in2_nr=15)
# Vorwärts drehen
motor1.forward()
# Zwei Sekunden lang
time.sleep(2)
# Vorwärts drehen mit halber Geschwindigkeit
motor1.forward(50)
time.sleep(2)
# Rückwärts drehen
motor1.backward()
time.sleep(2)
# Rückwärts drehen mit 70% Geschwindigkeit
motor1.backward(70)
time.sleep(2)
motor1.stop()

Man kann auch die Klasse Motor so erweitern, dass man die in die jeweilige Richtung zu fahrende Zeit in ms als Parameter an die Methoden forward und backward mitgeben kann:

class TimeMotor(Motor):
    def forward(self, speed=100, ms=None):
        self.in1.value(1)
        self.in2.value(0)
        if ms:
            time.sleep_ms(ms)
            self.stop()        

    def backward(self,speed=100, ms=None):
        self.in1.value(0)
        self.in2.value(1)
        if ms:
            time.sleep_ms(ms)
            self.stop()

Die Klasse TimeMotor erbt dabei alle Methoden - auch den Konstruktor - von der Klasse Motor. Die Methoden forward und backward werden überschrieben und erhalten einen optionalen weiteren Parameter ms für die in die jeweilige Richtung zu fahrenden Millisekunden. Wird ms nicht angegeben, verhalten sich Objekte der Klasse TimeMotor wie Objekte der Klasse Motor.

Die Nutzung sieht folgendermaßen aus:

motor2 = TimeMotor(ena_nr=4,in1_nr=2,in2_nr=15)
motor2.forward(ms=2000)
motor2.backward(ms=5000)