Hola controleros y controleras, en esta entrada aprenderemos a programar los Timer 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.
Timer con Micropython
Si viste nuestra entrada anterior sobre el uso de las interrupciones con MicroPython, esta entrada te será muy familiar.
Para el uso del Timer en MicroPython se debe importar el módulo machine , que nos dará acceso a las funciones necesarias para configurar y manejar las interrupciones del temporizador o Timer del microcontrolador empleado.
import machine
o de forma selectiva
from machine import Timer
Si va a utilizar alguna variable compartida entre la función de manejo de la interrupción por timer y el código principal debe utilizar una variable global para dicho fin.
Recuerde que toda interrupción debe ejecutarse lo más rápido posible y, por lo tanto, no debemos llamar a funciones como imprimir, o retardos dentro de ella.
A continuación se crea un objeto de clase Timer , que está disponible en el módulo machine. Con este objeto se configuran las interrupciones del temporizador o Timer en el microcontrolador Raspberry Pi Pico o en el NodeMCU ESP8266.
El constructor de esta clase recibe como entrada un valor numérico de 0 a 3, que indica el temporizador de hardware que se utilizará (La Raspberry Pi Pico y el ESP32 tiene 4 temporizadores de hardware). El ESP8266 posee 2 timers. Para este ejemplo, usaremos el temporizador 0.
tim = Timer()
Ahora necesitamos declarar nuestra función de manejo de la interrupción con el nombre que nosotros queramos.
Esta función recibe un argumento de entrada al que se le pasará un objeto de la clase Timer cuando se dispare la interrupción.
def temporizador(timer): #Variables globales compartidas con el main global contador, sentido #Lógica de la interrupción if sentido: contador += 1 else: contador -= 1
Ahora que hemos terminado la declaración de la función de manejo, se inicia el temporizador con una llamada al método init del objeto Timer creado previamente.
Las entradas de esta función son el período en el que ocurrirá la interrupción (especificado en milisegundos), el modo del temporizador (de un disparo o periódico) y la función de llamada que manejará la interrupción.
tim.init(period= 1000, mode=Timer.PERIODIC, callback=temporizador)
Argumentos clave:
mode
puede ser uno de:Timer.ONE_SHOT
– El temporizador funciona una vez hasta que expira el período configurado del canal.Timer.PERIODIC
– El temporizador funciona periódicamente a la frecuencia configurada del canal.period
– configura el periodo de la interrupción.
Cuando se modifican variables compartidas en el programa principal con la función de interrupción, se recomienda deshabilitar la interrupción, modificar la variable y posteriormente habilitar de nuevo la interrupción.
Entonces, deshabilitamos las interrupciones con una llamada a la función disable_irq del módulo machine. Esta función devolverá el estado de IRQ anterior, que almacenaremos en una variable.
Para volver a habilitar las interrupciones, simplemente llamamos a la función enable_irq , también desde el módulo machine, y pasamos como entrada el estado previamente almacenado. Entre estas dos llamadas, accedemos a la variable compartida y la modificamos.
state = machine.disable_irq() #modifica las variables globales machine.enable_irq(state)
Ejemplo con Timer
Convertir en temporizador, el proyecto de contador que vimos en el video pasado de los displays de 7 segmentos. El temporizador debe contabilizar exactamente los números de 0-9999 cada segundo.
main.py
""" USO DEL TIMER EN RASPBERRY PI PICO Display 7 Segmentos usando MicroPython Importación de nuestro propio módulo display7seg by: Sergio Andres Castaño Giraldo Referencia: https://controlautomaticoeducacion.com/ """ from machine import Pin, Timer import utime import display7seg def temporizador(timer): #Variables globales compartidas con el main global contador, sentido #Lógica de la interrupción if sentido: contador += 1 else: contador -= 1 def main(): global contador, sentido #Raspberry Pi PICO (4 digitos) display_pins = (16, 18, 13, 14, 15, 17, 12) #(a, b, c, d, e, f, g) transistor_pins = (22, 21, 20, 19) #NodeMCU 8266v3 (2 Digitos) #display_pins = (16, 5, 4, 0, 2, 14, 12) #transistor_pins = (13, 15) display7 = display7seg.Display(display_pins,transistor_pins = transistor_pins ) #Inicia las variables contador = 0 sentido = True tim = Timer() tim.init(period= 500, mode=Timer.PERIODIC, callback=temporizador) while True: #Muestra el valor del contador en el display #temporizacion(display7, contador) display7.show(contador) #Llamar la rutina MOSTRAR #Si contador es nueve coloque el sentido del contador a decrementar if contador == 9999: sentido = False #Si contador es cero coloque el sentido del contador a incrementar if contador == 0: sentido = True #Entry Point if __name__ == '__main__': main()
display7seg.py
""" Clase de Display 7 Segmentos usando MicroPython by: Sergio Andres Castaño Giraldo Referencia: https://controlautomaticoeducacion.com/ """ from machine import Pin import utime class Display: def __init__(self, Pins, kind = 'C', transistor_pins = 1): self.kind = kind self.number_digit = len(transistor_pins) #Configura los pines del display como salida display = list() for i in range(7): display.append( Pin(Pins[i], Pin.OUT) ) #Configura los pines de los transistores como salida transistors = list() for i in range(self.number_digit): transistors.append( Pin(transistor_pins[i], Pin.OUT) ) #Tupla con las posiciones del display self.display = display #Tupla con las posiciones de los transistores self.transistors = transistors def show(self, digits): #Realiza la multiplexación for i in range( self.number_digit ): number = int((digits % 10 ** (i+1)) / 10 ** i) self._show_one_display(number) self.transistors[i].on() utime.sleep_ms(1) self.transistors[i].off() #Metodo provado para mostrar número en un solo display def _show_one_display(self, digit): bit = 1; #Display Cátodo Común if self.kind.upper() == 'C': numbers = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) #Display Ánodo Común elif self.kind.upper() == 'A': numbers = (int('40',16),int('79',16),int('24',16),int('30',16),int('19',16),int('12',16),int('02',16),int('78',16),int('00',16),int('18',16)) else: return for i in range(7): if (numbers[digit] & bit) == 0: self.display[i].off() else: self.display[i].on() bit = bit << 1
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.