TUTORIAL III: PRIMEROS PASOS CON RASPBERRY PI Carmen López de la Torre (Universidad de Cantabria) Ignacio Elicegui Maestro (Universidad de Cantabria) Objetivos de este tutorial A lo largo de este tutorial aprenderemos a desenvolvernos con las placas Raspberry Pi. Comenzaremos con una breve descripción de estas placas y de las características de los diferentes tipos que podemos encontrar en el mercado. El siguiente paso será el de configurar la placa, desde la descarga del sistema operativo hasta el manejo de sus entradas y salidas. Finalmente realizaremos el ejercicio de conectar diferentes sensores a la placa y ver en el ordenador los valores que éstos arrojan. ¡Comenzamos! ¿Qué es Raspberry Pi? En esencia, Raspberry Pi (RP) es un ordenador de bajo costo integrado en una placa del tamaño de una tarjeta de crédito. Más formalmente, podemos definirla como una plataforma abierta que permite diferentes sistemas operativos (SO) y distribuciones ligeras para desarrollo. Las distribuciones más comunes son Linux, y la más utilizada Raspbian. En la actualidad existen tres modelos [1] de Raspberry Pi: 1 A+, 1 B+ y 2 B. A continuación describimos las características más importantes de estas placas. - - Raspberry Pi 1 A+: es la placa Raspberry más barata (Figura 1), y en 2014 reemplazó al antiguo modelo A. Sus características más interesantes son: o 256MB de memoria RAM o 1 puerto USB o No tiene puerto Ethernet o GPIO con 40 pines (el esquema de pines se mantiene igual en los 26 pines del modelo A antiguo) o Micro SD (antes era SD) o CPU Broadcom BCM2835 @ 700MHz o GPU: Co-procesador multimedia Dual Core VideoCore IV o Salida de audio y vídeo compuesto de 4 polos o Salida de vídeo y audio por HDMI o Puerto CSi para un módulo de cámara o Puerto DSI para pantallas TFT táctiles Figura 1. Raspberry Pi 1 A+ o Consumo bajo Raspberry Pi 1 B+: Este modelo (Figura 2) reemplazó al anterior modelo B en Julio de 2014 y fue mejorada por la RP 2 B+ en Febrero de 2015. o 542MB de memoria RAM o Puerto Ethernet 100Mb o GPIO con 40 pines (el esquema de pines se mantiene igual en los 26 pines del modelo B antiguo) o 4 puertos USB (el modelo B anterior tenía sólo 2 puertos USB) o Full HDMI port o Combined 3.5mm audio jack and composite video o Camera interface (CSI) Figura 2. Raspberry Pi 1 B+ o VideoCore IV 3D graphics core o Micro SD (antes era SD) o Menos consumo que su predecesor - Raspberry Pi 2 B: segunda generación de RP, recién llegada en Feb 2015. Mismas características que el modelo B+ pero con la añadidura: o 900MHz quad-core ARM Cortex-A7 CPU o 1GB RAM Para este tutorial utilizaremos la Raspberry Pi 2 model B. Configuración inicial de la Raspberry Pi - ¿Qué materiales necesitamos? o Raspberry Pi (nosotros usaremos la Raspberry Pi 2 model B) o Tarjeta SD Este es un punto bastante importante a la hora de configurar nuestra RP. Aunque en principio RP puede utilizar tarjetas SD de clase 4 o superior, éstas son muy lentas y lo ideal es una tarjeta de categoría 10. En cuanto a capacidad, una tarjeta de 4GB sería suficiente, aunque para curarse en salud para futuras actualizaciones del sistema operativo (SO) es mejor tener una de 8GB. En esta tarjeta instalaremos el SO, recordad que tiene que estar conectada siempre, la información de arranque de la placa estará en la tarjeta. o Alimentación Para alimentar nuestra placa necesitaremos un cargador micro usb de 5V. La corriente necesaria dependerá de los periféricos que le queramos conectar. La intensidad mínima para la RP sería unos 750/800mA, aunque se calentará bastante. Para que trabaje de forma más relajada se recomienda utilizar cargadores de unos 2100mA. Si vuestros proyectos no están bien alimentados podéis experimentar problemas por ello, ya que la placa podría no tener suficiente corriente para trabajar. o Para poder conectarnos con nuestra RP necesitaremos o bien un simple cable de red o bien un adaptador inalámbrico (normalmente plug and play). - Configuración de la Raspberry Pi o Paso 1: Montar la imagen del SO en la tarjeta SD El primer paso que tenemos que llevar a cabo es descargar el sistema operativo que queramos que opere nuestra RP. En nuestro caso usaremos la distribución Raspbian [2], ya que si estamos acostumbrados a Ubuntu no encontraremos mucha diferencia. En [2] podréis encontrar todas las distribuciones. Una vez nos hayamos descargado la imagen (archivo .img), el siguiente paso será el de montar (grabar) el SO en la tarjeta SD. Para ello necesitaremos un programa que realice esta función, en nuestro caso utilizaremos el “win32DiskImager” que os podréis descargar en este enlace [3]. Para montar la imagen abrimos el programa (Figura 3) y seleccionamos la imagen del SO que nos hemos descargado. Introducimos en el ordenador la tarjeta SD y seleccionamos en el programa dónde queremos que nos lo copie. En este paso deberéis ser muy cuidadosos ya que si escogéis otra unidad de escritura (por ejemplo vuestro disco duro) os borrará todo. Por último le damos a write y una vez finalizado el proceso ya tendremos el SO en nuestra tarjeta SD. Figura 3. Captura Win32 Disk Imager o Paso 2: Conectarse de forma remota a la Raspberry Pi Para conectarnos con nuestra placa de forma remota primero tendremos que conectarla a la red y asignarle una dirección IP para saber a quién dirigirnos y poder enviar/recibir información hacia/desde ella. Por defecto, una vez conectada a la red, nuestra RP tomará una dirección IP distinta cada vez que la desconectemos y la volvamos a conectar. Esto puede ser incómodo ya que tendremos que averiguar qué dirección ha tomado cada vez que queramos trabajar con ella. Por ello, en el siguiente paso os explicaremos cómo asignarle una dirección IP fija, que mantendrá aunque la desconectemos en algún momento. El primer paso será el de conectar el cable de red desde nuestro router a la placa. Para saber inicialmente cuál es la dirección que el router ha asignado a la RP tendremos que verlo en el panel de control de nuestro router (este paso dependerá de la marca/modelo del router que tengáis). Si no estáis familiarizados con él, buscando el modelo del router en cualquier buscador de Internet seguro que encontráis información. Para conectarnos con la placa lo haremos mediante SSH [4]. Si estamos trabajando con una máquina LINUX lo haremos a través de la consola. Si en nuestro caso estamos trabajando con Windows, necesitaremos algún programa que nos permita realizar conexiones SSH. Existen diferentes programas para Windows que realizan esta función (XShell, Virtual Box, PuTTY, etc.), en nuestro caso utilizaremos XShell [20]. El comando que utilizaremos para conectarnos es el siguiente: ssh pi@192.168.X.X (sustituir por la dirección de vuestra RP) La primera vez que nos conectemos nos aparecerá un mensaje que nos habla de las claves publica/privada, podemos contestar “yes”. A continuación nos pedirá la contraseña que por defecto es raspberry. La contraseña la podremos cambiar (y es recomendable) durante la configuración de la RP. Si por seguridad quisierais cambiar las claves pública/privadas SSH para no tener las mismas que todo el mundo, podéis seguir las instrucciones en este link [5]. El siguiente mensaje nos informará de que la placa no está configurada, así que ese será el siguiente paso a realizar. o Paso 3: Configuración inicial de la RP Para configurar nuestra RP, una vez que nos hayamos conectado por ssh, teclearemos el siguiente comando: sudo raspi-config El mensaje que nos aparecerá será una ventana como esta (Figura 4): Figura 4. Menu de configuración de la Raspberry Pi Con las flechas del teclado nos iremos moviendo por el menú y configurando los puntos que sean necesarios: Expand Filesystem: esta opción nos permitirá indicar que queremos utilizar toda la capacidad de la SD, ya que por defecto al grabar la imagen la capacidad queda limitada a 2GB. Change User Password: por defecto el usuario y el password son “pi” y “raspberry” respectivamente. Esta opción nos permitirá cambiar el password y fijar el que nosotros queramos. Enable Boot to Desktop/Scratch: esta opción permite a la RP iniciarse en modo gráfico cuando se inicia. Sin embargo, quizás no sea lo más conveniente, ya que este paso lo podremos hacer en cualquier momento y no trabajaremos mucho con el entorno gráfico. Internationalisation Options: a través de esta opción podremos escoger el idioma, la zona horaria y el layout del teclado (si quiere utilizarse). Enable Camera: permitirá utilizar la Pi Camera Add to Rastrack: esta opción permite añadir nuestra Raspberry Pi a la web creada por Ryan Walmsley [6]. En esta web se puede ver dónde están las RP que está usando la gente alrededor del mundo. Si nuestra RP está conectada a Internet podríamos seleccionar esta opción y ver aparecer nuestra RP (sólo un logo) en el mapa de la web. Overclock: configura el “overclocking” de nuestra RP, esto es, aumentar la frecuencia del procesador. Por defecto está configurada a 700MHz pero puede ponerse hasta 1000MHz. No es recomendable modificar esta opción ya que puede llevar a inestabilidades o incluso a freír el procesador, por lo tanto, si no sabes muy bien lo que estás haciendo será mejor que no toques nada de esta opción. Advanced Options: en este apartado se pueden modificar diferentes parámetros relativos a nuestra RP, en este link podrás ver una descripción de los mismos [7] (inglés). No entraremos en mayor detalle ya que no necesitaremos modificar nada en estos apartados por el momento. De todas las opciones que hemos mostrado anteriormente, sólo vamos a modificar tres de ellas: “Expland FileSystem”, “User Password” (en el caso de que queramos cambiar la contraseña), y las opciones de “Internationalisation Options”. Una vez hemos terminado de configurar nuestra RP, pinchamos en Finish. En ese momento la RP se reiniciará y ya tendremos nuestra placa configurada. o Paso 4: Establecer una ip estática a la Raspberry Pi Como explicamos anteriormente, puede ser interesante que nuestra RP tenga una IP fija (estática). Tendremos dos formas de asignarle la IP fija: la primera es utilizando las funciones que nos ofrezca nuestro router (dependerá de la marca/modelo, podréis buscarlo por Internet), y la segunda modificando un archivo en la RP. Este segundo paso será el que explicaremos a continuación. En primer lugar nos conectamos por SSH a la RP: ssh pi@192.168.X.X (sustituir por la dirección de vuestra RP) El archivo que tendremos que modificar para asignar la dirección estática es “intefaces”, que se encuentra dentro de la carpeta /etc/network. Para modificarlo necesitaremos información previa: la dirección de máscara de red (netmask), la del Gateway (que será la de nuestro router), y la nueva dirección fija que queramos asignarle. Para obtener esta información tecleamos lo siguiente: ifconfig Este comando nos devolverá la máscara de red (será algo así como 255.255.255.0). La dirección que queramos poner a nuestra RP compartirá las tres primeras partes de la dirección del router (192.168.X) y para la última parte asignaremos un número (de 0 a 255) que no tenga asignado ningún dispositivo más en el router. Si no estamos seguros de las direcciones que están ya asignadas podemos asignar como fija la dirección IP que nos ha dado el router, de esta forma estaremos seguros que ningún otro dispositivo tiene esa IP. Con la información anterior, tecleamos: cd /etc/network (accedemos al directorio) sudo nano interfaces (abrimos el fichero con el editor “nano”, también podréis usar el editor al que estéis acostumbrados) Buscamos la línea donde pone: iface eth0 inet manual y la cambiamos por las siguientes: iface eth0 inet static address 192.168.X.X (nueva IP fija) netmask 255.255.255.0 (poner nuestra máscara de red) gateway 192.168.Y.Y (poner la dirección de nuestro router) Figura 5. Archivo "interfaces" antes de ser modificado Figura 6. Archivo "interfaces" modificado Para finalizar, guardamos el archivo tecleando Ctrl+X, nos preguntará si queremos guardar los cambios, le diremos que “yes”. Para comprobar que se ha configurado la IP de forma correcta, reiniciamos la placa tecleando sudo reboot y una vez que se haya reiniciado, nos volveremos a conectar por ssh (se desconecta al reiniciarla) y tecleamos otra vez ifconfig para comprobar que la IP es la nueva que hemos asignado. Más detalles en [14]. En Raspberry Pi 2, a diferencia de las anteriores versiones, hay que modificar otros ficheros ya que aunque se le asigne la ip fija sigue pidiendo una ip por DHCP, y se llega al caso de que la RP tenga dos IPs. Si es tu caso, puedes encontrar más información en estos links [22] y [23]. o Paso 5: Acceder al escritorio gráfico (no es necesario) Aunque no nos será necesario acceder al escritorio gráfico para trabajar con nuestra RP, a continuación os explicaremos cuáles son los pasos para poder hacerlo. Como estamos conectados por ssh a nuestra RP no podemos lanzar el entorno gráfico con el comando “startx” que funciona en otras ocasiones. Por ello, lo haremos a través del programa VNC Server/Client. Para ello, estando conectados a nuestra RP tecleamos los siguientes comandos: sudo apt-get install tightvncserver (para instalar el programa servidor en la RP) tightvncserver (si es la primera vez que hacemos este paso nos pedirá ponerle una contraseña) vncserver:1 –geometry 1920x1080 –depth 16 El número “1” del último comando se refiere al display (que tendrá que ser el mismo que el del cliente de los siguientes pasos). En este momento, si no hemos obtenido ningún error, VNC server estará corriendo en nuestra RP. Ahora es el momento de poner en funcionamiento el VNC cliente, explicaremos cómo lo hacemos en Linux y en Windows. - Linux: El cliente lo instalaremos en el ordenador en el que vayamos a trabajar con el entorno gráfico de la RP. Para ello teclearemos los siguientes comandos sudo apt-get install xtightvncviewer (para instalar el programa cliente en el ordenador) xtightvncviewer (añadiremos & si queremos que trabaje en background, además nos pedirá una contraseña, la misma que pusimos en el servidor de la RP) Se abrirá una pequeña ventana del VNC Viewer y escribiremos RPI_IP:1 (tendréis que poner la IP de la RP en la parte marcada en negrita, el número 1 indica que el display será el 1) A continuación introduciremos la contraseña y ya tendremos listo nuestro entorno gráfico. - Windows: En este caso accederemos al link [8] y nos descargaremos la versión que corresponda a nuestra versión de Windows. Nos instalamos el programa y accedemos a su ventana principal (Figura 7). Ahí introduciremos la dirección IP de nuestra RP seguida de “:” y el display que hayamos puesto en el server. Figura 7. Captura TightVNC En la Figura 8 se muestra una captura del entorno gráfico de Raspberry Pi. Figura 8. Entorno gráfico de la Raspberry Pi Para cerrar la sesión, cerramos la ventana del entorno gráfico en el cliente, y para el servidor tecleamos lo siguiente: ps –ef|grep vnc //veremos todas las sesiones con los displays vncserver –kill :número_del_display Conceptos básicos sobre nuestra Raspberry Pi Una vez tenemos configurada nuestra placa llega el momento de ponernos manos a la obra y empezar a trabajar con ella. Sin embargo, antes de comenzar deberemos conocer algunos conceptos básicos como son el lenguaje en el que programaremos o la GPIO. o ¿Qué lenguaje usaremos para escribir nuestros programas en la RP? Aunque se pueden utilizar distintos lenguajes para programar (C, Javascript, PHP, etc.) en este caso utilizaremos Python ya que tiene excelentes librerías que nos harán las cosas más fáciles. Además, cuenta la leyenda que el apellido de nuestra Raspberry (Pi) viene de Python, aunque no sabemos en qué momento la “y”griega se convirtío en “i” latina… En Internet podréis encontrar multitud de tutoriales en python, como por ejemplo [9] [10]. o ¿Qué es la GPIO? Muy sencillo, es la interfaz con dispositivos externos. Gracias a ella podremos conectar sensores, pequeñas pantallas LCD, u otros gadgets. Las siglas GPIO se corresponden a “General Purpose Input Output” y es la forma que nos ofrece la RP para controlar sus puertos. En la Figura 7 se presenta el esquema de pines para la Raspberry Pi 2B y su correspondencia en la placa en la Figura 8. En primer lugar, nos aseguraremos de que nuestra GPIO está actualizada. Para ello, nos conectaremos por ssh (como hicimos en ocasiones anteriores) y teclearemos el siguiente comando: sudo apt-get update sudo apt-get upgrade Con este comando se nos actualizarán todos los paquetes. Esto lo podremos hacer de tarde en tarde, por si hay alguna actualización. Eso sí, hay que tener en cuenta que si hace mucho que no lo hemos actualizado puede tardar un rato. Más info en [15] Figura 9. Esquema de pines Raspberry Pi 2 model B Figura 10. Interfaces Rasbperry Pi 2 model B A continuación explicaremos los diferentes tipos de pines/puertos que presenta nuestra placa, para ello seguiremos el código de colores de la Figura 9: - Puertos rojos: ofrecen 3V ó 5V según corresponda. - Puertos negros: tierra. - Puertos amarillos: son puertos que pueden funcionar como entradas o salidas. El resto (salvo rojos y negros) podrían funcionar también como entrada y salida, pero si no es necesario (si tenemos suficiente con los amarillos) es mejor utilizarlos para sus funciones especiales que detallamos a continuación. - Puertos naranjas: Serial Peripherical Interface - Puertos verde claro: interfaz i2c - Puertos azul claro: UART (puerto serie) La Figura 10 muestra las principales interfaces de la Raspberry Pi 2 model B. o ¿Cómo utilizar las entradas y salidas GPIO? A la hora de escribir un programa para la Raspberry Pi en Python, en primer lugar tendremos que indicar que vamos a utilizar las entradas y salidas de la RP. Para ello, la primera línea de nuestro programa será la siguiente import RPi.GPIO as GPIO Antes de aprender a trabajar con las entradas y salidas de nuestra placa, debemos saber que hay dos formas de denominarlas: BOARD y BCM. No importará cual utilicemos mientras en un mismo programa utilicemos siempre la misma. En la Figura 9 se muestra en las columnas interiores (en blanco) los números de los pines que se utilizarán en el modo BOARD. En las columnas laterales (y en colores) se muestra la numeración de puertos GPIO, que se utilizarán en el modo BCM. En nuestros programas deberemos indicar qué tipo de nomenclatura vamos a utilizar, para ello utilizaremos el comando GPIO.setmode(modo) # Modo BOARD -> número de los pines GPIO.setmode(GPIO.BOARD) # Modo BCM -> puertos GPIO GPIO.setmode(GPIO.BCM) Manejo de los puertos de entrada Antes de leer un puerto debemos establecerlo como entrada, para ello utilizaremos el siguiente comando: GPIO.setup(Puerto/Pin, GPIO.IN) El primer parámetro será el puerto o pin (dependiendo de la nomenclatura que hayamos dicho que vamos a utilizar) y el segundo indica que lo establecemos como entrada. Por ejemplo, vamos a utilizar la nomenclatura de puerto GPIO y establecer el GPIO23 como entrada: import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) # nomenclatura de puertos GPIO GPIO.setup(23, GPIO.IN) # establecemos el puerto GPIO 23 como entrada Una vez que ya hemos dicho que funciona como entrada podremos leerlo. Los valores que podremos leer son booleanos, es decir, podremos leer 0/false/0V/LOW ó 1/true/3.3V/High. Podremos leer el valor con la siguiente línea de código: GPIO.input(Puerto/Pin) Manejo de los puertos de salida Antes de utilizar un puerto como salida deberemos de decirle al programa que ese puerto funcionará como salida. Para ello utilizaremos la siguiente línea de código: GPIO.setup(Puerto/Pin, GPIO.OUT) El primer parámetro será el puerto o pin (dependiendo de la nomenclatura que hayamos dicho que vamos a utilizar) y el segundo indica que lo establecemos como salida. Por ejemplo, vamos a utilizar la nomenclatura de pines y establecer el pin 13 como salida: import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) # nomenclatura pines GPIO.setup(13, GPIO.OUT) # establecemos el pin 13 como salida Una vez que nuestro puerto trabaja como output, podremos establecer los valores de 0/false/0V/LOW ó 1/true/3.3V/High. Para ello utilizaremos el siguiente comando: GPIO.output(13, 1) #fijamos la salida a 1/true/high GPIO.output(13, 0) #fijamos la salida a 0/false/low Llegados a este punto es importante que conozcamos el concepto de GPIO.cleanup(). Esta funcionalidad nos permite “limpiar” todos los puertos que hayamos usado, reseteándolos y estableciéndolos como entradas. Pero, ¿por qué es importante hacer esto? La respuesta a esta pregunta es que nos prevé de situaciones que puedan dañar la placa. Por ejemplo, si dejamos un puerto de salida en high, no lo reseteamos y en otro momento ponemos sin darnos cuenta ese puerto en GND podríamos freír la placa. La siguiente pregunta que se nos plantea es cómo utilizar esta función. La deberemos utilizar al final del programa, ya que reseteará todos los pines que hayamos utilizado. También debemos tener en cuenta que el programa no siempre finaliza de forma correcta, ya que podría haber algún error (excepción) y no terminar correctamente, o podemos pararlo nosotros de forma manual tecleando Ctrl+C. Para tener en cuenta estas tres posibilidades en la finalización de un programa, y que se limpien los puertos ocurra cual ocurra, una opción limpia es la de ordenar nuestro código de la siguiente forma: import RPi.GPIO as GPIO # Aquí definimos la nomenclatura de los puertos, inicializamos variables, etc. try: #Aquí introducimos nuestro código principal (lo que queramos que haga RP) except KeyboardInterrupt: # Esta interrupción se corresponde al evento cuando tecleamos Ctrl+C except: # Este apartado recogerá el resto de excepciones finally: GPIO.cleanup() #Limpiamos los puertos que hayamos utilizado Conectando un sensor Ahora que ya sabemos trabajar con las entradas y salidas de la Raspberry Pi, llega el momento de comunicarnos con el mundo real. Para ello, le conectaremos sensores y recibiremos los valores que éstos nos ofrezcan. Como vimos en tutoriales anteriores, tenemos dos tipos de sensores con los que trabajar, sensores analógicos y sensores digitales. En el caso de la Raspberry Pi, ésta sólo admite digitales así que para poder utilizar sensores analógicos necesitaremos un conversor analógico digital como este [11]. • Conectando un sensor digital Comenzaremos conectando un sensor digital, en este caso utilizaremos un sensor de movimiento por infrarrojos, también llamados PIR. Este sensor tiene tres pines (Vcc, GND y OUT) por lo que conectaremos Vcc a 3.3V, GND a una de nuestras tierras, y OUT lo conectaremos al pin 7 o GPIO4. A continuación presentamos el código Python que tomará las lecturas de este sensor y que imprimirá si existe o no movimiento. Destacar que cuando este sensor devuelve el valor 1 significa que hay movimiento y que si devuelve 0 significa que no lo hay. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. import RPi.GPIO as GPIO from time import sleep # Librería para poder poner tiempos de espera GPIO.setmode(GPIO.BOARD) GPIO.setup(7,GPIO.IN) # nomenclatura de número de pines # pin número 7 será la entrada del sensor try: while True: if GPIO.input(7): # si el sensor devuelve 1 print(GPIO.input(7)) # imprime el valor que devuelve el sensor print("Hay movimiento") else: print(GPIO.input(7)) # imprime el valor que devuelve el sensor print("No hay movimiento") sleep(1) # tiempo de espera de 1 segundo except KeyboardInterrupt: print ("Paramos el programa") except: print ("Ha habido un error y el programa se ha cerrado") finally: GPIO.cleanup() Tendremos varias formas de guardar este código en la RP. Por un lado, una vez conectados por ssh, podemos utilizar el editor de texto nano (o cualquiera con el que estemos acostumbrados a trabajar), copiar este código, y guardarlo con el nombre que queramos (por ejemplo “lecturaPIR”) con la extensión “.py” que indicará que es un código Python (lecturaPIR.py). Otra opción, que igual os parece más atractiva, es la de entrar visualmente a las carpetas de la RP y colocar nuestro código en una de ellas. Una forma muy práctica de hacer esto es, si hemos estado utilizando el programa XShell en Windows, instalar Xftp. Una vez instalado, nos conectaremos por ssh a nuestra RP, clicamos en el icono correspondiente y nos aparecerá una ventana con la estructura de archivos de nuestra RP. Creamos una carpeta donde guardaremos nuestros códigos, creamos el archivo y copiamos el código anterior, guardándolo con la extensión “.py”. Para poner nuestro programa a funcionar, una vez que estemos conectados por ssh, nos situaremos dentro de la carpeta donde esté nuestro código y teclearemos el siguiente comando: sudo python lecturaPIR.py Ahora comenzaremos a ver un mensaje u otro en la pantalla dependiendo si registra movimiento o no (podemos jugar pasando la mano por encima, cambiar las distancias, etc.). Cuando queramos que nuestro programa deje de funcionar teclearemos Ctrl+C, en ese momento el programa terminará y se hará el cleanup de los pines. Ahora que ya sabemos manejar un sensor digital en el que no nos hacía falta el uso de librerías, trataremos un ejemplo en el que se requieren librerías para recoger los valores. Recordad que las librerías son códigos que nos traducen los valores de los voltajes que recoge la placa y los transforma a valores “legibles” para nosotros. Al igual que en el tutorial anterior [18] utilizaremos el ejemplo del sensor de temperatura y humedad DHT22. Como ya explicamos, la conexión es sencilla: este sensor tiene 3 pines (normalmente tiene 4 y uno no se conecta). Tendremos que conectar Vcc (cable rojo) a los 5V de nuestra placa y GND (cable negro) a la tierra. El otro pin (DATA) le conectaremos a un pin digital de la placa. Como hemos dicho, para poder recoger los valores del sensor, necesitaremos las librerías que nos hagan la conversión del voltaje que recoja la placa a unos valores legibles de temperatura y humedad. Las librerías en Python del DHT22 para Raspberry Pi las ofrece Adafruit y se llaman “Adafruit_Python_DHT”. A continuación os mostraremos los pasos para instalar la librería y luego poder utilizarla en vuestros programas simplemente importándola. Nos conectaremos por ssh a nuestra placa como en ocasiones anteriores, e iremos ejecutando los siguientes comandos: sudo apt-get install -y build-essential python-dev git //dependencias mkdir -p /home/pi/sources //creamos carpeta llamada sources dentro del directorio /home/pi cd /home/pi/sources //entramos en la carpeta sources git clone https://github.com/adafruit/Adafruit_Python_DHT.git //descargamos las librerías cd Adafruit_Python_DHT //nos metemos en la carpeta de la librería sudo python setup.py install //instalamos la librería Ahora que está instalada la librería, la forma de recoger el dato en nuestros programas en Python es la siguiente: humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4) El primer argumento de la función (Adafruit_DHT.DHT22) indica el tipo del sensor. En nuestro caso será DHT22, si fuera un DHT11 sería Adafruit_DHT.DHT11 y si fuera un AM2302 sería Adafruit_DHT.AM2302, todos ellos son de la misma familia de sensores y utilizan la misma librería. El segundo argumento (4) es el pin en el que tenemos conectado el pin DATA del sensor. Es importante destacar que esta librería utiliza el modo BCM, aunque nosotros podremos tratar los pines del resto de nuestro programa con el modo que queramos (pero el mismo modo para todo el resto). A continuación podéis ver el código que utilizaremos para realizar la lectura del sensor: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. import RPi.GPIO as GPIO from time import sleep import Adafruit_DHT # Librería para poder poner tiempos de espera GPIO.setmode(GPIO.BOARD) GPIO.setup(7,GPIO.IN) # nomenclatura de número de pines # pin número 7 será la entrada del sensor try: while True: if GPIO.input(7): # cuando se reciba un valor en el pin 7 humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4) print("Temperatura = {0:.2f} y humedad = {1:.2f}%".format(temperature, humidity)) sleep(1) # tiempo de espera de 1 segundo except KeyboardInterrupt: print ("Paramos el programa") except: print ("Se ha producido un error y el programa se ha cerrado") finally: GPIO.cleanup() Ahora, guardamos el programa como hemos explicado anteriormente, por ejemplo con el nombre DHT22Lectura.py y lo ejecutamos: sudo python DHT22Lectura.py En la pantalla nos empezarán a aparecer líneas como las siguientes: Temperatura = 25.30 y humedad = 56.90% Temperatura = 25.35 y humedad = 56.91% Temperatura = 25.29 y humedad = 56.90% … Cuando queramos dejar de recibir valores por pantalla, teclearemos Ctrl+C • Conectando un sensor analógico Como hemos dicho anteriormente, la Raspberry Pi no tiene entradas analógicas como el Arduino, por ello necesitaremos algo que nos ayude a convertir las señales enviadas por los sensores analógicos en señales digitales. En nuestro caso utilizaremos el chip ADS1015, podéis encontrar más información sobre este componente en [12]. En la Figura 11 podéis ver el chip; sobre él hemos marcado los pines que utilizaremos para leer un sensor analógico. De izquierda a derecha podemos ver: el pin VDD por el que se alimenta el chip y que conectaremos a la entrada de 3.3V de la RP; el pin GND que conectaremos a un pin GND de la RP; los pines SCL y SDA que son los pines por los cuales el chip se va a comunicar con la RP, SCL ayuda a poder sincronizar los envíos y SDA envía el dato; los pines A0, A1, A2 y A3 son las distintas entradas analógicas a las que conectaremos nuestros sensores y que el chip se encargará de traducir a digital. Figura 11. Conversor analógico digital ADS1015 Es importante que antes de comenzar a trabajar con el chip, entendamos bien cómo funcionan los pines SCL y SDA, y para ello deberemos conocer brevemente qué es el bus I2C, si queréis más información podéis encontrarla, por ejemplo, en [13]. En pocas palabras, el bus I2C es una interfaz utilizada para comunicar distintos microcontroladores, controladores con periféricos, etc. En nuestro caso queremos conectar RP con un conversor. El bus está compuesto principalmente por 4 líneas, dos de ellas son las de alimentación y tierra, las otras dos son SDA y SCL. La línea SDA nos permitirá enviar datos y la SCL permitirá sincronizar la comunicación entre los dispositivos. Si nos fijamos en el dibujo de la Figura 12 y pensamos en nuestros dispositivos, el máster (el que ordena cuándo quiere recibir la información) será nuestra RP y el esclavo el conversor. Figura 12. Bus I2C (Fuente Wikipedia) El bus I2C no viene habilitado por defecto en la RP, por lo tanto tendremos que hacerlo nosotros. Los pasos para habilitar el bus son los siguientes: 1. Nos conectaremos por ssh (como hemos hecho anteriormente) a la RP. ssh pi@192.168.X.X (sustituir por la dirección de vuestra RP) 2. Entraremos en la configuración de la RP (sudo raspi-config) y habilitaremos el “i2c”. Para ello seleccionaremos el apartado de “Advanced options” y nos aparecerá el siguiente menú: Figura 13. Panel de opciones avanzadas de Raspberry Pi Seleccionamos la línea marcada en rojo en la Figura 13 (que es la correspondiente al I2C) y a continuación aceptamos a lo que nos vaya diciendo (que es que si queremos habilitarlo y que esté habilitado cuando encendamos la placa en futuras ocasiones). 3. Reiniciaremos la placa sudo reboot 4. Nos volvemos a conectar por ssh y modificaremos el archivo situado en /etc/modules añadiendo una nueva línea “i2c-dev” cd /etc sudo nano modules En este fichero añadiremos la línea i2c-dev Para salir del editor y guardar el archivo tecleamos “Ctrl+X”, abajo nos preguntará si queremos guardar los cambios, teclearemos “y” + intro, después nos preguntará si queremos dejar el mismo nombre al fichero, teclearemos “y” + intro. Figura 14. Fichero "modules" antes de ser modificado Figura 15. Fichero "modules" después de ser modificado 5. Reiniciaremos la placa otra vez sudo reboot 6. Ejecutaremos la siguiente línea para instalar “python-smbus” y “i2c-tools” para ayudarnos en la posible búsqueda de errores y para permitir utilizar la interfaz i2c con Python. sudo apt-get install i2c-tools python-smbus Una vez habilitado el puerto I2C podremos comunicar el conversor analógico digital con nuestra RP. Para comprobar su funcionamiento vamos a “crear” un sensor analógico de luminosidad con ayuda de un LDR y resistencias. El funcionamiento de este componente ya fue explicado en anteriores tutoriales, y puede ser consultado en [18]. Además, le añadiremos unos LEDs que se encenderán dependiendo de la cantidad de luz que llegue al dispositivo. El montaje se muestra en la Figura 16. Figura 16. Montaje lectura LDR con ADS1015 Ahora que ya tenemos listo el montaje, necesitaremos descargarnos las librerías del conversor. En este caso, no se pueden instalar si no que te descargas el fichero y luego lo importas en el código. Que ocurra una u otra cosa dependerá del tipo de librería. Podéis encontrarlas en [21]. A continuación presentamos el código que ejecutaremos en nuestra RP. El objetivo del código es el de recoger los valores de luminosidad recogidos por el conversor. 1. 2. 3. 4. 5. 6. 7. 8. 9. import RPi.GPIO as GPIO from time import sleep # Librería para poder poner tiempos de espera ADS1015 = 0x00 gain = 4096 # +/- 4.096V sps = 250 # 250 samples per second GPIO.setmode(GPIO.BOARD) GPIO.setup(11,GPIO.OUT) # nomenclatura de número de pines # pin número 11 se establece como salida 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. GPIO.setup(13,GPIO.OUT) GPIO.setup(15,GPIO.OUT) # pin número 13 se establece como salida # pin número 15 se establece como salida adc = ADS1x15(ic=ADS1015) try: while True: volts = adc.readADCSingleEnded(0, gain, sps) / 1000 # entrada A0 if volts < 1.75 : #si valor en el pin está entre 1.3 y 1.75V print "%.6f" % (volts) #imprime el valor que devuelve el conversor print("1 LED") GPIO.output(11, 1) #encendemos led conectado al pin 11 GPIO.output(13, 0) #apagamos led conectado al pin 13 GPIO.output(15, 0) #apagamos led conectado al pin 15 sleep (1) # tiempo de espera de 1 segundo elif 1.75 <= volts <= 2.2 : #si valor en pin está entre 1.75 y 2.2V print "%.6f" % (volts) #imprime el valor que devuelve el conversor print("2 LED") GPIO.output(11, 1) #encendemos led conectado al pin 11 GPIO.output(13, 1) #encendemos led conectado al pin 13 GPIO.output(15, 0) #apagamos led conectado al pin 15 sleep(1) # tiempo de espera de 1 segundo else: #si valor en pin es mayor que 2.2V print "%.6f" % (volts) #imprime el valor que devuelve el conversor print("3 LED") GPIO.output(11, 1) #encendemos led conectado al pin 11 GPIO.output(13, 1) #encendemos led conectado al pin 13 GPIO.output(15, 1) #encendemos led conectado al pin 15 sleep (1) # tiempo de espera de 1 segundo except KeyboardInterrupt: print ("Paramos el programa") except: print ("Ha habido un error y el programa se ha cerrado") finally: GPIO.cleanup() Para que nos sea más sencillo, podemos guardar este código en la misma carpeta de la librería del conversor. Si queremos hacerlo más limpio, por Internet podéis encontrar cómo importar la librería. Para ejecutar el programa, nos metemos en la carpeta donde tengamos guardado el código y ejeutamos la siguiente línea: sudo python LecturaLDR.py Bibliografía 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. http://www.raspberrypi.org/products/ http://www.raspberrypi.org/downloads/ http://sourceforge.net/projects/win32diskimager/ http://es.wikipedia.org/wiki/Secure_Shell http://nideaderedes.urlansoft.com/2014/01/15/raspberry-pi-como-conectarnos-via-ssh-sinmonitor/ http://rastrack.co.uk http://www.raspberrypi.org/documentation/configuration/raspi-config.md http://www.tightvnc.com/download.php https://launchpadlibrarian.net/18980633/Python%20para%20todos.pdf http://es.tldp.org/Tutoriales/Python/tut.pdf http://tienda.bricogeek.com/bricogeek/678-conversor-adc-8-bits-mcp3008.html https://www.adafruit.com/products/1083 http://www.electroensaimada.com/i2c.html http://www.electroensaimada.com/ip-estaacutetica.html http://raspi.tv/2013/rpi-gpio-basics-1-how-to-check-what-rpi-gpio-version-you-have http://www.xatakahome.com/domotica/algunas-cosas-a-tener-en-cuenta-antes-de-usar-unaraspberry-pi http://www.electroensaimada.com/raspberry-pi.html Tutorial II: Comunicándonos con el mundo real. http://sociotal.eu/content/knowledge-transfer http://www.home-automation-community.com/temperature-and-humidity-from-am2302dht22-sensor-displayed-as-chart/ https://www.netsarang.com/products/xsh_overview.html https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code https://www.raspberrypi.org/forums/viewtopic.php?p=798866#p798866 https://www.raspberrypi.org/forums/viewtopic.php?f=36&t=110557 Agradecimientos Este tutorial ha sido realizado dentro del proyecto europeo SocIoTal (www.sociotal.eu). Este proyecto ha recibido financiación del Séptimo Programa Marco de la Unión Europea para investigación, desarrollo tecnológico y demostración bajo el acuerdo de concesión nº 609112.