====== Raspberry Pi GPIO ====== **GPIO** (General Purpose Input/Output, Entrada/Salida de Propósito General) es un pin genérico en un chip, cuyo comportamiento (incluyendo si es un pin de entrada o salida) se puede controlar (programar) por el usuario en tiempo de ejecución. Los pines GPIO no tienen ningún propósito especial definido. Aplicaciones embebidas (por ejemplo, Arduino, BeagleBoard, Raspberry Pi) hacen un uso intensivo de GPIO para interactuar con el entorno físico. Esta entrada de la wiki es una **iniciación a la programación física con Raspberry Pi y Python**. La creación de la fantástica **librería gpiozero** de [[https://twitter.com/ben_nuttall|Ben Nuttall]] para ese lenguaje hace que esto sea ahora mucho más sencillo y el paso desde Arduino casi inmediato. La última versión de Raspbian incluye esta librería. Si no es tu caso deberás instalarla o mejor aún, actualizar tu sistema. Utilizaremos la versión 3 de Python. Se va a escribir la página a medida que sus contribuidores aprendemos. Probablemente haremos muchas referencias a Arduino, que es de donde venimos, aunque no es imprescindible conocerlo. La forma de aprender no será de abajo hacia arriba empezando por conceptos básicos de Python sino al revés, empezando directamente con pequeños proyectos y explicando lo mínimo necesario en cada caso. ===== Advertencia importante ===== {{:guias:rpigpio:450px-warningpi.png?300x265}} Una advertencia previa muy importante antes de empezar: **los pines GPIO no están protegidos** frente a voltajes excesivos de entrada o amperajes excesivos de salida. Si conectas algo de manera inapropiada, **puedes quemar tu Raspi**. Antes de conectar ningún montaje asegúrate de que sabes lo que estás haciendo. ===== Introducción ===== La principal diferencia con Arduino y otros microcontroladores respecto de su interacción con el mundo físico es que las Raspberry no tienen entradas analógicas ni salidas PWM. Para añadir esas funciones (o controlar motores y otros dispositivos) necesitaremos placas externas, las llamadas HAT (Hardware Attached on Top), similares a las shields de Arduino. En cambio sí disponen de los interfaces de comunicacionesz I2C, SPI y UART (puerto serie). Otra diferencia fundamental frente a modelos como Arduino UNO es que su voltaje de funcionamiento es 3.3V en lugar de 5. Todas las Raspberry Pi de 40 pines (modelos B, 2, 3 y Zero) comparten la distribución de pines. Puedes conectar las cosas directamente o a través de algunos accesorios que los reproducen en una breadboard. En los dibujos a veces empleamos una Raspi Zero, pero si tienes cualquier otro modelo puedes usarlo igual. {{:guias:rpigpio:261px-raspipinout.png?250x430}} {{:guias:rpigpio:expansion_raspi.jpg?500x348}} ===== Dos formas de usar Python ===== Para interactuar con el mundo físico vamos a usar el lenguaje de programación Python, y podemos hacerlo de dos modos diferentes: * Teclear instrucciones por línea de comandos en la ventana de Python o incluso en una ventana de terminal. * Escribir un programa completo en un archivo con extensión .py, guardarlo (CTRL + S) y ejecutarlo (F5). {{:guias:rpigpio:python_shell_program.png?970x310}} ===== Instalar la librería GPIOZERO ===== Si no tienes instalada la librería gpiozero, desde un terminal de Raspbian, ejecuta las siguientes instrucciones pi@raspberrypi:~$ sudo apt update pi@raspberrypi:~$ sudo apt install python3-gpiozero ===== Instalar el monitor de pines GPIO ===== En este enlace al [[https://github.com/rricharz/pi-gpio-display|Github]] de Rene Richarz están las instrucciones para instalar una aplicación que nos resultará muy útil porque muestra en la pantalla los pines de Raspberry y su estado (apagado, encendido...). {{:guias:rpigpio:screenshot.jpg?400|}} sudo apt-get install wiringpi cd Downloads git clone git://github.com/rricharz/pi-gpio-display cd pi-gpio-display chmod +x ./install ./install ===== Primer proyecto: Activar un led ===== Montaremos el esquema clásico de un led con una resistencia en serie -220ohm es un buen valor- entre el pin 25 y masa (GND). {{:guias:rpigpio:led_25.jpg?485x333}} Y probaremos este código (línea a línea en el shell de Python o entero en un archivo .py) from gpiozero import LED led = LED(25) led.on() Si todo ha ido bien tendremos un led encendido. Podemos apagarlo con **led.off()** El programa hace lo siguiente * Importa la función LED de la librería gpiozero. En Python se pueden importar librerías completas o funciones sueltas. * Crea un objeto con nombre **led** con esa función en el pin 25. * Utiliza el método **led.on()** para encenderlo. Si queremos hacer el clásico blink de Arduino que hace parpadear el led el código ahora es from gpiozero import LED from time import sleep led = LED(25) while True: led.on() sleep(1) led.off() sleep(1) Las novedades ahora son * Importamos la función **sleep(tiempo en segundos)** de la librería time, que detiene el programa un tiempo. * Para que se ejecute un código de manera repetitiva lo metemos en un bucle **while True**, lo que crea un bucle indefinido de manera similar a **void loop** en Arduino. **Truco**: ese programa se ha hecho para aprender el bucle while, pero no es necesario. La función tiene implementado ya el método como **led.blink()** ==== Leds de brillo variable ==== Podemos ahora hacer que el LED brille con una intensidad diferente de la máxima con un método diferente: PWMLED from gpiozero import PWMLED from time import sleep led = PWMLED(17) while True: led.value = 0 # apagado sleep(1) led.value = 0.5 # brillo a medias sleep(1) led.value = 1 # brillo a tope sleep(1) O ahora con un bucle from gpiozero import PWMLED from time import sleep led = PWMLED(17) intensidad = 0 while (intensidad <= 9): led.value = intensidad/10 intensidad = intensidad + 1 sleep(0.1) while (intensidad >= 1): led.value = intensidad/10 intensidad = intensidad - 1 sleep(0.1) ==== Tu primer semáforo ==== Y finalmente un último ejemplo de prueba con varios leds simulando un semáforo {{:guias:rpigpio:semaforo.png?500x388}} from gpiozero import LED from time import sleep rojo = LED(23) amarillo = LED(24) verde = LED(25) while True: verde.on() sleep(1) verde.off() amarillo.blink(0.1,0.1) sleep(1) amarillo.off() rojo.on() sleep(1) rojo.off() ===== Segundo proyecto: Leer la entrada de un botón ===== **Conecta el botón** entre los pines 17 y GND. Ten cuidado con la orientación de las patas, combrueba cuáles son las que cierran el circuito el pulsar. {{:guias:rpigpio:boton.jpg?500x421}} from gpiozero import Button boton = Button(17) boton.wait_for_press() print('Pulsaste!') Cuando pulses el botón, la instrucción print sacará un mensaje de texto en la consola de Python. ¡Pero sólo una vez! Si queremos que lo haga continuamente, deberemos crear un bucle while True: from gpiozero import Button boton = Button(17) while True: boton.wait_for_press() print('Pulsaste!') **Añadiremos ahora un led** en el pin 25 tal y como hicimos en el primer proyecto. {{:guias:rpigpio:boton_led.jpg?498x425}} from gpiozero import LED, Button from time import sleep led = LED(12) boton = Button(17) while True: boton.wait_for_press() led.toggle() sleep(0.5) Ahora la salida ya no es un mensaje de texto sino un led conectado al pin 25 y con una función nueva de los leds: toggle() cambia su estado de encendido a apagado o viceversa. La función **wait_for_press** espera a que se pulse el botón y mientras no suceda detiene el programa. Si queremos que el programa continúe haciendo otras cosas tenemos otras dos: when_pressed y when_released from gpiozero import LED, Button from signal import pause led = LED(12) boton = Button(17) boton.when_pressed = led.on boton.when_released = led.off pause() Podemos ahora combinar más funciones con este codigo (u otro similar que se nos ocurra) from gpiozero import LED, Button from time import sleep led = LED(12) button = Button(17) button.wait_for_press() led.on() sleep(3) led.off() ===== Tercer proyecto: Sonido con un zumbador ===== Un [[https://es.wikipedia.org/wiki/Zumbador|zumbador]] (buzzer en inglés) es un pequeño dispositivo capaz de convertir una señal eléctrica en sonido. Algo así como un altavoz cutre. Vale, muy cutre. Hay dos tipos fundamentales de zumbadores, pasivos y activos. Los primeros requieren una señal con una forma específica para funcionar, con el voltaje subiendo y bajando en forma de onda. Los activos son mucho más sencillos de usar y serán los que probemos. Su desventaja es que no podemos controlar el tono del sonido. Se conectan igual que un led pero no necesitan resistencia, sólo es necesario identificar el negativo -cable negro, a GND- y el positivo -cable rojo, al pin 17-. {{:guias:rpigpio:buzzer-circuit.png?600x584}} La librería gpiozero tiene un objeto para usar zumbadores: Buzzer. Los métodos para usarlo -.on y .off- son similares a un led from gpiozero import Buzzer from time import sleep buzzer = Buzzer(17) while True: buzzer.on() sleep(1) buzzer.off() sleep(1) Al igual que el objeto led tenía la función parpadeo (blink), Buzzer tiene un método que hace más simple lo anterior: beep. from gpiozero import Buzzer from time import sleep buzzer = Buzzer(17) while True: buzzer.beep() ===== Cuarto proyecto: Semáforo con pulsador y zumbador ===== {{:guias:rpigpio:camjam1wiring.png?600x584}} Se trata ahora de integrar todo lo anterior para hacer un semáforo con pulsador para peatones con el comportamiento típico - Intervalo regular de luz verde > naranja > roja - Detección de pulsación y en ese caso: * Pasar a luz naranja y roja si está en verde. * Una vez en rojo activar el zumbador un tiempo (para el peatón) y volver a la secuencia principal ===== Equipo ===== * [[:user:felixstdp|Félix]] * [[:user:salvari|Sergio]] ===== Enlaces ===== * [[https://www.raspberrypi.org/learning/physical-computing-with-python/worksheet/ | Getting Started with Physical Computing on the Raspberry Pi]] * [[https://www.raspberrypi.org/magpi/issues/essentials-gpio-zero-v1/ | MagPi Simple Electronics with GPIO Zero]] * [[https://gpiozero.readthedocs.io/en/stable/index.html| gpiozero reference]]