logo

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:

  1. Encender y apagar un led

  2. Controlar un sensor ultrasónico para medir distancias

  3. Montar un servidor de web sencillo

  4. 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:

led

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 Programming/Python 2.

Archivo: led.py
# 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 (# coding=utf-8) permite que nuestro archivo fuente de Python contenga caracteres propios del idioma español, por ejemplo vocales acentuadas o la letra eñe.

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 (ECHO) del HC-SR04 es de 5V. Sin embargo los pines GPIO de entrada de la RPi funcionan con 3.3V. Si se envía una señal de 5V a un puerto desprotegido de entrada de 3.3V, éste puede resultar dañado, y eso es algo que definitivamente queremos evitar. Necesitaremos usar un circuito divisor resistivo para disminuir el voltaje de salida del sensor y así permitir que la RPi reciba la señal correspondiente sin problemas.

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:

divisor resistivo

Partimos de la siguiente fórmula:

formula1

Sabemos que Vin = 5V y Vout = 3.3V. Por tanto lo que nos interesa calcular es:

formula2

Despejando tenemos:

formula3

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:

ultrasonico

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 pin ECHO del sensor.

  • El pin GND del sensor se conecta a tierra (cualquiera de los pines GND de la RPi).

3.4. Código de Python

Copia y pega el siguiente programa en un editor de texto.

Archivo: ultrasonico.py
# 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.

Archivo: servidor_web.py
# 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 wlan0 por eth0 si la RPi está conectada a la red a través de un cable ethernet.

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.

Archivo: sensor_web.py
# 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 servidor_web.py y sensor_web.py al mismo tiempo ya que se produciría el siguiente error: Address already in use. Esto se debe a que dos aplicaciones no deben usar simultáneamente el mismo número de puerto (el 8080 en nuestro caso).

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.