You are on page 1of 57

Table

of Contents
Introduccin 1.1
GPIO 1.2
WEB I 1.3
WEB II 1.4
Introduccin

Introduccin al Raspberry Pi

Qu es un Raspberry pi?
1. Es un ordenador de placa reducida de bajo coste.
2. Naci para estimular la enseanza de ciencias de la computacin en las escuelas del
Reino Unido( plataforma educativa).
3. Actualmente es una plataforma de desarrollo.

Recursos
SoC: Broadcom BCM2835 (CPU + GPU + DSP + SDRAM + puerto USB)
CPU: ARM 1176JZF-S a 700 MHz (familia ARM11)
Introduccin

Juego de instrucciones: RISC de 32 bits


GPU: Broadcom VideoCore IV, OpenGL ES 2.0, MPEG-2 y VC-1 (con licencia),
1080p30 H.264/MPEG-4 AVC
Memoria (SDRAM): 512 MiB (compartidos con la GPU)
Puertos USB 2.0: 4
Entradas de video: Conector MIPI CSI que permite instalar un
mdulo de cmara desarrollado por la RPF
Salidas de video: Conector RCA (PAL y NTSC), HDMI (rev1.3 y 1.4), Interfaz DSI para
panel LCD
Salidas de audio: Conector de 3.5 mm, HDMI
Almacenamiento integrado: MicroSD
Conectividad de red: 10/100 Ethernet (RJ-45) via hub USB
Perifricos de bajo nivel: GPIO, SPI, I2C, UART
Consumo energtico: 600 mA, (3.0 W)
Fuente de alimentacin: 5V va Micro USB o GPIO header
Dimensiones: 85.60mm 53.98mm
Sistemas operativos soportados:GNU/Linux: Debian (Raspbian), Fedora (Pidora), Arch
Linux (Arch Linux ARM), Slackware Linux. RISC OS

Modelos
RPI 1 Modelo A

RPI 1 Modelo A+
Introduccin

RPI 1 Modelo B

RPI 1 Modelo B+
Introduccin

RPI 2 Modelo B

RPI ZERO
Introduccin

RPI 3 Modelo B
Introduccin

RPI 1 Model RPI 1 RPI 1 Model RPI 1 Model


A Model A+ B B+

Broadcom Broadcom Broadcom Broadcom


SoC
BCM2835 BCM2835 BCM2835 BCM2835

ARM11 ARM11 ARM11


ARMv6 700
CPU ARMv6 700 ARMv6 700 ARMv6 700
MHz
MHz MHz MHz

Broadcom
Broadcom Broadcom Broadcom
VideoCore
VideoCore IV VideoCore IV VideoCore IV
IV 250
GPU 250 MHz. 250 MHz. 250 MHz.
MHz.
OpenGL ES OpenGL ES OpenGL ES
OpenGL
2.0 2.0 2.0
ES 2.0
256 MB 256 MB 512 MB 512 MB
LPDDR LPDDR LPDDR LPDDR
RAM
SDRAM 400 SDRAM SDRAM 400 SDRAM 400
MHz 400 MHz MHz MHz

USB 1 USB 2.0 1 USB 2.0 2 USB 2.0 4 USB 2.0

HDMI 1.4
HDMI 1.4 @ HDMI 1.4 @ HDMI 1.4 @
@
Salidas de vdeo 1920x1200 1920x1200 1920x1200
1920x1200
pxeles pxeles pxeles
pxeles
Almacenamiento SD/MMC microSD SD/MMC microSD

S, 10/100 S, 10/100
Ethernet No No
Mbps Mbps

85,60mmx56,5 65mmx56,5 85,60mmx56,5 85,60mmx56,5


Tamao
mm mm mm mm
Peso 45 g. 23 g. 45 g. 45 g.

Precio 25 dlares 20 dlares 35 dlares 35 dlares

Relacin con otros ordenadores

Herramientas
Windows
Introduccin

Win32DiskImager (Descargar)
Putty (Descargar)
WinSCP (Descargar)
Advanced IP Scanner (Descargar)
SDFormater (Descargar)

Linux

$ sudo dd bs=4M if=/path/of/raspbian-image.img of=/dev/mmcblk0


$ sudo apt-get -y install nmap
$ sudo nmap -sn ip.of.red.0/24
$ ssh pi@your.rpi.ip.address
$ scp your_archivo pi@your.rpi.ip.address:"/home/pi"

Materiales
MicroSD
Cable ethernet
Fuente de 5V 2amp
Raspberry pi
PC
Software Putty
Cable HDMI(opcional)
Teclado(opcional)
Mouse(opcional)
Usb Wifi(opcional)

Instalacion de SO
1. SO Raspbian, descargarlo de la pgina oficial de Raspberry Pi desde aqu
2. una memora microSD de al menos 4Gb (recomiendo que sea de clase 10)
3. software para grabar el SO en la memoria microSD, en este caso optaremos por
Win32DiskImager

El usuario por defecto es pi y la contrasea raspberry

Primera conexin:
Formaremos una red local entre el Rpi y la PC para poder acceder a esta sin necesidad de
una pantalla y teclado ni dems conectores.Los materiales que se necesitaremos son:
Introduccin

Despues de grabar la memora microSD con Raspbian, lo insertamos en la pc y vamos a


editar el archivo cmdline.txt:

pi@raspberrypi:~ $ nano boot/cmdline.txt


dwc_otg.lpm_enable=0 console=ttyAMA0,115200 <...> rootwait ip=your.rpi.ip.address

Luego insertamos la memoria en el raspberry pi, y alimentamos la raspberry pi, en paralelo


cambiamos la configuracin de ethernet en nuestra PC con la siguiente configuracin:

ip address: your.rpi.ip.another_address
netmask: 255.255.255.0
gateway: your.rpi.ip.address

Y conectamos la Rpi con la PC mediante el cable ethernet, y abrimos el programa Putty y


colocaremos la ip del raspberry pi, aceptamos la llave SSH y colocamos el usuario:pi y la
contrasea:raspberry cuando nos pidan. Luego de esto configuramos una mejor conexin
ya sea cableada o inalmbrica.

Desde https://www.raspberrypi.org/documentation/remote-access/ssh/ :

As of the November 2016 release, Raspbian has the SSH server disabled by default.
You will have to enable it manually. This is done using raspi-config: Enter sudo raspi-
config in the terminal, first select Interfacing options, then navigate to ssh, press Enter
and select Enable or disable ssh server. For headless setup, SSH can be enabled by
placing a file named 'ssh', without any extension, onto the boot partition of the SD card.

RASPBIAN JESSIE LITE

Segun un aviso de la actualizacin, se removio el acceso ssh por defecto por lo que no se
podr seguir el manual para versiones posteriores a Noviembre del 2016.

En los foros nos muestra una solucin para la version Lite de raspbian. Primero debemos
ingresar al archivo cmdline.txt aadir lo siguiente:

ip=192.168.1.200::192.168.1.1:255.255.255.0:rpi:eth0:off

Esta estructuta tiene la forma:

ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>

Despues de esto para habilitar la conexin ssh solo es necesario crear un archivo vacio
llamado ssh.
Introduccin

En el caso de nuestra computadora debemos configurarlo como:

$ ip address: 192.168.1.xxx
$ netmask: 255.255.255.0
$ gateway: 192.168.1.1

Nota: La creacin del archivo ssh o ssh.txt habilta el protcolo ssh en RASPBIAN JESSIE
WITH PIXEL pero la configuracin de ip esttica genera que el boot no se complete.

Cableada(IP Dinmica)
No editamos nada pero necesitaremos un software que escanee la red como Advanced IP
Scanner donde buscaremos la red que tenga como fabricante a Raspberry Pi Foundation.

Cableada(IP Esttica)
Editamos el archivo interfaces:

pi@raspberrypi:~ $ sudo nano /etc/networks/interfaces

y cambiamos a:

auto eth0
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.1.11
netmask 255.255.255.0
gateway 192.168.1.1 #direccin ip del router

Inalmbrica
Editamos el archivo wpa_supplicant.conf:&nbsp:

pi@raspberrypi:~ $ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

y cambiamos a:

network={
ssid="Your ssid"
psk="your wifi password"
}
Introduccin

En ambos casos reiniciar la Rpi y conectarse ahora por el nuevo IP a travs del cliente
SSH, en nuestro caso Putty(en el caso de una red inalmbrica averigue su IP con Advanced
IP Scanner )

Si la Raspberry Pi tiene acceso a internet comprobamos si esta bien configurado con el


siguiente comando:

pi@raspberrypi:~ $ ping -c 3 8.8.8.8


PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=173 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=45 time=180 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=45 time=172 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 172.677/175.469/180.461/3.554 ms

Y sino tendremos que configurar el DNS, para ello editamos el archivo /etc/resolv.conf

pi@raspberrypi:~ $ sudo nano /etc/resolv.conf


nameserver 8.8.8.8
nameserver 8.8.4.4

Con ello ya deberiamos poder acceder a internet, comprobamos ello con el comando
anteriormente descrito

Introduccin al S.O. GNU-Linux


Linux, es un kernel, es decir, el ncleo de un Sistema Operativo, mientras que GNU/Linux,
el Sistema Operativo que utiliza el Kernel Linux como ncleo, creado, difundido y promovido
a travs del Proyecto GNU, por la Free Software Foundation, organizacin sin fines de
lucro, fundada por Richard Stallman, principal precursor del Software Libre.

El Kernel Linux, parte fundamental del Sistema Operativo, fue desarrollado por Linus
Torvals, utilizando como modelo a UNIX. Una de las diferencias fundamentales entre los
ncleos Linux y UNIX, es que el primero, es Software Libre, mientras que el segundo no lo
es.

Por otra parte, mientras existe un nico Kernel Linux (con versiones diferentes), existen
decenas y hasta cientos de distribuciones GNU/Linux, es decir, diferentes Sistemas
Operativos basados en el Kernel Linux, entre las cuales se destacan: Debian, Ubuntu,
Lbuntu, Fedora, Gentoo, Slackware, CentOS, ArchLinux, Asturix, entre otros cientos.
Introduccin

Un sistema Linux reside bajo un rbol jerrquico de directorios muy similar a la estructura
del sistema de archivos de plataformas Unix.

Originariamente, en los inicios de Linux, este rbol de directorios no segua un estndar


cien por cien, es decir, podamos encontrar diferencias en l de una distribucin a otra.

Todo esto hizo pensar a la comunidad que, posteriormente, desarrollaran el proyecto FHS
(Filesystem Hierarchy Standard) en 1993.

Los Objetivos de FHS son:

Presentar un sistema de archivos coherente y estandarizado.


Facilidad para que el software prediga la localizacin de archivos y directorios
instalados.
Facilidad para que los usuarios prediga la localizacin de archivos y directorios
instalados.
Especificar los archivos y directorios mnimos requeridos.

Este estandr esta enfocado a:

Fabricantes de software independiente y creadores de sistemas operativos, para que


establezcan una estructura de ficheros lo ms compatible posible.
Usuarios comunes, para que entiendan el significado y el contendido de cada uno de
los elementos del sistema de archivos

Otro concepto muy importante es que en Linux todo es un archivo.

Organizacin de Archivos

El directorio raiz (/)


Todo surge a partir del directorio raz (/).

El contenido de este directorio debe ser el adecuado para reiniciar, restaurar, recuperar y/o
reparar el sistema, es decir, debe proporcionar mtodos, herramientas y utilidades
necesarias para cumplir estas especificaciones.

Contenido del directorio raz:

/bin

En este directorio se ubica el cdigo binario o compilado de los programas y comandos que
pueden utilizar todos los usuarios del sistema.

La denominacin es clara, bin de BINARY (binario en castellano).


Introduccin

No debe haber subdirectorios en /bin.

/boot

Este directorio contiene todo lo necesario para que funcione el proceso de arranque del
sistema.

/boot almacena los datos que se utilizan antes de que el kernel comience a ejecutar
programas en modo usuario.

El ncleo del sistema operativo (normalmente se guarda en el disco duro como un fichero
imagen llamado vmlinuz-versin _ ncleo) se debe situar en este directorio o, en el
directorio raz.

El ncleo tiene la capacidad de crear dos entornos o modos de ejecucin totalmente


separados.

Uno de ellos est reservado para el propio kernel, denominado el modo ncleo; y el otro
est reservado para el resto de programas, llamado el modo usuario.

Realmente se crean dos entornos totalmente separados, es decir, cada uno tiene su propia
zona de memoria y procesos independientes.

Dmonos cuenta que esta tcnica ofrece mucha seguridad y estabilidad al sistema.

Cuando un proceso del modo usuario necesita recursos del modo kernel (por ejemplo,
acceder a la memoria USB) se hacen uso de las famosas llamadas al sistema (interface que
ofrece el ncleo para la comunicacin del modo usuario con el modo kernel).

/dev

Este directorio almacena las definiciones de todos los dispositivos. Como se ha


mencionado, cada dispositivo tiene asociado un archivo especial.

Por ejemplo, el contenido de la sexta particin del disco duro ser /dev/hda5.

El fichero asociado al ratn tipo PS/2 ser /dev/psaux.

Adems, es importante saber que los dispositivos pueden ser de bloque o de carcter.

Normalmente los dispositivos de bloque son los que almacenan datos y, los de carcter los
que transfieren datos.

En definitiva, la estructura de este directorio es algo complejo. Podramos dedicar otro


artculo entero para poder explicar en profundidad el contenido y funcionamiento especifico
del directorio /dev. De momento nos vasta con saber que Linux lo utiliza para asociar
dispositivos (devices) con ficheros.
Introduccin

NOTA: El subdirectorio /dev/null es como un agujero negro. Esto es as, puesto que
cualquier dato que se almacena aqu, desaparece. Es muy til para redireccionar los errores
por ejemplo:

/etc

El directorio /etc contiene archivos necesarios para configuracin del sistema.

Archivos que son propios del ordenador y que se utilizan para controlar el funcionamiento
diversos programas.

Deben ser ficheros estticos y nunca pueden ser archivos binarios y/o ejecutables.

Algunos subdirectorios contenidos en /etc:

X11. Subdirectorio para la configuracin del sistema de ventanas. Es opcional.

SGML. Subdirectorio para la configuracin de SGML. Es opcional.

Xml. Subdirectorio para la configuracin de XML. Es opcional.

X11 Sistema de ventanas graficas originario de UNIX en su versin 11. Este sistema
tiene la peculiaridad de ser totalmente independiente del sistema operativo. Es una
estructura cliente-servidor.

XML - eXtensible Markup Language (lenguaje de marcas extensible). Es un


metalenguaje de etiquetas.

SGML - Standard Generalized Markup Language (Lenguaje de Marcacin


Generalizado). Sistema para la organizacin y etiquetado de documentos.

En definitiva, /etc mantiene los archivos de configuracin del sistema para un ordenador
especfico.

/home

Directorio que contiene los subdirectorios que son directorios origen para cada uno de los
usuarios del sistema.

Cada subdirectorio /home/user de cada usuario proporciona el lugar para almacenar sus
ficheros, as como los archivos de configuracin propios de cada uno.

Es importante saber que tambin algunos servicios, y no solo usuarios, crean aqu su
directorio origen, por ejemplo: el servicio de transferencia de ficheros (FTP).

El administrador tiene su propio directorio home, que es /root.

/lib
Introduccin

El directorio /lib contiene libreras compartidas (similar a las dlls para los usuarios de
Windows) necesarias para arrancar el sistema y para los ficheros ejecutables contenidos
en, por ejemplo, /bin.

Normalmente las libreras son ficheros binarios escritos en lenguaje C.

Tambin contiene mdulos del kernel esenciales que permiten el funcionamiento de muchos
elementos Hardware. Se ubicarn normalmente en /lib/modules/versin-del-kernel/.

En el apartado /usr/include se explica que son y como funcionan las libreras y los archivos
cabecera.

/media

Este directorio contiene los subdirectorios que se utilizan como puntos del montaje para los
medios de almacenamiento, tales como disquetes, CD-ROM y memorias USBs.

/mnt

Este directorio contiene sistemas de archivos externos que hayan sido montados.

Las entidades que aparecen dentro de /mnt representan recursos externos a los que se
puede acceder a travs de este directorio.

/opt

En este directorio (/opt de options, u opciones en castellano) se suelen instalar


complementos o add-ons de los programas.

Las aplicaciones crean un subdirectorio dentro de /opt denominado con el mismo nombre
del programa.

/root

Este directorio es el directorio /home del administrador del sistema (root).

/sbin

Los programas y comandos que se utilizan para la administracin del sistema se almacenan
en /sbin, /usr/sbin y /usr/local/sbin.

/sbin nicamente contiene los ejecutables esenciales para el arranque, recuperacin y


reparacin del sistema.

Todos estos directorios (/sbin, /usr/sbin y /usr/local/sbin) se utilizan con fines


administrativos, por tanto, slo puede ejecutar su contenido el administrador.
Introduccin

/srv

Contiene los archivos de datos especficos para cada servicio instalado en el sistema.

/tmp

En este directorio se guardan los archivos temporales.

El directorio /usr
Es la segunda seccin ms grande o estructura jerr quica (despus del directorio raz) del
sistema de ficheros.

Este directorio est pensado para almacenar datos que se puedan compartir con otros
hosts.

Estos datos adems deben ser inalterables, es decir, slo de lectura.

Normalmente, este directorio tiene su particin propia.

Comnmente, se almacena aqu el software instalado en el sistema.

Estructura de /usr

/usr/bin

ste es el directorio primario de comandos ejecutables del sistema.

/usr/bin alberga los archivos ejecutables vinculados al software instalado en el sistema.

/usr/include

Linux est escrito en lenguaje C.

En C es posible utilizar funciones que ya estn predefinidas (como otros muchos lenguajes
de programacin) para incluirlas en el programa que estemos haciendo. Esta tcnica se
denomina programacin modular.

Estas funciones se llaman comnmente archivos cabecera (.h de header) y contienen las
declaraciones externas de una librera.

La manera de incluir estos archivos cabecera en nuestro programa, es haciendo uso de la


directiva include; de ah la denominacin del subdirectorio.

Todos estos ficheros cabecera (que necesite el software instalado en el sistema) se


almacenan en este subdirectorio.
Introduccin

*Una librera no es ms que un programa compilado, donde originariamente se implemento


el cdigo fuente de las funciones que la componen.

La declaracin pblica del conjunto de funciones de la librera reside en los archivos


cabecera.

Vemos parte de su contenido:

/usr/lib

Este directorio incluye libreras compartidas y ficheros binarios pensados para no ser
ejecutados directamente por los usuarios del sistema.

/usr/local/

/usr/local/ es para uso del administrador del sistema cuando instala software localmente.
Puede usarse para programas y datos que son compartibles entre un grupo de mquinas

Este subdirectorio tiene una estructura similar a la del directorio /usr.

/usr/sbin

Este directorio contiene comandos y programas no esenciales usados exclusivamente por


el administrador de sistema.

Como se ha comentado, los comandos necesarios para la reparacin, recuperacin y otras


funciones esenciales del sistema, se almacenan en /sbin.

/usr/src

Por lo general, en /usr/src (src de source o, fuente en castellano) se guarda el cdigo fuente
del Kernel del sistema.

Para comprobar si tenemos en nuestra distribucin los fuentes del kernel instalados,
deberamos ver un enlace simblico llamado linux.

El directorio /var
Este directorio va ha contener ficheros de datos variables y temporales, as como archivos
spool (ficheros almacenados en fila en espera a ejecutarse, como por ejemplo colas de
impresin).

Todos los log del sistema y los generados por los servicios instalados, se ubican dentro de
la estructura jerrquica de /var. Esto quiere decir que el tamao global de este directorio va
ha crecer constantemente.

La utilidad de /var radica en poder detectar problemas para prevenirlos y solucionarlos.


Introduccin

Es aconsejable montar en una nueva particin este directorio. Si no se pudiera, es preferible


ubicar /var fuera de la particin raz y de la particin /usr.

Distribucin de algunos subdirectorios de /var

/var/cache

Subdirectorio pensado para albergar datos de aplicaciones en cache (usados en un espacio


breve de tiempo).

El sistema de paquetes de Debian (apt-get), mantiene y almacena todos los paquetes que
nos hemos instalado con el gestor de paquetes Apt-get. Por ejemplo, si ejecutamos:

pi@raspberry:# sudo apt-get install nmap

Debian se bajar de algn repositorio especificado en /etc/apt/sources.list el archivo


nmap_version.deb, lo almacenar en /var/cache/apt y lo instalar desde esta ruta.

Posteriormente lo podemos borrar. Por defecto Debian almacena aqu todo los paquetes
que nos hemos instalado con su gestor de paquetes Apt-get.

/var/lib

Encontramos aqu informacin sobre el estado variable de las aplicaciones.

/var/lock

Aqu se almacenan los ficheros que estn bloqueados por el sistema.

/var/log

En /var/log se guardan los mensajes de registro generados por el sistema operativo y por
diversos servicios.

Por ejemplo:

En /var/log/messages son los logs generados por el kernel, en /var/log/httpd/access_log


encontramos quien (desde que ip) est accediendo a nuestro servidor Web y, en
/var/log/wtmp encontraremos todos los accesos y salidas en el sistema.

/var/mail

Linux enviar aqu los archivos de correos de cada usuario del sistema.

/var/run
Introduccin

/var/run contiene archivos con informacin del sistema que lo describen desde que se
arranc. Generalmente, se borrar todos los archivos que cuelgan de este subdirectorio al
comenzar el proceso de arranque.

Estos archivos con informacin del sistema son los llamados archivos identificados de
procesos PID, que guardan el identificador del proceso (Process ID).

Podemos ver aqu los archivos PID en un instante determinado en mi mquina:

/var/spool

/var/spool contiene ficheros almacenados en forma de fila de trabajos, para un


procesamiento posterior.

Un ejemplo claro puede ser los trabajos que guarda la impresora para, posteriormente,
ejecutarlos por un orden de llegada y/o prioridad.

/var/tmp

Algunos datos temporales se almacenan aqu y que, posiblemente, pueden aparecer en


nuestra distribucin GNU/Linux para no saturar el directorio /tmp.

Existen otra serie de directorios que no especifica el estndar FSH, pero que son
importantes.

Directorio /lost+found. Perdidos y encontrados

Las herramientas y utilidades para restaurar y/o reparar el sistema de archivos almacenan
los datos en este directorio.

Es un espacio temporal donde se guardan los datos que se recuperan despus de una
cada del sistema.

Fijmonos que, normalmente en cada particin que creemos existir un /lost+found en el


nivel superior.

Por ltimo, decir que este directorio existe slo en distribuciones que tengan como sistemas
de archivos ext2 o ext3.

Directorio /proc

/proc es un sistema de archivos virtual. Se genera y actualiza dinmicamente, es decir,

no se mantiene en el disco duro, se mantiene el la memoria RAM. Es el sistema quien lo


crea y lo destruye.
Introduccin

Este directorio contiene informacin sobre los procesos, el ncleo e informacin relativa al
sistema.

Comandos en GNU-Linux
Algunos de los miles de comandos de linux!!!

Comando Funcin Uso


man manual $ man man

ls listing $ ls /home/pi

cd change directory $ cd ..

mv move $ mv carpeta1 carpeta2

rm remove $ rm archivo.txt

rmdir remove directory $ rmdir carpeta

mkdir make directory $ mkdir carpeta

cp copy $ cp archivo1.txt archivo2.txt

find find $ find archivo.txt

locate locate $ locate archivo.txt

Uso del editor Nano


$ nano name_of_file

raspi-config
La herramienta Raspi-config le ayuda a configurar su Raspberry Pi; varios ajustes se
pueden cambiar con esta herramienta sin tener que conocer los comandos correctos para
su uso.

$ sudo raspi-config
Introduccin

Escritorio Remoto: VNC


$ sudo apt-get install tightvncserver
$ vncserver :1 -geometry 1280x800 -depth 16 -pixelformat rgb565

Para windows descargar desde aqu

Para linux instalar:

pi@raspberrypi:~ $ sudo apt-get -y install

ingresar con your.rpi.ip.address:1

Editor remoto: Sublime


Usar la terminal para editar no es amigable, por ello recurrimos a esta gran utilidad.

Instalar sublime
1. Instalar sublime desde aqu
2. Instalar Package Control Ejecutar View/Console y pegar
Introduccin

import urllib2,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa15


48d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.instal
led_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urll
ib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler()) ); by = urllib2.
urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashli
b.sha256(by).hexdigest(); open( os.path.join( ipp, pf), 'wb' ).write(by) if dh ==
h else None; print('Error validating download (got %s instead of %s), please try m
anual install' % (dh, h) if dh != h else 'Please restart Sublime Text to finish in
stallation')

3. Ejecutar ctrl-shift-p, escribir install y seleccionar rsub

Instalar rmate

pi@raspberrypi:~ $ sudo wget -O /usr/local/bin/rsub https://raw.github.com/aurora/rmat


e/master/rmate
pi@raspberrypi:~ $ sudo chmod +x /usr/local/bin/rsub

Configurar Putty
1. Ejecutar como administrador putty
2. Seleccionar Connection/SSH/tunnels
3. Colocar en Source port: 52698, en Destination:127.0.0.1:52698 y seleccionar
Remote

USO

pi@raspberrypi:~ $ rsub your_file

Resumen

pi@raspberrypi:~ $ sudo apt-get update


pi@raspberrypi:~ $ sudo apt-get upgrade
pi@raspberrypi:~ $ sudo apt-get install -y tree
pi@raspberrypi:~ $ sudo apt-get install -y mlocate
pi@raspberrypi:~ $ sudo updatedb
GPIO

Manejo de los GPIO's

Instalacin
$ sudo apt-get -y update
$ sudo apt-get -y upgrade
$ sudo apt-get -y install python-dev
$ sudo apt-get -y install python-rpi.gpio

Datasheet
GPIO
GPIO

Uso de GPIO con Python


LED
Un led es un componente electrnico cuya funcin principal es convertir la energa
elctrica en una fuente luminosa, la palabra led proviene del acrnimo ingles Light
Emmiting Diode o diodo emisor de luz.

Blink

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
led = 18 #GPIO18
delay = 1 #one second
GPIO.setwarnings(False) #disable warnings
GPIO.setmode(GPIO.BCM) # mode BCM or Board
GPIO.setup(led, GPIO.OUT) # input or output
while True:
GPIO.output(led, True)
time.sleep(delay)
GPIO.output(led, False)
time.sleep(delay)
GPIO

PWM

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
led = 18 #GPIO18
GPIO.setwarnings(False) #disable warnings
GPIO.setmode(GPIO.BCM) # mode BCM or Board
GPIO.setup(led, GPIO.OUT) # input or output
pwm_led = GPIO.PWM(led, 500)
pwm_led.start(100)
while True:
duty_s = raw_input("Enter Brightness (0 to 100): ")
duty = int(duty_s)
pwm_led.ChangeDutyCycle(duty)

Pulsador
Los pulsadores (PUSHBUTTONS), son interruptores que al ser accionados de forma
manual cambian de estado y al soltarlo regresan a su estado inicial
GPIO

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
led = 18 #GPIO18
delay = 0.2 #0.2 seconds
GPIO.setwarnings(False) #disable warnings
GPIO.setmode(GPIO.BCM) # mode BCM or Board
GPIO.setup(led, GPIO.IN, pull_up_down=GPIO.PUD_UP) # input or output
while True:
input_state = GPIO.input(led)
if input_state == False:
print("Button Pressed")
time.sleep(delay)
GPIO

Pulsador II

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
led = 18 #GPIO18
switch = 23
GPIO.setwarnings(False) #disable warnings
GPIO.setmode(GPIO.BCM) # mode BCM or Board
GPIO.setup(led, GPIO.OUT) # input or output
GPIO.setup(switch, GPIO.IN, pull_up_down=GPIO.PUD_UP)
led_state = False
old_input_state = True
while True:
new_input_state = GPIO.input(switch)
if new_input_state == False and old_input_state == True:
led_state = not led_state
old_input_state = new_input_state
GPIO.output(led, led_state)

Ultrasonido
GPIO

Los sensores de ultrasonidos o sensores ultrasnicos son detectores de proximidad


que trabajan libres de roces mecnicos y que detectan objetos a distancias que van
desde pocos centmetros hasta varios metros. El sensor emite un sonido y mide el
tiempo que la seal tarda en regresar. Estos reflejan en un objeto, el sensor recibe el
eco producido y lo convierte en seales elctricas, las cuales son elaboradas en el
aparato de valoracin

import RPi.GPIO as GPIO


import time
GPIO.setmode(GPIO.BCM)
TRIG = 23
ECHO = 24
print "Distance Measurement In Progress"
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
GPIO.output(TRIG, False)
print "Waiting For Sensor To Settle"
time.sleep(2)
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
while GPIO.input(ECHO)==0:
pulse_start = time.time()
while GPIO.input(ECHO)==1:
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 17150
distance = round(distance, 2)
print "Distance:",distance,"cm"
GPIO.cleanup()
GPIO

Servomotor
Un servomotor (tambin llamado servo) es un dispositivo similar a un motor de
corriente continua que tiene la capacidad de ubicarse en cualquier posicin dentro de
su rango de operacin, y mantenerse estable en dicha posicin.
GPIO

from Tkinter import *


import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 100)
pwm.start(5)
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
scale = Scale(frame, from_=0, to=180, orient=HORIZONTAL, command=self.update)
scale.grid(row=0)
def update(self, angle):
duty = float(angle) / 10.0 + 2.5
pwm.ChangeDutyCycle(duty)

root = Tk()
root.wm_title('Servo Control')
app = App(root)
root.geometry("200x50+0+0")
root.mainloop()

DHT22

Instalacin
$ sudo apt-get -y update
$ sudo apt-get -y install python-pip
$ sudo pip install adafruit_python_dht

import Adafruit_DHT
import time

while True:
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4)
if humidity is not None and temperature is not None:
print('Temp={0:0.1f}* Humidity={1:0.1f}%'.format(temperature, humidity))
else:
print('Failed to get reading. Try again!')

time.sleep(1)

Resumen
GPIO

sudo apt-get -y update


sudo apt-get -y upgrade
sudo apt-get install -y python-dev
sudo apt-get install -y python-rpi.gpio
sudo apt-get install -y python-pip
sudo pip install adafruit_python_dht
WEB I

Servidores y Bases de Datos con


Raspberry

Control de la Raspberry pi a travs de una


pgina web.
El proyecto que se implementar consiste en el monitoreo de sensores y control de
actuadores mediante la interfaz de una pgina web.

En la siguiente imagen se muestra un esquema simple de la aplicacin, esta se compondr


de todas principales:

1. Aplicacin WEB: Esta se encarga de mostrar los datos guardados en la base de


datos.

2. Servicio o Demonio: Este se encarga de leer los datos que proporciona los sensores y
guardarlo en la base de datos.

Esta arquitectura tiene como cualidad de ser simple y escalable.


WEB I

Aplicacin WEB:
Para esta parte implementaremos un servicio restful.

Usaremos como framework django , para implementar con facilidad el servicio restful
aadiremos django rest framework .

Como primer paso instalaremos un entorno virtual llamado virtualenv

pi@raspberrypi:~ $ sudo apt-get install -y python-pip


pi@raspberrypi:~ $ sudo pip install virtualenv

Teniendo instalado virtualenv, creamos un entorno de trabajo que llamaremos rpi-env:

pi@raspberrypi:~ $ mkdir ~/projects


pi@raspberrypi:~ $ cd ~/projects
pi@raspberrypi:~/projects $ virtualenv rpi-env

Lo activamos con:
WEB I

pi@raspberrypi:~/projects $ source rpi-env/bin/activate

Teniendo todo lo anterior instalamos django y django-rest-framework:

(rpi-env) pi@raspberrypi:~/projects $ pip install django


(rpi-env) pi@raspberrypi:~/projects $ pip install djangorestframework

Creamos un proyecto llamado DomoProject y una aplicacin llamada Domo:

(rpi-env) pi@raspberrypi:~/projects $ django-admin.py startproject DomoProject .


(rpi-env) pi@raspberrypi:~/projects $ ./manage.py startapp Domo
(rpi-env) pi@raspberrypi:~/projects $ ./manage.py migrate

Para verificar que vamos por buen camino ejecutamos el siguiente comando para visualizar
la estructura de carpetas generadas:

(rpi-env) pi@raspberrypi:~/projects $ tree | head -22

Debiendo obtener lo siguiente:

.
db.sqlite3
Domo
admin.py
apps.py
__init__.py
migrations
__init__.py
models.py
tests.py
views.py
DomoProject
__init__.py
__init__.pyc
settings.py
settings.pyc
urls.py
urls.pyc
wsgi.py
manage.py
rpi-env
bin

Vamos a hacer una pequea prueba para ello editamos el archivo settings.py y aadimos la
ip del raspberry(en mi caso '192.168.2.9') en la linea ALLOWED_HOSTS = []
WEB I

(rpi-env) pi@raspberrypi:~/projects $ nano DomoProject/settings.py


ALLOWED_HOSTS = ['192.168.2.9']

Y luego lanzamos el servidor de desarrollo:

(rpi-env) pi@raspberrypi:~/projects $ ./manage.py runserver 0.0.0.0:8000

Ingresamos desde nuestra pc a un buscador y colocamos la ip del raspberry seguido del


puerto 8000, en mi caso http://192.168.2.9:8000/ y deberiamos obtener algo similar a lo que
muestra la siguiente imagen:

Para apagar el servidor apretamos Ctrl+C

Lo primero que haremos es crear un modelo de la base de datos, para ello usaremos la
ORM de django, editamos el archivo models.py que se encuentra dentro de la carpeta
Domo. Hacemos los mismo con serializers.py

(rpi-env) pi@raspberrypi:~/projects $ nano Domo/models.py

Domo/models.py
WEB I

from __future__ import unicode_literals

from django.db import models

class Sensor(models.Model):
date_created = models.DateTimeField(auto_now=True)
temperature = models.FloatField()
humidity = models.FloatField()

(rpi-env) pi@raspberrypi:~/projects $ nano Domo/serializers.py

Domo/serializers.py

from rest_framework import serializers

from Domo.models import Sensor

class SensorSerializer(serializers.ModelSerializer):
class Meta:
model = Sensor
fields = ('date_created', 'temperature', 'humidity')

(rpi-env) pi@raspberrypi:~/projects $ nano Domo/views.py

Domo/views.py

from django.shortcuts import render


from rest_framework import viewsets

from Domo.models import Sensor


from Domo.serializers import SensorSerializer

class SensorViewSet(viewsets.ModelViewSet):
queryset = Sensor.objects.all().order_by('-id')[:40]
serializer_class = SensorSerializer

def home(request):
return render(request, 'index.html')

(rpi-env) pi@raspberrypi:~/projects $ nano Domo/urls.py


WEB I

Domo/urls.py

from rest_framework import routers

from Domo.views import SensorViewSet

router = routers.DefaultRouter()
router.register(r'sensors', SensorViewSet)

urlpatterns = router.urls

(rpi-env) pi@raspberrypi:~/projects $ nano Domo/admin.py

Domo/admin.py

from django.contrib import admin

from Domo.models import Sensor

@admin.register(Sensor)
class SensorAdmin(admin.ModelAdmin):
list_display = ('date_created', 'temperature', 'humidity')

Luego aadimos la aplicacin Domo al proyecto:

(rpi-env) pi@raspberrypi:~/projects $ nano DomoProject/settings.py

DomoProject/settings.py
WEB I

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'rest_framework',

'Domo',
]

....

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # modificamos esta parte
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

...

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

(rpi-env) pi@raspberrypi:~/projects $ nano DomoProject/urls.py

DomoProject/urls.py
WEB I

"""DomoProject URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin

from Domo.views import home

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('Domo.urls', namespace='core')),
url(r'^$', home),
]

(rpi-env) pi@raspberrypi:~/projects $ mkdir templates


(rpi-env) pi@raspberrypi:~/projects $ nano templates/index.html

templates/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Proyecto</title>
</head>

<body>
<div id="header">
<h2 style="text-align: center">Proyecto</h2>
</div>
<div id="content">
<div class="demo-container">
<div id="placeholder" style="margin:0 auto;"></div>
<br>
<div style="width:1000px;margin:0 auto;">
Actualizar: <input type="checkbox" id="myCheck" checked>
WEB I

<br>
Time : <input type="number" id="interval" value="1000">
<br>
<label id="lblLast"></label>
</div>
</div>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var temperature = {
x: [],
y: [],
fill: 'tonexty',
type: 'scatter',
name: 'Temperatura'
};

var humidity = {
x: [],
y: [],
fill: 'tonexty',
type: 'scatter',
name: 'Humedad',
yaxis: 'y2'
};

var layout = {
title: 'Sensores',
showlegend: true,
legend: {
x: 0,
y: 1,
traceorder: 'normal',
font: {
family: 'sans-serif',
size: 12,
color: '#000'
},
bgcolor: '#E2E2E2',
},
yaxis: {
title: 'C',
range: [0, 100]
},
yaxis2: {
title: '%',
side: 'right',
overlaying: 'y',
WEB I

range: [0, 100]


}
};

var data = [humidity, temperature];

var updateInterval = 1000;


// Load all posts on page load
function GetData() {
$.ajax({
url: "/api/sensors/", // the endpoint
type: "GET", // http method
// handle a successful response
success: function (data) {
temperature['x'] = [];
temperature['y'] = [];

humidity['x'] = [];
humidity['y'] = [];

$.each(data, function (index, value) {


temperature['x'].push(new Date(value['date_created']));
temperature['y'].push(value['temperature']);

humidity['x'].push(new Date(value['date_created']));
humidity['y'].push(value['humidity']);
});
},
// handle a non-successful response
error: function (xhr, errmsg, err) {

}
});

};

function update() {
GetData();

if (document.getElementById("myCheck").checked) {
Plotly.newPlot('placeholder', data, layout);
document.getElementById('lblLast').innerHTML = "Temperatura Actual: "
+
temperature['y'][0] + "<br>Humedad Actual: " + humidity['y'][0];
}
var interval = Number(document.getElementById("interval").value);
if (!isNaN(interval)) {
updateInterval = interval;
}
setTimeout(update, updateInterval);
}

update();
WEB I

})
;
</script>
</html>

(rpi-env) pi@raspberrypi:~/projects $ ./manage.py makemigrations


(rpi-env) pi@raspberrypi:~/projects $ ./manage.py migrate
(rpi-env) pi@raspberrypi:~/projects $ ./manage.py collectstatic
(rpi-env) pi@raspberrypi:~/projects $ ./manage.py runserver 0.0.0.0:8000

Ahora instalamos el servidor Apache:

(rpi-env) pi@raspberrypi:~/projects $ sudo apt-get install -y apache2 libapache2-mod-w


sgi

Despues de instalamos editamos el archivo 000-default.conf ubicado en


/etc/apache2/sites-available , aadiendo lo siguiente antes de < /VirtualHost >
WEB I

(rpi-env) pi@raspberrypi:~/projects $ sudo nano /etc/apache2/sites-available/000-defau


lt.conf

Alias /static /home/pi/projects/static


<Directory /home/pi/projects/static>
Require all granted
</Directory>
<Directory /home/pi/projects/DomoProject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGIDaemonProcess projects python-path=/home/pi/projects python-home=/home/pi/projects


/rpi-env
WSGIProcessGroup projects
WSGIScriptAlias / /home/pi/projects/DomoProject/wsgi.py

Luego le damos permisos a las carpetas y archivos.

(rpi-env) pi@raspberrypi:~/projects $ sudo chmod 664 ~/projects/db.sqlite3


(rpi-env) pi@raspberrypi:~/projects $ sudo chown www-data ~/projects/db.sqlite3
(rpi-env) pi@raspberrypi:~/projects $ sudo chown www-data ~/projects
(rpi-env) pi@raspberrypi:~/projects $ sudo service apache2 restart

Ahora podremos ingresar directamente a la ip sin necesidad de indicar el puerto ni ejecutar


ningun comando ya que se esta ejecutando el servidor de produccin.

Servicio o Demonio
Creamos un archivo llamado myservice.py

(rpi-env) pi@raspberrypi:~/projects $ mkdir myservice


(rpi-env) pi@raspberrypi:~/projects $ nano myservice/myservice.py

myservice.py

#!/usr/bin/env python
import logging
import logging.handlers
import argparse
import sys
from datetime import datetime
import sqlite3
import Adafruit_DHT
WEB I

def getSensors():
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4)
t = datetime.utcnow()
return t, temperature, humidity
# Deafults
LOG_FILENAME = "/tmp/myservice.log"
LOG_LEVEL = logging.INFO # Could be e.g. "DEBUG" or "WARNING"

# Define and parse command line arguments


parser = argparse.ArgumentParser(description="My simple Python service")
parser.add_argument("-l", "--log", help="file to write log to (default '" + LOG_FILENA
ME + "')")

# If the log file is specified on the command line then override the default
args = parser.parse_args()
if args.log:
LOG_FILENAME = args.log

# Configure logging to log to a file, making a new file at midnight and keeping the la
st 3 day's data
# Give the logger a unique name (good practice)
logger = logging.getLogger(__name__)
# Set the log level to LOG_LEVEL
logger.setLevel(LOG_LEVEL)
# Make a handler that writes to a file, making a new file at midnight and keeping 3 ba
ckups
handler = logging.handlers.TimedRotatingFileHandler(LOG_FILENAME, when="midnight", bac
kupCount=3)
# Format each log message like this
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
# Attach the formatter to the handler
handler.setFormatter(formatter)
# Attach the handler to the logger
logger.addHandler(handler)

# Make a class we can use to capture stdout and sterr in the log
class MyLogger(object):
def __init__(self, logger, level):
"""Needs a logger and a logger level."""
self.logger = logger
self.level = level

def write(self, message):


# Only log if there is a message (not just a new line)
if message.rstrip() != "":
self.logger.log(self.level, message.rstrip())

# Replace stdout with logging to file at INFO level


sys.stdout = MyLogger(logger, logging.INFO)
# Replace stderr with logging to file at ERROR level
sys.stderr = MyLogger(logger, logging.ERROR)
WEB I

conn = sqlite3.connect('/home/pi/projects/db.sqlite3')
curs = conn.cursor()

while True:
curs.execute("INSERT INTO Domo_sensor(date_created, temperature, humidity) VALUES(
(?), (?), (?))", getSensors())
conn.commit()
conn.close()

(rpi-env) pi@raspberrypi:~/projects $ nano myservice.sh

myservice.sh

#!/bin/sh

### BEGIN INIT INFO


# Provides: myservice
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Put a short description of the service here
# Description: Put a long description of the service here
### END INIT INFO

# Change the next 3 lines to suit where you install your script and what you want to c
all it
DIR=/usr/local/bin/myservice
DAEMON=$DIR/myservice.py
DAEMON_NAME=myservice

# Add any command line options for your daemon here


DAEMON_OPTS=""

# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO
from Python.
DAEMON_USER=root

# The process ID of the script when it runs is stored here:


PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $D
AEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
log_end_msg $?
WEB I

}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}

case "$1" in

start|stop)
do_${1}
;;

restart|reload|force-reload)
do_stop
do_start
;;

status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;

*)
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit 1
;;

esac
exit 0

(rpi-env) pi@raspberrypi:~/projects $ sudo chmod 755 myservice/myservice.py


(rpi-env) pi@raspberrypi:~/projects $ sudo chmod +x myservice.sh
(rpi-env) pi@raspberrypi:~/projects $ sudo cp myservice.sh /etc/init.d
(rpi-env) pi@raspberrypi:~/projects $ sudo update-rc.d myservice.sh defaults
(rpi-env) pi@raspberrypi:~/projects $ sudo cp -rf myservice/ /usr/local/bin/
(rpi-env) pi@raspberrypi:~/projects $ sudo service myservice start
WEB I

Salida:

Clientes
Python

GET method:

import requests
import datetime

url = 'http://192.168.2.9/api/sensors/'

response = requests.get(url)
assert response.status_code == 200

for data in response.json():


date = datetime.datetime.strptime(data['date_created'][:-1], "%Y-%m-%dT%H:%M:%S.%f"
)
humidity = data['humidity']
temperature = data['temperature']
print("Fecha: {}, Humedad: {}, Temperatura: {}".format(date, humidity, temperature
))

POST method:
WEB I

import requests
import datetime
import json
import time

url = 'http://192.168.2.9/api/sensors/'

for i in range(100):
date = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')

headers = {'Content-type': 'application/json'}


response = requests.post(url, data =json.dumps({'date_created': date,'temperature'
: 11.1, 'humidity': 10.1}), headers=headers)
assert response.status_code == 201
time.sleep(0.1)

Resumen
Para los alumnos del curso es necesario ejecutar los siguientes comandos:

sudo apt-get install -y update


sudo apt-get install -y upgrade
sudo apt-get install -y install python-dev
sudo apt-get install -y python-rpi.gpio
sudo apt-get install -y python-pip
sudo pip install adafruit_python_dht
sudo pip install virtualenv
mkdir ~/projects
cd ~/projects
virtualenv rpi-env
source rpi-env/bin/activate
pip install django
pip install djangorestframework
sudo apt-get install -y apache2 libapache2-mod-wsgi

Fuente
https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-
with-apache-and-mod_wsgi-on-ubuntu-14-04
http://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-
background-as-a-service-on-boot/
WEB II

Configuracin de motion
Creamos un directorio para guardar las imagenes:

pi@raspberrypi:~ $ mkdir /home/pi/Monitor


pi@raspberrypi:~ $ sudo chgrp motion /home/pi/Monitor
pi@raspberrypi:~ $ sudo chmod g+rwx /home/pi/Monitor
pi@raspberrypi:~ $ sudo chmod -R g+w /home/pi/Monitor/

Instalamos la librera motion.

pi@raspberrypi:~ $ sudo apt-get install -y motion

Editamos el archivo motion.conf, buscando los siguientes campos y los cambiamos a lo


siguientes valores:

pi@raspberrypi:~ $ sudo nano /etc/motion/motion.conf

stream_localhost off
webcontrol_localhost off
framerate 60
target_dir /home/pi/Monitor

Editamos el archivo /etc/default/motion y cambiamos de no a yes

pi@raspberrypi:~ $ sudo nano /etc/default/motion

start_motion_daemon=yes

Despues ejecutamos lo siguiente:

pi@raspberrypi:~ $ sudo service motion stop


pi@raspberrypi:~ $ sudo service motion start

Y Accedemos a la imagen de la cmara a traves de la url desde nuestro buscador:


http://{your-rpi-address}:8081/

Obteniendo lo siguiente:
WEB II

Las imagenes y videos pueden llenar el almacenamiento, por ello configuramos que pasada
los 15 minutos despues de cada hora borre todos excepto las 20 ultimas imagenes:

pi@raspberrypi:~ $ sudo crontab -e

15 * * * * (date; ls /home/pi/Monitor/*.jpg | head -n -20 | xargs rm -v) >> /tmp/image


s_deleted 2>&1

Configurando el Servidor
Implementamos el servidor para que provea y guarde los datos, para ellos creamos el
modelo Motor que contiene 2 atributos: date_created que guarda la fecha de creacin del
comando y status que contiene el comando respectivo. Adems de los serializers y vistas
respectivas.

Domo/models.py
WEB II

from __future__ import unicode_literals

from django.db import models

STATUS_CHOICES = (
('F', 'Forward'),
('B', 'Backward'),
('L', 'Left'),
('R', 'Right'),
('S', 'Stop')
)

# Create your models here.

class Motor(models.Model):
date_created = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='S')

Domo/serializers.py:

from rest_framework import serializers

from Domo.models import Motor

class MotorSerializer(serializers.ModelSerializer):
class Meta:
model = Motor
fields = ('date_created', 'status')

Domo/views.py:

from django.shortcuts import render


from rest_framework import viewsets

# Create your views here.


from Domo.models import Motor
from Domo.serializers import MotorSerializer

class MotorViewSet(viewsets.ModelViewSet):
queryset = Motor.objects.all()
serializer_class = MotorSerializer

Domo/admin.py
WEB II

from django.contrib import admin


from Domo.models import Motor

# Register your models here.


@admin.register(Motor)
class MotorAdmin(admin.ModelAdmin):
list_display = ('date_created', 'status')

Domo/urls.py

from rest_framework import routers


from Domo.views import MotorViewSet

router = routers.DefaultRouter()
router.register(r'motors', MotorViewSet)

urlpatterns = router.urls

Creamos el archivo index.html donde implementamos las peticiones mediante javascript


utilizando ajax.

templates/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Proyecto</title>
</head>

<body>

<div style="text-align:center;margin:auto;">
<button onclick="forward()">Avanzar</button>
</div>

<div style="text-align:center;margin:auto;">
<button onclick="backward()">Retroceder</button>
</div>

<div style="text-align:center;margin:auto;">
<button onclick="left()">Izquierda</button>
</div>

<div style="text-align:center;margin:auto;">
<button onclick="right()">Derecha</button>
</div>

<div style="text-align:center;margin:auto;">
WEB II

<button onclick="stop()">Parar</button>
</div>

<img id="ip_link" src="" target="_blank" />

</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script type="text/javascript">

var ip = location.host;
document.getElementById("ip_link").src = "http://"+ip+":8081";

// Load all posts on page load


function move(state) {
$.ajax({
url: "/api/motors/", // the endpoint
type: "POST", // http method
// handle a successful response
success: function (data) {

},
data: {
'date_created': new Date(),
'status': state
},
// handle a non-successful response
error: function (xhr, errmsg, err) {

}
});

};

function forward(){
move('F');
};

function backward(){
move('B');
};

function left(){
move('L');
};

function right(){
move('R');
};

function stop(){
move('S');
};
WEB II

</script>
</html>

Obteniendo algo similar a la siguiente imagen:

Luego implementamos la clase Car que se encarga de manejar los movimientos del
vehculo.

Car.py

import RPi.GPIO as GPIO


import time

class Car:
def __init__(self, motorL, motorR):
"""
Manejar los motores
:param pins:
[in1, in2, in3, in4]
"""
GPIO.setmode(GPIO.BCM)
self._pinsA = motorL
self._pinsB = motorR

for pin in (self._pinsA + self._pinsB):


GPIO.setup(pin, GPIO.OUT)

def motorOn(self, pins):


GPIO.output(pins[0], False)
GPIO.output(pins[1], True)
WEB II

def motorOff(self, pins):


GPIO.output(pins[0], False)
GPIO.output(pins[1], False)

def motorReverse(self, pins):


GPIO.output(pins[0], True)
GPIO.output(pins[1], False)

def forward(self):
self.stop()
self.motorOn(self._pinsA)
self.motorOn(self._pinsB)
time.sleep(0.2)
self.stop()

def backward(self):
self.stop()
self.motorReverse(self._pinsA)
self.motorReverse(self._pinsB)
time.sleep(0.2)
self.stop()

def left(self):
self.stop()
self.motorOn(self._pinsB)
self.motorReverse(self._pinsA)
time.sleep(0.2)
self.stop()

def right(self):
self.stop()
self.motorOn(self._pinsA)
self.motorReverse(self._pinsB)
time.sleep(0.2)
self.stop()

def stop(self):
self.motorOff(self._pinsA)
self.motorOff(self._pinsB)

def __exit__(self, exc_type, exc_val, exc_tb):


GPIO.cleanup()

Ahora creamos la clase Data que se encarga de obtener los datos, filtrar el ltimo y verificar
si este ha sido creado en menos de 1 segundo. Si cumple lo anterior obtenemos el
comando status y realizamos la tarea respectiva.

main.py
WEB II

from datetime import datetime, timedelta


from Car import Car
import requests

class Data:
def __init__(self, url, timeout=1):
self.url = url
self.before = None
self.timeout = timeout

def load(self):
response = requests.get(self.url)
assert response.status_code == 200
data = response.json()[-1]
date = datetime.strptime(data['date_created'][:-1], "%Y-%m-%dT%H:%M:%S.%f")
if self.before == date:
return
self.before = date
u = datetime.utcnow()
diff = u - date
if diff < timedelta(seconds=self.timeout):
return data['status']

if __name__ == '__main__':
data = Data(url='http://192.168.2.10/api/motors/')
motorL = [17, 27]
motorR = [23, 24]

car = Car(motorL, motorR)

while True:
resp = data.load()
if resp == 'F':
car.forward()
elif resp == 'B':
car.backward()
elif resp == 'L':
car.left()
elif resp == 'R':
car.right()
elif resp == 'S':
car.stop()