1. Introducción
Este taller es una introducción a la Raspberry Pi (RPi). La RPi es una computadora completa contenida en una placa del tamaño de una tarjeta de crédito. La placa del RPi 2 Modelo B aloja un SoC (System-on-a-chip) Broadcom BCM2836 que incluye:
-
Un procesador de cuatro núcleos ARM Cortex-A7 a 900 MHz
-
1 GB de memoria RAM
Tiene además las siguientes características:
-
4 puertos USB
-
40 pines GPIO (General-Purpose Input/Output)
-
Puerto HDMI
-
Puerto ethernet
-
Conector combinado de audio de 3.5 mm y video compuesto
-
Interfaz de cámara (CSI)
-
Interfaz de display (DSI)
-
Ranura para tarjetas Micro SD
-
GPU (Unidad de Procesamiento Gráfico) VideoCore IV 3D
El reducido costo de la RPi (35.00 USD aprox.) se debe en gran medida a que éste no incluye los dispositivos periféricos necesarios para su operación. El monitor, mouse, teclado, etc. deben ser provistos por el usuario.
1.1. Objetivos del taller
En este taller aprenderás a usar la RPi para:
-
Encender y apagar un led
-
Controlar un sensor ultrasónico para medir distancias
-
Montar un servidor de web sencillo
-
Proporcionar un servicio web para poder obtener las mediciones del sensor ultrasónico
2. Práctica: El led parpadeante
En esta práctica controlaremos el encendido y apagado de un led (diodo emisor de luz) conectado a la RPi.
2.1. Requisitos de hardware
-
RPi con su respectivo mouse, teclado, monitor y fuente de alimentación
-
Un led
-
Un protoboard
-
Una resistencia de entre 270Ω y 330Ω
-
Cables conectores
2.2. Requisitos de software
-
Sistema operativo Raspbian
-
Python 2.7
2.3. Armando el proyecto
La siguiente figura, elaborada en Fritzing, muestra la manera de conectar los componentes:
Las conexiones son las siguientes:
-
El ánodo del led (la patita larga) se conecta al pin GPIO 24 de la RPi.
-
El cátodo del led (la patita corta) se conecta a la resistencia.
-
El otro extremo de la resistencia se conecta a tierra (cualquiera de los pines
GND
de la RPi).
2.4. Código de Python
Copia y pega el siguiente programa en un editor de texto.
Sugerencia
Utiliza el IDLE de Python para editar todos tus archivos. En el menú del ambiente gráfico de Raspbian selecciona la opción |
# coding=utf-8
# Importar las funciones necesarias de los módulos RPi y
# time.
import RPi.GPIO as GPIO
import time
# Las pausas duran medio segundo.
TIEMPO_PAUSA = 0.5
# Pin donde está conectado el ánodo del LED.
PIN_LED = 24
# Indicar que se usa el esquema de numeración de pines
# de BCM (Broadcom SOC channel), es decir los números de
# pines GPIO (General-Purpose Input/Output).
GPIO.setmode(GPIO.BCM)
# Establecer un canal: indicar que el pin conectado al led
# es de salida.
GPIO.setup(PIN_LED, GPIO.OUT)
try:
# Ciclo infinito.
# Para terminar el programa se debe presionar Ctrl-C.
while True:
# Encender el led.
GPIO.output(PIN_LED, GPIO.HIGH)
# Pausar un momento.
time.sleep(TIEMPO_PAUSA)
# Apagar el led.
GPIO.output(PIN_LED, GPIO.LOW)
# Pausar otro momento.
time.sleep(TIEMPO_PAUSA)
finally:
# Reiniciar todos los canales de GPIO.
GPIO.cleanup()
Nota
La primera línea del programa ( |
Abre una terminal de la RPi y teclea el siguiente comando para correr el programa:
sudo python led.py
Cuando corremos el programa, el led se prende por medio segundo, y luego se apaga durante otro medio segundo. Esto se repite indefinidamente hasta que presionemos Ctrl-C
para terminar el programa.
3. Práctica: Sensor ultrasónico de distancia
En esta práctica programaremos un sensor ultrasónico que permitirá medir la distancia a la que se encuentra algún objeto posicionado en frente. El programa irá guardando las mediciones en un archivo de texto CSV que será de utilidad para la Práctica: Creando un servicio web.
3.1. Requisitos de hardware
-
RPi con su respectivo mouse, teclado, monitor y fuente de alimentación
-
Un sensor ultrasónico de distancia HC-SR04. Este sensor tiene cuatro pines:
-
VCC
: Alimentación de 5V -
TRIG
: Trigger o activador (entrada) del sensor -
ECHO
: Eco (salida) del sensor -
GND
: Tierra
-
-
Un protoboard
-
Dos resistencias R1 y R2 (ver descripción de abajo)
-
Cables conectores
Importante
La señal de salida del sensor ( |
Un divisor resistivo consiste de dos resistencias (R1 y R2) en serie conectados a un voltaje de entrada (Vin), el cual debe ser reducido a un voltaje de salida (Vout). En nuestro circuito, Vin será ECHO
, el cual requiere disminuir de 5V a nuestro Vout de 3.3V. El siguiente esquema muestra la disposición que deben tener las resistencias:
Partimos de la siguiente fórmula:
Sabemos que Vin = 5V y Vout = 3.3V. Por tanto lo que nos interesa calcular es:
Despejando tenemos:
Si conocemos el valor de la resistencia R2 podemos fácilmente calcular la resistencia R1. Por ejemplo, si R2 = 2kΩ, R1 tendría que ser igual a 1030.303Ω o algún otro valor cercano (por ejemplo 1kΩ).
3.2. Requisitos de software
-
Sistema operativo Raspbian
-
Python 2.7
3.3. Armando el proyecto
La siguiente figura, elaborada en Fritzing, muestra la manera de conectar los componentes:
Las conexiones son las siguientes:
-
El pin
VCC
del sensor se conecta a cualquier pin de 5V de la RPi. -
El pin
TRIG
del sensor se conecta al pin GPIO 23 de la RPi. -
El pin GPIO 24 de la RPi se conecta a una pista disponible del protoboard. Un extremo de la resistencia R2 se conecta a esta pista, y el otro extremo se conecta a tierra (cualquiera de los pines
GND
de la RPi). Un extremo de la resistencia R1 se conecta también a esta pista, y el otro extremo se conecta al pinECHO
del sensor. -
El pin
GND
del sensor se conecta a tierra (cualquiera de los pinesGND
de la RPi).
3.4. Código de Python
Copia y pega el siguiente programa en un editor de texto.
# coding=utf-8
# Importar las funciones necesarias de los módulos RPi,
# time y datetime.
import RPi.GPIO as GPIO
import time
from datetime import datetime
# Pin GPIO donde está conectado el activador (entrada) del
# sensor HC-SR04.
TRIG = 23
# Pin GPIO donde está conectado el eco (salida) del sensor
# HC-SR04.
ECHO = 24
# Nombre del archivo de texto donde se guardan todas las
# mediciones.
ARCHIVO_SALIDA = 'datos_sensor.csv'
# Crear el archivo de mediciones. El archivo tiene un
# formato CSV (Comma Separated Values). Cada renglón
# contiene tres datos delimitados por comas. Los datos
# son los siguientes:
# i.- El número de medición
# ii.- La fecha y hora en la que se tomó la medición
# iii.- La distancia medida
with open(ARCHIVO_SALIDA, 'w') as archivo:
archivo.write('#, Fecha/Hora, Distancia\n')
# Indicar que se usa el esquema de numeración de pines
# de BCM (Broadcom SOC channel), es decir los números de
# pines GPIO (General-Purpose Input/Output).
GPIO.setmode(GPIO.BCM)
# Establecer que TRIG es un canal de salida.
GPIO.setup(TRIG, GPIO.OUT)
# Establecer que ECHO es un canal de entrada.
GPIO.setup(ECHO, GPIO.IN)
print "Medición de distancias en progreso"
# Contar cuantas mediciones llevamos.
numero = 0
try:
# Ciclo infinito.
# Para terminar el programa se debe presionar Ctrl-C.
while True:
# Apagar el pin activador y permitir un par de
# segundos para que se estabilice.
GPIO.output(TRIG, GPIO.LOW)
print "Esperando a que el sensor se estabilice"
time.sleep(2)
# Prender el pin activador por 10 micro segundos
# y después volverlo a apagar.
GPIO.output(TRIG, GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(TRIG, GPIO.LOW)
# En este momento el sensor envía 8 pulsos de 40KHz
# (ultrasonido) y coloca su salida ECHO en HIGH.
# Se debe detectar este evento e iniciar un conteo
# de tiempo.
print "Iniciando eco"
while True:
pulso_inicio = time.time()
if GPIO.input(ECHO) == GPIO.HIGH:
break
# La salida ECHO se mantendrá en HIGH hasta recibir
# el eco reflejado por el obstáculo. En ese momento
# el sensor pondrá ECHO en LOW y se debe terminar
# de contar el tiempo.
while True:
pulso_fin = time.time()
if GPIO.input(ECHO) == GPIO.LOW:
break
# La duración del eco se mide en segundos.
duracion_eco = pulso_fin - pulso_inicio
# Sabemos que:
#
# distancia = velocidad * tiempo
#
# La velocidad del sonido es de 343 m/s (34,300
# centímetros por segundo). Necesitamos dividir
# el valor resultante entre dos porque la medición
# corresponde al tiempo que tarda el pulso
# ultrasónico en llegar al obstáculo y regresar
# nuevamente al sensor.
distancia = (34300 * duracion_eco) / 2
# Imprimir resultado.
print "Distancia: %.2f cm" % distancia
# Incrementar el número de mediciones realizadas.
numero += 1
# Guardar resultado en el archivo de texto.
with open(ARCHIVO_SALIDA, 'a') as archivo:
ahora = datetime.now()
archivo.write('%d, %s, %.2f\n' %
(numero, ahora, distancia))
finally:
# Reiniciar todos los canales de GPIO.
GPIO.cleanup()
Para correr el programa teclea el siguiente comando desde la terminal:
sudo python ultrasonico.py
Coloca un obstáculo en frente del sensor a diferentes distancias en momentos distintos para observar los cambios en las mediciones. El programa debe producir una salida similar a la siguiente:
Medición de distancias en progreso Esperando a que el sensor se estabilice Iniciando eco Distancia: 93.76 cm Esperando a que el sensor se estabilice Iniciando eco Distancia: 93.81 cm Esperando a que el sensor se estabilice Iniciando eco Distancia: 21.01 cm Esperando a que el sensor se estabilice Iniciando eco Distancia: 21.68 cm Esperando a que el sensor se estabilice Iniciando eco Distancia: 22.09 cm Esperando a que el sensor se estabilice Iniciando eco Distancia: 92.75 cm
Presiona Ctrl-C
para terminar el programa.
4. Práctica: ¡Hola web!
En esta práctica programaremos un pequeño servidor de web que correrá en la RPi. Al conectarse al servidor desde un navegador aparecerá una página con el mensaje “¡Hola web!”.
4.1. Requisitos de hardware
-
RPi con su respectivo mouse, teclado, monitor y fuente de alimentación
-
Adaptador Wi-Fi USB
4.2. Requisitos de software
-
Sistema operativo Raspbian
-
Python 2.7
-
Bottle: framework de web para Python
Para instalar Bottle, en la terminal de la RPi corre el siguiente comando:
sudo apt-get install python-bottle
4.3. Código de Python
Copia y pega el siguiente programa en un editor de texto.
# coding=utf-8
# Importar las funciones necesarias del módulo bottle.
from bottle import route, run
# Definir una ruta para nuestro servidor.
@route('/hola')
def hola():
# Devolver un mensaje al cliente.
return "¡Hola web!"
# Ejecutar el servidor usando el puerto indicado. El host
# 0.0.0.0 permite que clientes externos accedan a este
# servidor.
run(host='0.0.0.0', port=8080)
Desde la terminal de la RPi teclea el siguiente comando para correr el servidor de web:
python servidor_web.py
Presiona Ctrl-C
en esta misma terminal cuando desees detener el servidor.
Puedes acceder al servidor web desde la misma RPi. Coloca el siguiente URL en la barra de direcciones del navegador:
http://localhost:8080/hola
Debe aparecer una página con el siguiente mensaje:
¡Hola web!
Si deseas acceder al servidor web desde otra computadora conectada a la misma red local, primero necesitas determinar la dirección IP de la RPi. En la terminal de la RPi corre el siguiente comando:
ifconfig wlan0
Sugerencia
Sustituye |
La dirección IP aparece en la segunda línea de la salida después de: inet addr:
(por ejemplo: 10.48.0.42
). Usando dicha dirección, escribe el URL correspondiente en la barra de direcciones del navegador de la otra computadora, algo similar a:
http://10.48.0.42:8080/hola
La salida debe ser la misma que se obtuvo anteriormente:
¡Hola web!
5. Práctica: Creando un servicio web
En esta última práctica vamos a crear un servicio web que permitirá obtener la información capturada por el sensor ultrasónico de distancias Práctica: Sensor ultrasónico de distancia.
Un servicio web es un sistema de software diseñado para permitir interoperatibilidad máquina a máquina en una red. Nuestro servicio web leerá el archivo de texto CSV que generó nuestro programa que controla el sensor ultrasónico y lo devolverá para ser consumido por algún otro programa, por ejemplo un editor de hojas de cálculo como Microsoft Excel o LibreOffice Calc.
5.1. Requisitos de hardware y software
Para esta práctica se requiere la misma configuración de hardware y software que se usó en las prácticas de Práctica: Sensor ultrasónico de distancia y Práctica: ¡Hola web!.
5.2. Código de Python
Copia y pega el siguiente programa en un editor de texto.
# coding=utf-8
# Importar las funciones necesarias del módulo bottle.
from bottle import route, run, static_file
# Definir una ruta para nuestro servidor.
@route('/sensor')
def sensor():
# Devolver el contenido del archivo de texto con las
# mediciones registradas. Indicar que dicho contenido
# es un documento de Microsoft Excel.
return static_file('datos_sensor.csv', '.',
mimetype='application/vnd.ms-excel')
# Ejecutar el servidor usando el puerto indicado. El host
# 0.0.0.0 permite que clientes externos accedan a este
# servidor.
run(host='0.0.0.0', port=8080)
Desde la terminal de la RPi teclea el siguiente comando para correr el servidor de web:
python sensor_web.py
Importante
Asegúrate de no intentar correr |
Presiona Ctrl-C
en esta misma terminal cuando desees detener el servidor.
Coloca el siguiente URL en la barra de direcciones del navegador (sustituye localhost
por la dirección IP correspondiente si deseas realizar la consulta desde otra computadora conectada a la misma red que la RPi):
http://localhost:8080/sensor
Dependiendo de cómo esté configurado el navegador, el resultado de la petición podrá abrir automáticamente un programa como Excel o un simple editor de texto.
Puedes tener corriendo en otra ventana de terminal el programa ultrasonico.py
. De esta forma tu servicio web devuelve siempre las mediciones en vivo, con dos segundos de retraso a lo mucho.