Escolar Documentos
Profissional Documentos
Cultura Documentos
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
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
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
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
Herramientas
Windows
Introduccin
Win32DiskImager (Descargar)
Putty (Descargar)
WinSCP (Descargar)
Advanced IP Scanner (Descargar)
SDFormater (Descargar)
Linux
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
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
ip address: your.rpi.ip.another_address
netmask: 255.255.255.0
gateway: your.rpi.ip.address
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.
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
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
$ 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:
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: :
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 )
Y sino tendremos que configurar el DNS, para ello editamos el archivo /etc/resolv.conf
Con ello ya deberiamos poder acceder a internet, comprobamos ello con el comando
anteriormente descrito
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.
Todo esto hizo pensar a la comunidad que, posteriormente, desarrollaran el proyecto FHS
(Filesystem Hierarchy Standard) en 1993.
Organizacin de Archivos
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.
/bin
En este directorio se ubica el cdigo binario o compilado de los programas y comandos que
pueden utilizar todos los usuarios del sistema.
/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.
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
Por ejemplo, el contenido de la sexta particin del disco duro ser /dev/hda5.
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.
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
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.
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.
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).
/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.
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
Las aplicaciones crean un subdirectorio dentro de /opt denominado con el mismo nombre
del programa.
/root
/sbin
Los programas y comandos que se utilizan para la administracin del sistema se almacenan
en /sbin, /usr/sbin y /usr/local/sbin.
/srv
Contiene los archivos de datos especficos para cada servicio instalado en el sistema.
/tmp
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.
Estructura de /usr
/usr/bin
/usr/include
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.
/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
/usr/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.
/var/cache
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:
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
/var/lock
/var/log
En /var/log se guardan los mensajes de registro generados por el sistema operativo y por
diversos servicios.
Por ejemplo:
/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).
/var/spool
Un ejemplo claro puede ser los trabajos que guarda la impresora para, posteriormente,
ejecutarlos por un orden de llegada y/o prioridad.
/var/tmp
Existen otra serie de directorios que no especifica el estndar FSH, pero que son
importantes.
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.
Por ltimo, decir que este directorio existe slo en distribuciones que tengan como sistemas
de archivos ext2 o ext3.
Directorio /proc
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!!!
ls listing $ ls /home/pi
cd change directory $ cd ..
rm remove $ rm archivo.txt
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
Instalar sublime
1. Instalar sublime desde aqu
2. Instalar Package Control Ejecutar View/Console y pegar
Introduccin
Instalar rmate
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
Resumen
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
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
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
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
2. Servicio o Demonio: Este se encarga de leer los datos que proporciona los sensores y
guardarlo en la base de datos.
Aplicacin WEB:
Para esta parte implementaremos un servicio restful.
Usaremos como framework django , para implementar con facilidad el servicio restful
aadiremos django rest framework .
Lo activamos con:
WEB I
Para verificar que vamos por buen camino ejecutamos el siguiente comando para visualizar
la estructura de carpetas generadas:
.
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
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
Domo/models.py
WEB I
class Sensor(models.Model):
date_created = models.DateTimeField(auto_now=True)
temperature = models.FloatField()
humidity = models.FloatField()
Domo/serializers.py
class SensorSerializer(serializers.ModelSerializer):
class Meta:
model = Sensor
fields = ('date_created', 'temperature', 'humidity')
Domo/views.py
class SensorViewSet(viewsets.ModelViewSet):
queryset = Sensor.objects.all().order_by('-id')[:40]
serializer_class = SensorSerializer
def home(request):
return render(request, 'index.html')
Domo/urls.py
router = routers.DefaultRouter()
router.register(r'sensors', SensorViewSet)
urlpatterns = router.urls
Domo/admin.py
@admin.register(Sensor)
class SensorAdmin(admin.ModelAdmin):
list_display = ('date_created', 'temperature', 'humidity')
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',
],
},
},
]
...
DomoProject/urls.py
WEB I
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
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('Domo.urls', namespace='core')),
url(r'^$', home),
]
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
humidity['x'] = [];
humidity['y'] = [];
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>
Servicio o Demonio
Creamos un archivo llamado 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"
# 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
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()
myservice.sh
#!/bin/sh
# 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
# 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
. /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
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
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')
Resumen
Para los alumnos del curso es necesario ejecutar los siguientes comandos:
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:
stream_localhost off
webcontrol_localhost off
framerate 60
target_dir /home/pi/Monitor
start_motion_daemon=yes
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:
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
STATUS_CHOICES = (
('F', 'Forward'),
('B', 'Backward'),
('L', 'Left'),
('R', 'Right'),
('S', 'Stop')
)
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:
class MotorSerializer(serializers.ModelSerializer):
class Meta:
model = Motor
fields = ('date_created', 'status')
Domo/views.py:
class MotorViewSet(viewsets.ModelViewSet):
queryset = Motor.objects.all()
serializer_class = MotorSerializer
Domo/admin.py
WEB II
Domo/urls.py
router = routers.DefaultRouter()
router.register(r'motors', MotorViewSet)
urlpatterns = router.urls
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>
</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";
},
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>
Luego implementamos la clase Car que se encarga de manejar los movimientos del
vehculo.
Car.py
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
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)
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
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]
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()