Hola controleros y controleras, en esta entrada aprenderemos a programar las salidas PWM con MicroPython y para eso usaremos la poderosa Raspberry Pi Pico o también el NodeMCU8266.
Antes de comenzar, te hago la invitación que aprendas a programar microcontroladores con nuestro Curso Gratuito de MicroPython.
Y que te suscríbas al canal si te interesa la programación de microcontroladores o la teoría del control.
Señal PWM
La señal PWM (Modulación por Ancho de Pulso) es una señal periódica configurable donde se puede modificar el ciclo de trabajo (Duty Cycle – En Ingles) utilizando el micropython.
Por ejemplo, el PWM de un PIN en una Raspberry pi Pico o en un ESP es simplemente una señal binaria (0v o 3.3v) que podremos configurar para que trabaje un determinado tiempo en Encendido o 3.3v y el resto de tiempo en Apagado o 0v, y repita este procedimiento infinitamente, pudiendo variar este ancho de pulso en cualquier instante, tal y como se puede observar en la siguiente figura:
Esto es interesante, porque el voltaje medio que se le aplica a la carga es proporcional al tiempo que la señal se mantuvo en 3.3v y con esto podemos lograr varias aplicaciones como controlar la luminosidad de un LED, la velocidad de un motor, regular resistencias calefactoras a través de relés de estado sólido, controlar un servomotor con una Raspberry Pi Pico o ESP, etc.
PWM en la Raspberry Pi Pico
Cada pin GPIO en la Raspberry Pi Pico puede ser configurado como salida PWM, pero el bloque de modulación de ancho de pulso (PWM) del microcontrolador RP2040 está compuesto por ocho segmentos, cada uno con dos salidas.
Si observamos el pinout de la Raspberry Pi Pico veremos que cada pin tiene una letra y un número entre corchetes. El número representa el segmento PWM conectado a ese pin; la letra representa qué salida del segmento es utilizado.
Se debe verificar que salidas de PWM se está utilizando, evitando conectar en nuestro proyecto pines con una combinación de letras y números que ya hayamos empleado.
Por ejemplo, si utilizamos el PWM_A[0] en el pin GP0 y el PWM_B[0] en el pin GP1, todo va a funcionar correctamente y continuará funcionando si agregamos un tercer PWM_A[1] en el pin GP2.
Sin embargo, si intentamos configurar para este caso el PWM del GP16, note que ese PWM ya está siendo usado por el GP0 ya que ambos están conectados a PWM_A[0]. Por lo tanto, tendríamos un conflicto si intentamos hacer esa configuración.
PWM ESP8266 y MicroPython
ESP8266 permite usar PWM por software en todos los pines de E / S: GPIO0 a GPIO16. Las señales PWM en ESP8266 tienen una resolución de 10 bits.
PWM con MicroPython
Para configurar un pin PWM en micropython necesitamos importar la clase PWM y la clase Pin del módulo machine.
from machine import Pin, PWM
Luego, creamos la instancia o objeto con el método PWM para la Raspberry Pi Pico:
led = PWM(Pin(15)) led.freq(frequancy)
O para la NodeMCU ESP8266 podemos hacerlo en una linea:
led = PWM(Pin(4), frequency)
Para crear un objeto PWM, debemos pasar como parámetros, el pin vamos a configurar, la frecuencia de la señal y el ciclo de trabajo.
led.duty_u16(duty_cycle)
Con MicroPython podemos asignar un ciclo de trabajo para la Raspberry Pi Pico un entero de 16 bits sin signo, el mismo formato de número que recibe del pin de entrada analógica. Esto se logra con el uso de la función duty_u16.
También podemos usar duty() que seria empleado en el NodeMCU ESP8266 v3 Lolin.
led.duty(duty_cycle)
Note que para configurar el PWM necesitamos dos parámetros: Frecuencia (frequency) y el ciclo de trabajo (duty_cycle)
- Frecuencia Raspberry Pi Pico : La frecuencia puede tener un valor entre 0 y 19200000. Se puede usar una frecuencia de 5000 Hz para controlar el brillo del LED.
- Ciclo de trabajo Raspberry Pi Pico: El ciclo de trabajo puede tener un valor entre 0 y 65535. En el cual 65535 corresponde al 100% del ciclo de trabajo (brillo total) y 0 corresponde al 0% del ciclo de trabajo (LED apagado).
- Frecuencia NodeMCU8266 : La frecuencia puede tener un valor entre 0 y 78125. Se puede usar una frecuencia de 5000 Hz para controlar el brillo del LED. Por defecto la placa está configurada a 1khz.
- Ciclo de trabajo NodeMCU8266: El ciclo de trabajo puede tener un valor entre 0 y 1023. En el cual 1023 corresponde al 100% del ciclo de trabajo (brillo total) y 0 corresponde al 0% del ciclo de trabajo (LED apagado).
El ciclo de trabajo podemos configurarlo en el loop principal del programa, por lo tanto no hay necesidad de establecer el ciclo de trabajo al crear una instancia PWM ya que será 0 por defecto.
Para configurar el ciclo de trabajo (duty Cycle), usamos el método duty() del objeto PWM creado y como parámetro de entrada le definimos el ciclo de trabajo deseado.
Dentro de mientras bucle, creamos un por bucle que aumenta el ciclo de trabajo en 1 en cada bucle con un intervalo de 5 ms entre cada cambio.
for duty_cycle in range(0, 65535): led.duty_u16(duty_cycle) sleep(0.005)
Medidor de Velocidad de un Motor DC con PIC
Motor DC con Encoder – Velocidad – Posición
Comunicación Serial Arduino Simulink/Matlab
Control de Velocidad de Motor DC con Micropython (PWM)
Para nuestro ejemplo vamos a realizar un control de velocidad de un motor DC usando el PWM de la Raspberry Pi Pico o de la NodeMCU8266v3 lolin y programado en micropython.
Como es de esperar, nuestra etapa de control será el microcontrolador, sin embargo, necesitamos una etapa de potencia que soporte el voltaje y la corriente del motor que deseamos manipular.
Como etapa de potencia, podemos usar un Mosfet IRFZ44N como un Switch, dado que es un dispositivo capaz de mover grandes potencias. La idea básica es que la señal PWM Swichee a alta velocidad el mosfet y de esa forma podremos regular la velocidad del motor DC como lo hicimos en el control de motor DC con Arduino o también en el control de motor DC con PIC.
Es muy importante colocar el diodo en paralelo al motor, para proteger el mosfet y nuestro microcontrolador de las corrientes inversas generados por la bobina del motor.
Sin embargo para esta práctica vamos a emplear el driver de puente H BTS7960 el cual es empleado para controlar motores de corriente continua de alta potencia, capaces de proporcionar hasta 43A de corriente a una tensión de alimentación de entre 6 a 27V.
Este driver funciona a con voltajes de 3.3V a 5V por lo cual es compatible con la raspberry pi pico y el nodemcu8266. Además, admiten realizar el control de la velocidad del motor mediante PWM con una frecuencia máxima de 25 kHz en ambas direcciones.
La ventaja de usar este módulo es que por ser un puente H podremos invertir el giro del motor facilmente.
En la implementación práctica, usaremos una motor de 12v, por lo tanto debemos usar dos fuentes de alimentación. Una para las Raspberry Pi Pico y otra para el motor. Recordar conectar ambas tierras de las fuentes, para crear una única tierra común.
El código en Micropython para la rapsberry pi pico y el NodeMCU8266 controlando la velocidad y el sentido de giro de un motor DC via PWM por medio de un potenciometro y un botón se muestra a continuación.
""" Programa de Ejemplo de PWM Control de Giro y Velocidad de un motor DC con Puente H by: Sergio Andrés Castaño Giraldo Sitio web: https://controlautomaticoeducacion.com/ Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo """ from machine import Pin, PWM, ADC from utime import sleep_ms def main(): #Placa -> Raspberry Pi Pico = True, ESP8266 = False placa= True frequency = 10000 #10Khz sentido = True #Sentido derecha if placa: potenciometro = ADC(26) #Raspberry Pi Pico ADC0 r_pwm = PWM(Pin(16)) #PWM derecha r_pwm.freq(frequency) l_pwm = PWM(Pin(17)) #PWM izquierda l_pwm.freq(frequency) boton = Pin(15, Pin.IN, Pin.PULL_UP) else: potenciometro = ADC(0) #NodeMCU8266v3 ADC0 r_pwm = PWM(Pin(4), frequency) #PWM derecha l_pwm = PWM(Pin(5), frequency) #PWM izquierda boton = Pin(2, Pin.IN, Pin.PULL_UP) while True: #Pregunta por el boton if not boton(): sleep_ms(200) #Anti-Rebote while not boton(): pass sleep_ms(200) #Anti-Rebote sentido = not sentido #Aplica el PWM al motor if placa: velocidad = potenciometro.read_u16(); if sentido: r_pwm.duty_u16(velocidad) l_pwm.duty_u16(0) else: r_pwm.duty_u16(0) l_pwm.duty_u16(velocidad) else: velocidad = potenciometro.read(); if sentido: r_pwm.duty(velocidad) l_pwm.duty(0) else: r_pwm.duty(0) l_pwm.duty(velocidad) sleep_ms(5) if __name__ == '__main__': main()
Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:
👉 Invitar a Sergio a un Café ☕️
Que esten muy bien, nos vemos en la siguiente entrada.
Mi nombre es Sergio Andres Castaño Giraldo, y en este sitio web voy a compartir una de las cosas que mas me gusta en la vida y es sobre la Ingeniería de Control y Automatización. El sitio web estará en constante crecimiento, voy a ir publicando material sobre el asunto desde temas básicos hasta temas un poco más complejos. Suscríbete al sitio web, dale me gusta a la página en Facebook y únete al canal de youtube. Espero de corazón que la información que comparto en este sitio, te pueda ser de utilidad. Y nuevamente te doy las gracias y la bienvenida a control automático educación.