Para aprender cómo funciona la GPIO (General-purpose input/output) de Raspberry Pi he montado un pequeño rover motorizado que captura vídeo en tiempo real mediante una cámara USB y que puede ser controlado remotamente.
Quiero advertir que ya existen trabajos similares y productos prefabricados mejor acabados y seguramente con mayor rendimiento, pero si te interesara diseñar y hacer funcionar tu propio robot casero entonces te invito a que sigas leyendo :D
Eligiendo el hardware y conectando todo
La base es un viejo coche de control remoto por radiofrecuencia que compré hace años en un bazar chino. Sobre éste gira el proyecto: dos motores de corriente continua (DC) moviendo dos ejes para las ruedas de marcha adelante/atrás y dirección derecha/ izquierda:
Para mover los motores necesitamos un controlador H-Bridge o puente en H que no es más que un circuito electrónico que permite aplicar un voltaje a través de una carga en cualquier dirección, es decir, invertir la polaridad a nuestra elección para mover el motor en una dirección u otra. Además estos puentes en H permiten cortocircuitar para frenar en seco el motor o desconectar hasta su detención libre (free-run).
En este caso he elegido el módulo L298N, un controlador dual H-Bridge bastante popular y económico (4,35€) pero lo suficientemente potente como para impulsar motores de 5 a 35V y de hasta 2A.
Además proporciona un regulador de 5V integrado que puede ser utilizado para alimentar otras partes de la circuitería del robot:
En la base del coche de control remoto encastamos los dos módulos.
La Raspberry Pi es alimentada a través del conector micro USB con una batería SWPKPOWER SW-A22617 (6,20€) que ofrece una salida de 5V/800mA y una capacidad de 2600mAh y el controlador L298N recibe el suministro eléctrico mediante una pila de petaca Duracell de 9V alcalina (2,55€) con 565 mAh conectada al pin VCC y a GND. También es necesario conectar el pin 6 de la RPi a tierra.
Después conectamos los motores del coche a los pines de las salidas correspondientes: Motor A o izquierdo y Motor B o derecho e interconectamos los pines IN1, 2, 3 y 4 a las salidas digitales de la GPIO de la RPi (17, 27 y 10, 9 respectivamente).
El siguiente paso es puentear con jumpers los pines ENA y ENB a 5V para activar cada uno de los canales.
Una opción interesante sería no usar los jumpers y conectar 2 pines de la GPIO de la Raspberry Pi a los pines ENA y ENB del controlador y configurarlos como PWM (modulación por ancho de pulsos) para regular el consumo y la velocidad de los motores. Si bien lo he descartado en este proyecto porque con los motores actuales al disminuir la cantidad de energía apenas podían arrancar y llevar la carga (mover el robot).
El esquema físico queda entonces de la siguiente manera:
Fijaros también que aprovecharemos los dos puertos USB para conectar un nano adaptador inalámbrico modelo RaLink RT5370 (6,75€) mediante el cual controlaremos nuestro rover y una webcam de 1,3M con micrófono integrado (6,20€) para el stream de video.
Si sumamos cables y la carcasa para la pila de petaca, el coste total aproximado del hardware utilizado ronda los 80€. El resultado final es este:
Configurando la red inalámbrica de nuestro robot
Damos un giro a la parte del software. El sistema operativo de la Raspberry Pi para este proyecto es Raspbian con un kernel 3.6:
Lo primero que vamos a hacer es configurar la red inalámbrica para poder controlar nuestro rover remotamente por ssh. Para ello conectamos el dongle USB y comprobamos que se detecta correctamente:
Ahora, para conectarnos a nuestra red WiFi, tenemos que editar el fichero wpa_supplicant.conf y configurar el SSID con la clave compartida correspondiente:
Después paramos el interfaz inalámbrico y volvemos a levantarlo para recargar la configuración:
A continuación comprobamos la conectividad:
Preparando el streaming de video
Para el streaming de vídeo con la webcam USB utilizamos MJPG-streamer, una aplicación que captura JPG de webcams compatibles con Linux-UVC, sistema de archivos u otros plugins de entrada y los distribuye como M-JPEG a través de HTTP para navegadores web, VLC y otros programas. Es el sucesor de uvc-streamer, una aplicación de streaming de Linux-UVC con Pan/Tilt.
La instalación sólo requiere unos sencillos pasos:
Para probarlo ejecutamos el siguiente comando:
Ahora configuramos un pequeño script para cuando queramos lanzar el stream de video en background:
Controlando la GPIO de Raspberry Pi con WebIOPI
Webiopi es un API escrita en Python para controlar, depurar y utilizar la GPIO de la RPi localmente o de forma remota, desde un navegador o desde cualquier aplicación.
La utilizaremos porque nos permite ejecutar el proyecto muy rápidamente sin necesidad de tener demasiados conocimientos.
Su licencia es Apache License 2.0 y sus características son:
- API REST a través de HTTP y COAP (draft-14) con soporte multicast
- Servidor escrito en Python con cero dependencias
- Soporta GPIO, Serial, I2C, SPI, 1-Wire con cero dependencias
- Soporta más de 30 dispositivos, incluyendo DAC, ADC, sensores ...
- Completa biblioteca de Python para el servidor, GPIO, I2C, SPI, conductores y dispositivos de serie
- Compatible con Python 2 y 3
- Extensible y altamente personalizable
- Incluye protección de Usuario / clave
- Compatible con dispositivos móviles
- Incluye las aplicaciones web de depuración
. GPIO Header
. Lista GPIO
. Monitor Serial
. Monitor Dispositivos
- Biblioteca cliente Javascript construida sobre jQuery
- Biblioteca cliente Python con HTTP y soporte CoAP
Para instalarlo sólo necesitaremos Python, ya sea la versión 2.7 o la 3.2. Simplemente hay que descargar y extraer el paquete. El script de instalación se encargará automáticamente de descargar e instalar las dependencias requeridas usando apt-get.
Si no utilizas Raspbian es posible que tengas que instalar los encabezados de desarrollo de GCC y Python.
Ahora podemos llamar a webiopi directamente desde la línea de comandos:
Sin embargo perderemos el servidor y el estado de la GPIO tan pronto como paremos el script (CTRL-C) o cerremos el terminal.
Por ello es necesario iniciar el servicio en background mediante:
Si queremos que webiopi se inicie automáticamente cuando arranque de la RPi podemos utilizar el siguiente comando:
La base del código fuente se basa en dos artículos publicados en la revista MagPI (Cambot). Primero modificaremos su script en Python en /home/pi/cambot/cambot.py en el que definiremos el estado inicial de los pines de la GPIO y las macros que podrán ser llamadas externamente:
Como podéis ver en el código la configuración es sumamente sencilla. Se inicializan en OUT un par de pines para controlar cada motor y simplemente cambiando su estado (HIGH o LOW) es posible definir macros para cada movimiento.
Para que este script sea llamado al iniciar el servidor webiopi tendremos que especificarlo en el fichero de configuración /etc/webiopi/config. Para ello vamos al fichero config y especificamos la ruta en la sección de scripts:
Y aprovechando en este mismo fichero revisaremos el document root y el fichero index e indicaremos que se utilicen las credenciales del fichero passwd:
Para ello posteriormente generaremos el fichero passwd mediante el comando webiopi-passwd:
Una buena idea teniendo en cuenta que de esta manera no almacenaremos en claro la contraseña de acceso…
Finalmente creamos el fichero index.html en el document root especificado con los controles correspondientes usando jQuery y todas las funciones de javascript para a llamar a las macros escritas en Python. Fijaros que también incrustaremos (IMG) el streaming de video:
Y ya está. Sólo nos queda reiniciar el servidor webiopi para cargar la nueva configuración:
¡A jugar!
Antes de empezar os animo a ver la aplicación GPIO Header que permite visualizar y controlar cada uno de los pines de la RPi. Para ello abrimos en el navegador la URL:
http://raspberry:8000/app/gpio-header
Como podéis comprobar es posible cambiar el estado de cada pin sólo mediante un clic.
Ahora abriremos la url principal de nuestro frontal web:
http://raspberry:8000/
Y bueno, aquí os dejo un breve vídeo con el resultado:
Carencias, mejoras y próximos pasos
Como comentaba al principio quien decida basarse en esta entrada o similares para crear un rover de estas características tendrá que tener como objetivo principal el aprendizaje y no un rendimiento demasiado excelso.
Primero, las limitaciones de la webcam y del interfaz USB mediante el cual se conecta a la RPi harán que el streaming de vídeo denote un retardo que degradará en parte la experiencia del usuario. Si se quiere mejorar en este aspecto se tendría que pensar en la compra de la cámara por hardware que se conecta internamente y directa al procesador sin hacer uso de ningún chipset intermedio, utilizando el interfaz CSi dedicado que trae de serie. Con esto se mejorará ostensiblemente la tasa de fps (imágenes por segundo).
A parte del streaming de vídeo también se podría añadir al frontal web un botón para realizar una instantánea (a mayor resolución) y una opción para respaldar estas capturas (video y fotos) a algún servicio de almacenamiento en la nube tipo Dropbox.
Segundo, los motores del coche de radiocontrol reciclados son algo "vagos" y en cuanto la capacidad de las baterías disminuye sufren para mover la carga.
En este caso también podrían sustituirse y se podría modular por pulsos para controlar la velocidad del giro.
Si os dais cuenta en la protoboard delantera he realizado algunas conexiones para poner en serie la pila de 9V con las tres pilas AA (4,5V) que originalmente tenía el coche para ganar algo de potencia.
Por último, aunque eso ya será en otras entradas, tengo pendiente añadir más funcionalidades mediante sensores de ultrasonidos, detección de movimiento, leds, laser y reconocimiento por voz.
Por supuesto, se admiten sugerencias... ;)
Quiero advertir que ya existen trabajos similares y productos prefabricados mejor acabados y seguramente con mayor rendimiento, pero si te interesara diseñar y hacer funcionar tu propio robot casero entonces te invito a que sigas leyendo :D
Eligiendo el hardware y conectando todo
La base es un viejo coche de control remoto por radiofrecuencia que compré hace años en un bazar chino. Sobre éste gira el proyecto: dos motores de corriente continua (DC) moviendo dos ejes para las ruedas de marcha adelante/atrás y dirección derecha/ izquierda:
Para mover los motores necesitamos un controlador H-Bridge o puente en H que no es más que un circuito electrónico que permite aplicar un voltaje a través de una carga en cualquier dirección, es decir, invertir la polaridad a nuestra elección para mover el motor en una dirección u otra. Además estos puentes en H permiten cortocircuitar para frenar en seco el motor o desconectar hasta su detención libre (free-run).
En este caso he elegido el módulo L298N, un controlador dual H-Bridge bastante popular y económico (4,35€) pero lo suficientemente potente como para impulsar motores de 5 a 35V y de hasta 2A.
Además proporciona un regulador de 5V integrado que puede ser utilizado para alimentar otras partes de la circuitería del robot:
En la base del coche de control remoto encastamos los dos módulos.
La Raspberry Pi es alimentada a través del conector micro USB con una batería SWPKPOWER SW-A22617 (6,20€) que ofrece una salida de 5V/800mA y una capacidad de 2600mAh y el controlador L298N recibe el suministro eléctrico mediante una pila de petaca Duracell de 9V alcalina (2,55€) con 565 mAh conectada al pin VCC y a GND. También es necesario conectar el pin 6 de la RPi a tierra.
Después conectamos los motores del coche a los pines de las salidas correspondientes: Motor A o izquierdo y Motor B o derecho e interconectamos los pines IN1, 2, 3 y 4 a las salidas digitales de la GPIO de la RPi (17, 27 y 10, 9 respectivamente).
El siguiente paso es puentear con jumpers los pines ENA y ENB a 5V para activar cada uno de los canales.
Una opción interesante sería no usar los jumpers y conectar 2 pines de la GPIO de la Raspberry Pi a los pines ENA y ENB del controlador y configurarlos como PWM (modulación por ancho de pulsos) para regular el consumo y la velocidad de los motores. Si bien lo he descartado en este proyecto porque con los motores actuales al disminuir la cantidad de energía apenas podían arrancar y llevar la carga (mover el robot).
El esquema físico queda entonces de la siguiente manera:
Fijaros también que aprovecharemos los dos puertos USB para conectar un nano adaptador inalámbrico modelo RaLink RT5370 (6,75€) mediante el cual controlaremos nuestro rover y una webcam de 1,3M con micrófono integrado (6,20€) para el stream de video.
Si sumamos cables y la carcasa para la pila de petaca, el coste total aproximado del hardware utilizado ronda los 80€. El resultado final es este:
Configurando la red inalámbrica de nuestro robot
Damos un giro a la parte del software. El sistema operativo de la Raspberry Pi para este proyecto es Raspbian con un kernel 3.6:
pi@escorial ~ $ uname -a
Linux escorial 3.6.11+ #538 PREEMPT Fri Aug 30 20:42:08 BST 2013 armv6l GNU/Linux
Lo primero que vamos a hacer es configurar la red inalámbrica para poder controlar nuestro rover remotamente por ssh. Para ello conectamos el dongle USB y comprobamos que se detecta correctamente:
pi@escorial ~ $ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
[root@escorial ~]# lsusb -vs 001:004
Ahora, para conectarnos a nuestra red WiFi, tenemos que editar el fichero wpa_supplicant.conf y configurar el SSID con la clave compartida correspondiente:
pi@escorial ~ $ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="WLAN_AB"
psk="****************"
}
Después paramos el interfaz inalámbrico y volvemos a levantarlo para recargar la configuración:
pi@escorial ~ $ sudo wpa_action wlan0 stop
wpa_action: ifdown wlan0
Configuring interface wlan0=wlan0 (inet)
run-parts --verbose /etc/network/if-down.d
run-parts: executing /etc/network/if-down.d/upstart
run-parts: executing /etc/network/if-down.d/wpasupplicant
run-parts --verbose /etc/network/if-post-down.d
run-parts: executing /etc/network/if-post-down.d/wireless-tools
run-parts: executing /etc/network/if-post-down.d/wpasupplicant
wpa_supplicant: terminating wpa_supplicant daemon via pidfile /var/run/wpa_supplicant.wlan0.pid
Stopped /sbin/wpa_supplicant (pid 1755).
wpa_supplicant: removing /run/sendsigs.omit.d/wpasupplicant.wpa_supplicant.wlan0.pid
wpa_action: removing sendsigs omission pidfile: /run/sendsigs.omit.d/wpasupplicant.wpa_supplicant.wlan0.pid
pi@escorial ~ $ sudo ifup wlan0
A continuación comprobamos la conectividad:
pi@escorial ~ $ sudo wpa_cli status
Selected interface 'wlan0'
bssid=d0:71:33:21:d3:c6
ssid=WLAN_AB
id=0
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.1.39
address=7c:de:70:42:6f:38
do
Preparando el streaming de video
Para el streaming de vídeo con la webcam USB utilizamos MJPG-streamer, una aplicación que captura JPG de webcams compatibles con Linux-UVC, sistema de archivos u otros plugins de entrada y los distribuye como M-JPEG a través de HTTP para navegadores web, VLC y otros programas. Es el sucesor de uvc-streamer, una aplicación de streaming de Linux-UVC con Pan/Tilt.
La instalación sólo requiere unos sencillos pasos:
apt-get install libjpeg8-dev imagemagick subversion
cd /usr/src/
svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code
cd mjpg-streamer/mjpg-streamer
make
Para probarlo ejecutamos el siguiente comando:
pi@escorial /usr/src/mjpg-streamer-code/mjpg-streamer $ sudo ./mjpg_streamer -i "./input_uvc.so -y -n " -o "./output_http.so -n -w ./www"
MJPG Streamer Version: svn rev: 3:172
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 5
i: Format............: YUV
i: JPEG Quality......: 80
o: www-folder-path...: ./www/
o: HTTP TCP port.....: 8080
o: username:password.: disabled
o: commands..........: disabled
Ahora configuramos un pequeño script para cuando queramos lanzar el stream de video en background:
#!/bin/sh
PLUGINPATH=/usr/src/mjpg-streamer-code/mjpg-streamer
STREAMER=$PLUGINPATH/mjpg_streamer
DEVICE=/dev/video0
RESOLUTION=320x240
FRAMERATE=25
HTTP_PORT=8001
# check for existing webcam device
if [ ! -e "/dev/video0" ]; then
echo "stream.sh: Error - NO /dev/video0 device" 2>&1 | logger
exit 2
fi
#PLUGINPATH=/usr/local/lib
$STREAMER -i "$PLUGINPATH/input_uvc.so -y -n -d $DEVICE -r $RESOLUTION -f $FRAMERATE" -o "$PLUGINPATH/output_http.so -n -p $HTTP_PORT" -b
Controlando la GPIO de Raspberry Pi con WebIOPI
Webiopi es un API escrita en Python para controlar, depurar y utilizar la GPIO de la RPi localmente o de forma remota, desde un navegador o desde cualquier aplicación.
La utilizaremos porque nos permite ejecutar el proyecto muy rápidamente sin necesidad de tener demasiados conocimientos.
Su licencia es Apache License 2.0 y sus características son:
- API REST a través de HTTP y COAP (draft-14) con soporte multicast
- Servidor escrito en Python con cero dependencias
- Soporta GPIO, Serial, I2C, SPI, 1-Wire con cero dependencias
- Soporta más de 30 dispositivos, incluyendo DAC, ADC, sensores ...
- Completa biblioteca de Python para el servidor, GPIO, I2C, SPI, conductores y dispositivos de serie
- Compatible con Python 2 y 3
- Extensible y altamente personalizable
- Incluye protección de Usuario / clave
- Compatible con dispositivos móviles
- Incluye las aplicaciones web de depuración
. GPIO Header
. Lista GPIO
. Monitor Serial
. Monitor Dispositivos
- Biblioteca cliente Javascript construida sobre jQuery
- Biblioteca cliente Python con HTTP y soporte CoAP
Para instalarlo sólo necesitaremos Python, ya sea la versión 2.7 o la 3.2. Simplemente hay que descargar y extraer el paquete. El script de instalación se encargará automáticamente de descargar e instalar las dependencias requeridas usando apt-get.
Si no utilizas Raspbian es posible que tengas que instalar los encabezados de desarrollo de GCC y Python.
$ wget http://webiopi.googlecode.com/files/WebIOPi-0.6.0.tar.gz
$ tar xvzf WebIOPi-0.6.0.tar.gz
$ cd WebIOPi-0.6.0
$ sudo ./setup.sh
Ahora podemos llamar a webiopi directamente desde la línea de comandos:
$ sudo webiopi [-h] [-c config] [-l log] [-s script] [-d] [port]
Options:
-h, --help Display this help
-c, --config file Load config from file
-l, --log file Log to file
-s, --script file Load script from file
-d, --debug Enable DEBUG
Arguments:
port Port to bind the HTTP Server
Sin embargo perderemos el servidor y el estado de la GPIO tan pronto como paremos el script (CTRL-C) o cerremos el terminal.
Por ello es necesario iniciar el servicio en background mediante:
$ sudo /etc/init.d/webiopi start
y
$ sudo /etc/init.d/webiopi stop
Si queremos que webiopi se inicie automáticamente cuando arranque de la RPi podemos utilizar el siguiente comando:
$ sudo update-rc.d webiopi defaults
La base del código fuente se basa en dos artículos publicados en la revista MagPI (Cambot). Primero modificaremos su script en Python en /home/pi/cambot/cambot.py en el que definiremos el estado inicial de los pines de la GPIO y las macros que podrán ser llamadas externamente:
#imports import webiopi # Libreria GPIO GPIO = webiopi.GPIO # -------------------------------------------------- # # Definicion constantes # # -------------------------------------------------- # # GPIOs motor izquierdo L1=17 # H-Bridge 1 L2=27 # H-Bridge 2 # GPIOs motor derecho R1=10 # H-Bridge 3 R2=9 # H-Bridge 4 # -------------------------------------------------- # # Funciones motor izquierdo # # -------------------------------------------------- # def left_stop(): GPIO.output(L1, GPIO.LOW) GPIO.output(L2, GPIO.LOW) def left_forward(): GPIO.output(L1, GPIO.HIGH) GPIO.output(L2, GPIO.LOW) def left_backward(): GPIO.output(L1, GPIO.LOW) GPIO.output(L2, GPIO.HIGH) # -------------------------------------------------- # # Funciones motor derecho # # -------------------------------------------------- # def right_stop(): GPIO.output(R1, GPIO.LOW) GPIO.output(R2, GPIO.LOW) def right_forward(): GPIO.output(R1, GPIO.HIGH) GPIO.output(R2, GPIO.LOW) def right_backward(): GPIO.output(R1, GPIO.LOW) GPIO.output(R2, GPIO.HIGH) # -------------------------------------------------- # # Definicion macros # # -------------------------------------------------- # @webiopi.macro def go_forward(): left_forward() @webiopi.macro def go_backward(): left_backward() @webiopi.macro def turn_left(): right_forward() @webiopi.macro def turn_right(): right_backward() @webiopi.macro def stop(): left_stop() right_stop() # -------------------------------------------------- # # Iniciacializacion # # -------------------------------------------------- # def setup(): # Instalacion GPIOs GPIO.setFunction(L1, GPIO.OUT) GPIO.setFunction(L2, GPIO.OUT) GPIO.setFunction(R1, GPIO.OUT) GPIO.setFunction(R2, GPIO.OUT) def destroy(): # Resetea las funciones GPIO GPIO.setFunction(L1, GPIO.IN) GPIO.setFunction(L2, GPIO.IN) GPIO.setFunction(R1, GPIO.IN) GPIO.setFunction(R2, GPIO.IN)
Como podéis ver en el código la configuración es sumamente sencilla. Se inicializan en OUT un par de pines para controlar cada motor y simplemente cambiando su estado (HIGH o LOW) es posible definir macros para cada movimiento.
Para que este script sea llamado al iniciar el servidor webiopi tendremos que especificarlo en el fichero de configuración /etc/webiopi/config. Para ello vamos al fichero config y especificamos la ruta en la sección de scripts:
[SCRIPTS]
# Load custom scripts syntax :
# name = sourcefile
# each sourcefile may have setup, loop and destroy functions and macros
#myscript = /home/pi/webiopi/examples/scripts/macros/script.py
cambot = /home/pi/cambot/cambot.py
Y aprovechando en este mismo fichero revisaremos el document root y el fichero index e indicaremos que se utilicen las credenciales del fichero passwd:
[HTTP]
# HTTP Server configuration
enabled = true
port = 8000
# File containing sha256(base64("user:password"))
# Use webiopi-passwd command to generate it
passwd-file = /etc/webiopi/passwd
# Use doc-root to change default HTML and resource files location
#doc-root = /home/pi/webiopi/examples/scripts/macros
doc-root = /home/pi/cambot
# Use welcome-file to change the default "Welcome" file
welcome-file = index.html
Para ello posteriormente generaremos el fichero passwd mediante el comando webiopi-passwd:
$ sudo webiopi-passwd
WebIOPi passwd file generator
Enter Login: webiopi
Enter Password:
Confirm password:
Hash: e70c940a189251e9cd4515b3a1a6c6f02aa05c744a456ce360fe14bf2c5c0353
Saved to /etc/webiopi/passwd
Una buena idea teniendo en cuenta que de esta manera no almacenaremos en claro la contraseña de acceso…
Finalmente creamos el fichero index.html en el document root especificado con los controles correspondientes usando jQuery y todas las funciones de javascript para a llamar a las macros escritas en Python. Fijaros que también incrustaremos (IMG) el streaming de video:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" />
<title>CamBot</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
function init() {
var button;
button = webiopi().createButton("bt_up", "/\\", go_forward, stop);
$("#up").append(button);
button = webiopi().createButton("bt_left", "<", turn_left, stop);
$("#middle").append(button);
button = webiopi().createButton("bt_stop", "X", stop);
$("#middle").append(button);
button = webiopi().createButton("bt_right", ">", turn_right, stop);
$("#middle").append(button);
button = webiopi().createButton("bt_down", "\\/", go_backward, stop);
$("#down").append(button);
}
function go_forward() {
webiopi().callMacro("go_forward");
}
function go_backward() {
webiopi().callMacro("go_backward");
}
function turn_right() {
webiopi().callMacro("turn_right");
}
function turn_left() {
webiopi().callMacro("turn_left");
}
function stop() {
webiopi().callMacro("stop");
}
webiopi().ready(init);
</script>
<style type="text/css">
button {
margin: 5px 5px 5px 5px;
width: 50px;
height: 50px;
font-size: 24pt;
font-weight: bold;
color: black;
}
</style>
</head>
<body>
<div id="content" align="center">
<img width="320" height="240" src="http://192.168.1.37:8001/?action=stream"><br/>
<div id="up"></div>
<div id="middle"></div>
<div id="down"></div>
</div>
</body>
</html>
Y ya está. Sólo nos queda reiniciar el servidor webiopi para cargar la nueva configuración:
$ sudo /etc/init.d/webiopi restart
¡A jugar!
Antes de empezar os animo a ver la aplicación GPIO Header que permite visualizar y controlar cada uno de los pines de la RPi. Para ello abrimos en el navegador la URL:
http://raspberry:8000/app/gpio-header
Como podéis comprobar es posible cambiar el estado de cada pin sólo mediante un clic.
Ahora abriremos la url principal de nuestro frontal web:
http://raspberry:8000/
Y bueno, aquí os dejo un breve vídeo con el resultado:
Carencias, mejoras y próximos pasos
Como comentaba al principio quien decida basarse en esta entrada o similares para crear un rover de estas características tendrá que tener como objetivo principal el aprendizaje y no un rendimiento demasiado excelso.
Primero, las limitaciones de la webcam y del interfaz USB mediante el cual se conecta a la RPi harán que el streaming de vídeo denote un retardo que degradará en parte la experiencia del usuario. Si se quiere mejorar en este aspecto se tendría que pensar en la compra de la cámara por hardware que se conecta internamente y directa al procesador sin hacer uso de ningún chipset intermedio, utilizando el interfaz CSi dedicado que trae de serie. Con esto se mejorará ostensiblemente la tasa de fps (imágenes por segundo).
A parte del streaming de vídeo también se podría añadir al frontal web un botón para realizar una instantánea (a mayor resolución) y una opción para respaldar estas capturas (video y fotos) a algún servicio de almacenamiento en la nube tipo Dropbox.
Segundo, los motores del coche de radiocontrol reciclados son algo "vagos" y en cuanto la capacidad de las baterías disminuye sufren para mover la carga.
En este caso también podrían sustituirse y se podría modular por pulsos para controlar la velocidad del giro.
Si os dais cuenta en la protoboard delantera he realizado algunas conexiones para poner en serie la pila de 9V con las tres pilas AA (4,5V) que originalmente tenía el coche para ganar algo de potencia.
Por último, aunque eso ya será en otras entradas, tengo pendiente añadir más funcionalidades mediante sensores de ultrasonidos, detección de movimiento, leds, laser y reconocimiento por voz.
Por supuesto, se admiten sugerencias... ;)
Justo lo que estaba buscando. Gracias por este completisimo tuyo brto!
ResponderEliminar¿donde compraste la batería para la RPi y el controlador L298N?
ResponderEliminarhola @anonimo,
ResponderEliminarlos compre en DealExtreme y en Amazon respectivamente...
joo...que molon..
ResponderEliminarPedazo de entrada!! si señor, eres un maquina Vicente :D
ResponderEliminarTe importaría poner los links de las compras o pasarmelo por DM en @1Gbdeinfo??
Muchas gracias!!
This is mostly an unauthorized translation of my cambot article, published in the MagPi #9 and #10.
ResponderEliminarPlease add missing credits and licence, or ask before translating and copying.
Hi Eric,
ResponderEliminarperhaps you did not read in my post the sentence:
"La base del código fuente se basa en dos artículos publicados en la revista MagPI (Cambot). "
And it is not a translation of your article, I've only used the source code that you have posted.
I'm sorry if I upset you, if you need to add an additional reference or something else please let me know.
Regards
I also take this opportunity to congratulate you for the API development (really it's great!).
ResponderEliminarI specified the license before Webiopi features. Do not know if you need anything else ...
gracias @akil3s!
ResponderEliminarTe dejo aquí la lista de la compra (de Deal Extreme) por si alguien más le interesa:
http://dx.com/p/compact-1-3mp-pc-usb-webcam-with-built-in-microphone-black-51874
http://dx.com/p/mini-prototype-printed-circuit-board-breadboard-white-140147
http://dx.com/p/l298n-stepper-motor-driver-controller-board-module-blue-149662
http://dx.com/p/swpkpower-sw-a22617-rechargeable-2600mah-emergency-mobile-power-charger-black-174049
http://dx.com/p/9v-battery-holder-case-box-with-leads-142701
http://dx.com/p/ultra-mini-nano-usb-2-0-802-11n-b-g-150mbps-wi-fi-wlan-wireless-network-adapter-black-71905
http://dx.com/p/breadboard-jumper-cables-wires-for-electronic-diy-100-male-to-male-40-female-to-female-203948
http://dx.com/p/hc-sr04-ultrasonic-sensor-distance-measuring-module-133696
http://dx.com/p/arduino-650nm-laser-sensor-module-black-137473
http://dx.com/p/arduino-magic-cup-light-modules-pair-136115
http://dx.com/p/200ohm-4-3k-1-4w-resistor-set-25-x-10-pcs-163332
http://dx.com/p/2kohm-potentiometer-adjustable-resistors-set-blue-10-pcs-187062
Michísimas gracias Vicente, como siempre de 10!!
ResponderEliminarGracias!
ResponderEliminarme vale justo para un proyecto de la Universidad :D
Did not seen that reference to the cambot article, sorry. Bold font may help. With the licence, that's fine.
ResponderEliminarPlease see http://trouch.com/2013/12/01/webiopi-needs-your-help/
Thanks for your support.
Ok, thank you. I've highlighted in bold font. I'll continue to investigate and try to help in your project.
ResponderEliminarMuy buen post. El código a utilizar sería el mismo si uso la camara por hardware??? Tendré algun problema?
ResponderEliminarsi es por hardware tendrás que configurar el streamer para el mismo.... pero ganarás en rendimiento.. feedback por favor!
EliminarHola.
ResponderEliminarCuando dices "puentear con jumpers los pines ENA y ENB a 5V", ¿A que te refieres? ¿A la salida 5V que tiene el módulo L298N, o al pin de 5V que tiene la raspberry?
Gracias
hola Daniel, disculpa por no haber sido demasiado específico en la entrada.. me refiero a los pines del controlador L298N..
EliminarSaludos!
Hola!
ResponderEliminarEstoy planteándome hacer un cochecillo de estos con mi RPI... se entiende bien la entrada, aunque no se mucho de electrónica, jeje.
Cuando dices que la RPI se tiene que conectar a tierra, ¿a qué te refieres exactamente? Entiendo lo que es una toma de tierra, pero no se si realmente tendría que enchufar un cable al pin de la RPI y que tocara el suelo...
Perdón si lo que pregunto es una chorrada, pero voy un poco pez en estos temas jeje.
Saludos!
hola David, preguntar nunca es una chorrada, haces bien..
Eliminarcuando digo conectar a tierra en esa caso es al pin GND (masa o tierra) del módulo L298N. Echa también un vistazo a https://es.answers.yahoo.com/question/index?qid=20091212110932AANFePG
Gran persona Vicente Motos... Compartes conocimiento y Realmente resuelves dudas por muy sencillas que parezcan las preguntas (siempre con profesionalismo)... te deseo Exito!!!
Eliminarjoé! muchas gracias!! me gustaría tener más tiempo para investigar, responder y detallar aún más algunas preguntas, pero hago lo que puedo...:)
EliminarHace falta comprar todo lo que has puesto en la lista que tienes al principio de los comentarios??
ResponderEliminarMe podrias decir lo justo y necesario? te lo agradecería. Gracias y muy bueno el trabajo
la gracia es reutilizar todo lo posible y a partir de ahí dejar volar tu imaginación..
Eliminarnecesitarás un controlador para los motores eso sí, pero a partir de ahí tú eliges si quieres cámara, controlarlo o no por WiFi, el tipo de baterías, etc.
Fenomenal el trabajo. Enhorabuena por el detalle y lo bien explicado que está. Muchas gracias
ResponderEliminaruna pregunta hise pruebas en python usando RPi coloco como output los pines que muestras y luego coloco GPIO.output(17,GPIO.HIGH), GPIO.output(27,GPIO.LOW) y en el L298 se prende la luz pero las ruedas no se mueven que puede ser?¿?
ResponderEliminartiene pinta de ser un problema por potencia insuficiente, revisa las características de tu motor y las baterías...
EliminarHola Vicente excelente tu trabajo. Quisiera preguntarte si es posible usar una sola fuente de potencia (8 pilas AA) y no dos, para alimentar tanto a la raspberry como a los dos motores.
ResponderEliminarDe ser posible, queria ver si me podias comentar que me conviene mas:
- Pasar el pack de pilas a traves de un solo UBEC 5v (regulador conmutado), y de ahi sacar tres lineas, una para raspberry, y una por motor.
- Pasar el pack de pilas de traves de dos UBEC 5v, uno para la raspberry, otro para los motores.
Saludos y gracias!
Felipe
Entiendo que sí Felipe, pero habría que probarlo... en cuanto a la mejor opción evidentemente es mejor tener dos reguladores (dado que el precio de regulador es bajo)
EliminarSaludos!
Muchas gracias por compartirlo. Me he impreso un juguetito basándome en éste tutorial:
ResponderEliminarhttp://www.thingiverse.com/thing:662121
Por cierto, si te fijas en el código que he publicado, le he añadido control de velocidad PWM. No se puede modificar desde la web, pero sirve para que al ir hacia atrás vaya más despacio y al girar vaya aún más despacio
EliminarEnhorabuena por tu projecto ...
ResponderEliminarTe podría sugerir que añadieras la capacidad de leer códigos QR ,
Estas etiquetas estarían pegadas al suelo digamos a 1m unas de otras y perfectamente localizados en un mapa de coordenadas.(previamente cargado en la memoria.)
Así el robot podría ajustar sus trajectoria y saber la posición exacta.
Esto es como más o menos los robots de AMAZON se orientan en sus almacenes.
interesante. Gracias por la propuesta!
EliminarSaludos Vicente es un excelente tutorial.
ResponderEliminarTe cuento que he hecho todo lo que has puesto pero al final no se como poner en red el robot con mi computadora. Me puedes explicar esa parte por favor?
De antemano te agradezco.
hola, muchsa gracias.
EliminarEl rover lleva un adaptador WiFi (http://dx.com/p/ultra-mini-nano-usb-2-0-802-11n-b-g-150mbps-wi-fi-wlan-wireless-network-adapter-black-71905) y está conectado a la misma red que mi PC.
Saludos,
Hola Vicente
ResponderEliminarDisculpa que te vuelva a preguntar sobre la red, pero la verdad es que soy nuevo en esto y no me funciona todavía.
Utilizaste un Access point configurado por ti mismo o usaste el router con el que normalmente te conectas al internet?
Y una vez que apago la raspi y quiero volver a controlar el rover, le enciendo y solo debo escribir el código para iniciar el servidor webiopi en background o tengo que hacer algo mas?
Saludos
no tienes pq disculparte anónimo y menos por preguntar...
Eliminarla red wifi que utilizaba era la de mi router doméstico y tiene que preparar en el arranque todo lo necesario para cuando reinicies la rpi...
Saludos Vicente
ResponderEliminarEs justo lo que necesitaba y me fue de gran ayuda, te agradezco por haber hecho el tutorial.
Te comento que quisiera mejorarlo aumentando algunas características y para lo cual debo colocar más botones en la página web.
Tal vez sabes cuál es el código para colocar botones debajo de los que ya están?
Gracias
Gracias Giovanny!
Eliminarpara colocar más botones sólo edita el html y fíjate en el resto:
button = webiopi().createButton("bt_up", "/\\", go_forward, stop);
$("#up").append(button);
Y su función:
function go_forward() {
webiopi().callMacro("go_forward");
}
Que tal amigo, he tratado de ponder en funcionamiento el servicio de webiopi, sin embargo no se habilita la pagina de inicio index.html la cual posee la interfaz... aluna sugerencia? Saludos
ResponderEliminarestá el servidor web levantado en el puerto 8000? has editado en la configuración el welcome-file?
EliminarLa pagina solo carga el script ( el codigo de control de cambot) cuanto no esta habilitado, tan luego yo habilito el script y manda directo a la pagina de inicio de Webiopi. Es algo curioso xD
EliminarHice todo pero no se porque no me aparece index.html
ResponderEliminarsoy nuevo pero solo me aparece
GPIO Header
Control and Debug the Raspberry Pi GPIO with a display which looks like the physical header.
GPIO List
Control and Debug the Raspberry Pi GPIO ordered in a single column.
Serial Monitor
Use the browser to play with Serial interfaces configured in WebIOPi.
Devices Monitor
cuando ingreso a la direcccion ip:8000
cd mjpg-streamer/mjpg-streamer: No existe el fichero o el directorio
ResponderEliminarHe hecho todo tal cual como lo tienes y eso me aparece
Axl Alejandro Ramìrez esta es la direccion /usr/src/mjpg-streamer-code/mjpg-streamer, como ves te falta la palabra "-code", aprovechando tengo una duda, cuando creo el script en donde lo debo guardar, le he dado todos los permisos pero me sale un error con la entrada de video, espero me puedan ayudar.. gracias!!!!
ResponderEliminarSaludos amigos
ResponderEliminarLes quiero compartir ciertas mejoras que le hice al proyecto gracias a todo lo que está en este tutorial, de manera que puedan observar y si es posible ayudarles con lo que tengo hecho en este video:
https://www.youtube.com/watch?v=pMuPMCwcR4o&feature=autoshare