Objetivos
Material requerido
Raspberry Pi 3 o equivalente |
1xDiodos LED | |
Algunos cables de Protoboard. | |
Una Protoboard . |
Raspberry Pi y las salidas analógicas
Hasta ahora hemos usado señales digitales en nuestra relación con el mundo exterior,tanto para para leer como para enviar mensajes. Pero naturalmente, el mundo exterior es más bien analógico la mayor parte de las veces y necesitamos algún medio de enviar y recibir señales analógicas a nuestros dispositivos externos.
Por ejemplo ya vimos que con una señal digital podemos encender y apagar un LED pero ¿Qué pasa si tenemos el día caprichoso y queremos variar el brillo de nuestro led (Dimming)?
Pues naturalmente que de algún modo tendremos que enviar una señal proporcional al valor de intensidad que queremos producir en la intensidad del led… y aquí salta el primer problema: Puedo enviar unos y ceros pero no enviar medios valores o tercios… así que ¿Ahora qué?
Para los que venís del mundo Arduino o electrónico la solución es obvia: una señal PWM. Pero para los que están empezando con esto, necesitamos comentar un poco que es algo de nombre tan amenazador y de paso como controlarlo con nuestra vieja Raspberry.
Y esta es una de esas ocasiones en que para poder continuar tenemos que empezar con uno de esos rollitos teóricos que tanto nos gustan y que espero no asusten a nadie, porque como siempre es una idea muy sencilla, y astuta, que nos resuelve un problema peliagudo mediante un ingenioso truco que os aseguro que es mucho más fácil de lo que parece al principio.
Las señales PWM
Suponte que tienes el grifo abierto, llenándote un vaso de agua y te das cuenta de que estas a punto de alcanzar el límite. Normalmente no cerramos de golpe el grifo para cortarlo. Más bien giras el grifo controladamente para controlar el volumen de agua que pasa y disminuir el caudal saliente.
Y a medida que te acercas al límite continuas girando el grifo y disminuyendo el paso de agua para poder afinar con precisión en la altura exacta de agua que deseas en el vaso.
Estoy seguro de que tienes dominado el procedimiento. Es tan habitual que no pensamos mucho en ello. En realidad estás haciendo una regulación automática del flujo de agua, controlando el caudal que permites y como lo haces con un grifo mecánico, estas modificando de modo analógico el caudal de agua que el permites salir.
Pero, si intentamos hacer algo así con un sistema digital tenemos un pequeño lio, porque digitalmente puedo abrir el grifo (1) o cerrarlo (0) pero no puedo modificar el flujo de una manera sencilla.
Podemos claro está, abrir y cerrar el grifo rápida y sucesivamente para r permitiendo que pequeños chorros de agua vayan saliendo y si somos un poco hábiles conseguiremos una buena aproximación a llenar el vaso sin derramarlo, pero suena un poco raro ¿No? Tenemos que ser rápidos y precisos. Algo que no se nos suele dar muy bien pero que curiosamente a los ordenadores se les da genial.
Por eso, cuando tenemos que usar un sistema digital que simule una señal analógica podemos usar una señal PWM (Pulse Width Modulation) donde hacemos exactamente eso: Abrir y cerrar con rapidez el grifo electrónico con suficiente velocidad para que engañemos a nuestros sentidos.
Imagínate que podemos medir el tiempo con precisión y dividimos un segundo en 500 partes, más que de sobra para que nuestros sentidos no lo noten. Ahora jugamos con cuanto tiempo mantenemos abierta la señal de tensión digital que ponemos.
La idea es que en cada parte vas a mantener la señal en alto un porcentaje del tipo total posible (La anchura del pulso que hayamos elegido)
Si por cada división de las 500, mantenemos abierta la tensión (O el grifo que para el caso es lo mismo) una porción de la misma, digamos un 5%, nos encontraremos con que la tensión promedio a la salida (O tensión eficaz) es un 5% de la que supondría mantener siempre la señal alta
Podemos jugar con el porcentaje de tiempo que mantenemos abierta la tensión de forma más o menos arbitraria: 50% o 90% en el ejemplo de arriba.
Aunque te puede parecer raro, las señales eléctricas no se disipan de forma instantánea sino que de alguna manera el mundo analógico del exterior percibe esto como una corriente que es el una proporción de la tensión que supondría tener abierto siempre el valor máximo
El resultado final es que a la salida vemos una tensión que varía proporcionalmente al porcentaje del tiempo que mantengo alta la señal, y estamos generando una muy buena aproximación a una señal analógica mediante conmutar con rapidez la proporción de tiempos en que la señal esta alta o baja.
¿Qué te parece el truco? Por eso lo llamamos modulación de ancho de pulsos (PWM) porque el valor eficaz de la tensión de salida depende directamente del ancho del pulso, o si lo prefieres de otro modo, de la proporción entre el ancho del pulso activo y el ancho de pulso a 0 voltios.
Naturalmente esto tiene que ser suficientemente rápido para que nuestro ojo no vea el truco, pero fíjate que nuestro ojo detecta variaciones por encima de o alrededor de una décima de segundo y aquí estamos hablando de cambio 500 veces por segundo.
Esa es una velocidad muy lenta para un circuito electrónico, pero que queda muy lejos de nuestras posibilidades. Si le pasamos una señal así a un led, veremos algo parecido a esto
Una vez que entendamos el truco (Va, que no es para tanto) necesitamos definir un par de variables que definan nuestro ciclo de modulación de pulsos o PWM, y como ya sabemos cómo es esto, os encontrareis con algunos nombres raros que harán parecer todo muy complicado, pero que va, es una tontería.
En primer lugar la frecuencia de la señal PWM: Hemos dicho arriba que podíamos dividir el tiempo de un segundo en 500 pedazos y jugar con la extensión del pulso en cada pulso. Pues oh sorpresa 500 es lo que llamamos la frecuencia base de la señal.
Podemos decidir partirlo en solo 20 (No es demasiado recomendable, porque está muy cerca de la décima de segundo que percibe nuestro ojo) y entonces diríamos que la señal base es de 20Hz ¿Qué te parece?
El siguiente término es el Duty Cycle, que es un porcentaje. Es la proporción entre el tiempo que tenemos alta la señal y el máximo tiempo posible. O dicho de otro modo: si tengo la señal con tensión alta un 60% del tiempo es un duty cycle del 60%.
Así que una vez visto todo esto, vamos a montar un pequeño circuito que modifique el brillo de ese led, mediante nuestra Raspberry Pi y veremos como modificar las caracteristicas de la señal PWM.
Esquema de montaje
El esquema eléctrico del circuito es de lo más sencillo. Simplemente conectamos el GPIO 24al positivo de un LED mediante una resistencia de 1K, y la otra pata a GND para cerrar el circuito
Usando PWM con Python
Como siempre con Python, vamos a empezar importante la librería de control de los GPIO y también la librería Time para regular el tiempo de encendido del led:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM)
Definimos el GPIO 24 como salida
GPIO.setup(24, GPIO.OUT)
Ahora necesitamos crear un objeto el pin 24 que gobernara la modulación PWM y vamos a llamarla rojo porque ese es el color del led:
rojo = GPIO.PWM(24, 100) rojo.start(100)
La idea es sencilla. Una vez definido el pin GPIO como salida creamos un objeto del tipo PWM en el pin 24, con una frecuencia de ciclo de 100, o lo que es lo mismo dividimos en 100 partes un segundo y después lo iniciamos con el valor primero, 100 en este caso, o sea, encendido a tope.
Esto es un tanto diferente de la manera como lo hacíamos con Arduino en que especificábamos un porcentaje del ciclo y no podíamos cambiar la frecuencia, pero la idea de fondo es la misma y no sería demasiado complicado definir una función que hiciese lo mismo que en Arduino, pero todo llegará.
Ya solo falta ir modificando el duty cycle o porcentaje útil del pulso PWM (Como en Arduino) mediante la instrucción:
rojo.ChangeDutyCycle( x )
Donde x es un numero entero entre 0 y 100. Veamos cómo quedaría un programa más o menos completo que varíe la intensidad del led:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(24, GPIO.OUT) rojo = GPIO.PWM(24, 100) rojo.start(100) while True: for i in range(100,-1,-1): rojo.ChangeDutyCycle(100 - i) time.sleep(0.02) print("Ciclo completo")
Como veis, la idea de generar una señal PWM que simule una señal analógica es igual de sencilla en Raspberry que en Arduino, pero tiene un par de diferencias como que hay que definir e inicializar un objeto asociado a un pin previamente definido como salida, e indicarle la frecuencia de la señal y el porcentaje del Duty Cycle, pero sigue siendo la misma idea
En otrro momento usaremos estas señales PWM para maejar un Servo por ejemplo que es na de las aplicaciones tipicas delas señales de modulacion de pulsos, pero precisamente porque s eusan ampliamente prefiero dejar el tema aqui por hoy.
Aqui os dejo un pequeño video con el resultado en el que se aprecia la variacion de intensidad del LED:
Moviendo un servo
Podemos usar una señal PWM para modificar la velocidad de giro de un motor de continua. Aunque al principio os puede sonar raro, modificando el Duty Cycle de la señal lo que hacemos es modificar la tensión eficaz a la salida.
La idea es que si podemos sacar entre 0 y 5 voltios por un pin, eso corresponde a Duty cicles de 0% y 100%. Esta es la parte fácil, pero a veces resulta menos evidente que si saco un Duty Cycle de 50%, la tensión promedio a la salida es de 2,5V, es decir, la tensión nominal por el Duty Cycle.
Esta es una manera sencilla para regular la velocidad de un motor de corriente continua o CC y volveremos a hablar largo y tendido más adelante, pero no quería dejar pasar la ocasión de mencionarlo aquí para el inventario.
Lo que hoy me interesa es hablar un poco de los servos, que son unos motores muy sencillos y muy usadores en robótica y todo este asunto de los Makers y el DIY.
Mientras que los motores normales de CC están pensados para que modifiquen su velocidad en función de la tensión que apliquemos a su entrada, los servos están diseñados para que se sitúen en un Angulo determinado en función de la señal de entrada.
Imagínate un timón de un barco o avión. Queremos controlar el Angulo del timón en función de una señal de control y no que gire libremente. Es decir buscamos una forma de decirle algo así como ponte a 30º y mantente ahí.
¿Podemos informar a un servo del Angulo que deseamos adopte? La respuesta, naturalmente es que sí, y de un modo muy sencillo. Los servos esta diseñados para que reconozcan el valor del DUTY Cycle de una señal PWM como una indicación del Angulo deseado.
Si un Servo está diseñado para girar entre 0º y digamos 180º, si le damos un Duty Cycle de 50% se colocara a 90º . Si le diéramos uno del 30% entonces giraría 60º.
El tema es tan fácil que podemos usar el programa anterior que modificaba el brillo del LED para posicionar el Angulo de un servo, pero antes ¿Qué crees tú que ocurrirá al correr ese programa?
Venga, va. Un pequeño esfuerzo, ¿Que crees que hará el servo, si le pasamos ese programa del LED?
Si quieres buena nota piensa en la respuesta correcta antes de ver el video que te lo muestra.