Source code for openbricks.drivers.l298n

# SPDX-License-Identifier: MIT
"""
L298N H-bridge motor driver.

The L298N drives a brushed DC motor via two direction pins (IN1/IN2) and one
PWM pin (EN-A or EN-B). It's open-loop: the class knows nothing about the
physical motor speed or position. For closed-loop use, wrap one of these in
``jgb37_520.JGB37Motor`` (which adds an encoder).

Pinout recap for one channel::

    IN1  = direction bit A
    IN2  = direction bit B
    PWM  = enable / speed (tie to VCC for 100%, PWM for speed control)

    IN1  IN2  result
    ---  ---  ----------
     0    0   coast
     0    1   reverse
     1    0   forward
     1    1   brake
"""

from machine import Pin, PWM

from openbricks.interfaces import Motor

_PWM_FREQ_HZ = 20_000  # Above audible range; fine for most hobby H-bridges.
_DUTY_MAX = 1023       # ESP32 default PWM resolution.


[docs] class L298NMotor(Motor): def __init__(self, in1, in2, pwm, invert=False, pwm_freq=_PWM_FREQ_HZ): """ Args: in1, in2: GPIO numbers for the two direction pins. pwm: GPIO number for the EN pin (speed/duty). invert: swap forward/reverse. Handy when wiring goes the wrong way. pwm_freq: PWM frequency in Hz. """ self._in1 = Pin(in1, Pin.OUT, value=0) self._in2 = Pin(in2, Pin.OUT, value=0) self._pwm = PWM(Pin(pwm), freq=pwm_freq, duty=0) self._invert = invert
[docs] def run(self, power): """Power is -100..100.""" if power > 100: power = 100 elif power < -100: power = -100 if self._invert: power = -power if power > 0: self._in1.value(1) self._in2.value(0) elif power < 0: self._in1.value(0) self._in2.value(1) else: self._in1.value(0) self._in2.value(0) duty = int(abs(power) * _DUTY_MAX / 100) self._pwm.duty(duty)
[docs] def brake(self): """Short both terminals — active brake.""" self._in1.value(1) self._in2.value(1) self._pwm.duty(_DUTY_MAX)
[docs] def coast(self): """Cut drive entirely — motor spins freely.""" self._in1.value(0) self._in2.value(0) self._pwm.duty(0)