1

I am using an ESP32 with MicroPython to control a motor driver. I have created a class for the motor that allows me to set the motor's power using a setPower method. However, I have encountered an issue where the GPIO pin used to control the motor only activates (sets to "high") if I call setPower(1) inside a while loop. If I try to activate the motor before the loop, the pin does not remain active.

I even added timeouts hoping it was just a boot issue, but that didn't work.

from lib.Driver import *
from time import sleep_ms as delay

delay(3000)  # Wait 3 seconds to let the ESP32 boot

p = Motor(PORT_1A)   # Create Motor instances
p2 = Motor(PORT_2A)

driver = TB6612FNG(p, p2, STBY_A)

print("Pin activated")
driver.motorB.setPower(1)  # Attempt to set power to 1 before the loop

while True:
    delay(1000)  # Wait 1 second
    print("Running...")

Observed Behavior:

  • The motor does not activate when driver.motorB.setPower(1) is called outside the while loop.
  • If I move driver.motorB.setPower(1) inside the while loop, the motor activates and runs as expected.
  • If I remove the while loop completely, the motor activates as well. Here is the version that works correctly:

I thought it was perhaps a problem caused because the Esp32 did not maintain the high state of the pin, but even when I put a 10 second sleep in the loop, the pin does not return to a low state.

This is the code that "works":


from lib.Driver import *
from time import sleep_ms as delay


p = Motor(PORT_1A)
p2 = Motor(PORT_2A)


driver = TB6612FNG(p, p2, STBY_A);

while True:
    
    driver.motorB.setPower(1)
    

I also thought it was because of my esp's firmware, but I tried with the last two versions: v1.24.1 (2024-11-29) .bin / [.app-bin] / [.elf] / [.map] / [Release notes] (latest) v1.24.0 (2024-10-25) .bin / [.app-bin] / [.elf] / [.map] / [Release notes]

and the same thing happens with both.

This is the code I use to control the TB6612FNG H-bridge:

from machine import Pin, PWM
import time

PORT_1A = [26,25,27]
PORT_2A = [32,4,0]
STBY_A = 33

PORT_1B = [15,16,2]
PORT_2B = [18,19,23]
STBY_B = 17



class Motor:
    def __init__(self, *args):
        
        if len(args)==1 and isinstance(args[0], list):
            p = args[0]
            
            in1 = p[0]
            in2 = p[1]
            pwm_pin = p[2]
        elif len(args)==3:
            in1 = args[0]
            in2 = args[1]
            pwm_pin = args[2]
        else:
            raise ValueError("se requieren 3 argumentos o una lista")
        """
        Clase para controlar un motor individual.
        :param in1: Pin para la dirección IN1.
        :param in2: Pin para la dirección IN2.
        :param pwm_pin: Pin PWM para la velocidad.
        """
        self.in1 = Pin(in1, Pin.OUT)
        self.in2 = Pin(in2, Pin.OUT)
        self.pwm = PWM(Pin(pwm_pin), freq=1000)  # PWM a 1 kHz
        self.direction = 1  # Dirección predeterminada
        self.stop()  # Por seguridad, inicializa el motor detenido

    def set_direction(self, direction):
        """
        Configura la dirección del motor.
        :param direction: 'forward' para dirección normal o 'reverse' para invertir el giro.
        """
        if direction in ['forward', 'reverse']:
            self.direction = 1 if direction == "forward" else -1
        else:
            raise ValueError("La dirección debe ser 'forward' o 'reverse'.")

    def setPower(self, power):
        """Controla la velocidad y dirección del motor.
        Parámetro power: -1 (máxima velocidad atrás) a 1 (máxima velocidad adelante).
        """
        power = max(min(1, power), -1)

        self.duty_cycle = abs(int(power * 1023))  # Convierte el valor en 0-1023 (PWM)

        if power == 0:
            # Detener el motor
            self.in1.value(0)
            self.in2.value(0)
            self.pwm.duty(0)
        elif power * self.direction > 0:
            # Adelante
            self.in1.value(1)
            self.in2.value(0)
            self.pwm.duty(self.duty_cycle)
        else:
            # Atrás
            self.in1.value(0)
            self.in2.value(1)
            self.pwm.duty(self.duty_cycle)

    def stop(self):
        """
        Detiene el motor.
        """
        self.in1.off()
        self.in2.off()
        self.pwm.duty(0)


class TB6612FNG:
#     def __init__(self, ain1, ain2, pwma, bin1, bin2, pwmb, stby):
#         """
#         Clase para controlar el controlador TB6612FNG con dos motores.
#         :param ain1, ain2, pwma: Pines del Motor A.
#         :param bin1, bin2, pwmb: Pines del Motor B.
#         :param stby: Pin de Standby (habilitación).
#         """
#         self.stby = Pin(stby, Pin.OUT)
#         self.stby.on()  # Activa el controlador (quita Standby)
# 
#         # Inicialización de los dos motores usando la clase Motor
#         self.motorA = Motor(ain1, ain2, pwma)
#         self.motorB = Motor(bin1, bin2, pwmb)
    def __init__(self, *args):
        
        if len(args)==1 and isinstance(args[0], list):
            p = args[0]
            if len(args[0])==7:    
                ain1 = p[0]
                ain2 = p[1]
                pwma = p[2]
                bin1 = p[3]
                bin2 = p[4]
                pwmb = p[5]
                
                stby = p[6]
            else:
                raise ValueError("se requieren 7 argumentos correspondientes a los 7 pines")
        elif len(args)==7:
            ain1 = args[0]
            ain2 = args[1]
            pwma = args[2]
            bin1 = args[3]
            bin2 = args[4]
            pwmb = args[5]
            
            stby = args[6]
        elif len(args)==3:
            self.motorA = args[0]
            self.motorB = args[1]
            self.stby = Pin(args[2], Pin.OUT)
            self.stby.on()
        else:
            raise ValueError("se requieren los 7 pines del driver o 1 lista que los contenga a todos")
            
        """
        Clase para controlar el controlador TB6612FNG con dos motores.
        :param ain1, ain2, pwma: Pines del Motor A.
        :param bin1, bin2, pwmb: Pines del Motor B.
        :param stby: Pin de Standby (habilitación).
        """
        
        if(self.motorA is None):
            self.stby = Pin(stby, Pin.OUT)
            self.stby.on()  # Activa el controlador (quita Standby)

            # Inicialización de los dos motores usando la clase Motor
            self.motorA = Motor(ain1, ain2, pwma)
            self.motorB = Motor(bin1, bin2, pwmb)

    def standby_on(self):
        """Activa el modo Standby."""
        self.stby.off()

    def standby_off(self):
        """Desactiva el modo Standby."""
        self.stby.on()



0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.