Archivo de la categoría: Proyectos

Proyectos que he desarrollado y quiero compartir con la comunidad

Crear tu propio servidor para gestionar los relojes infantiles Q50

Tengo un reloj Q50, al que se inserta una tarjeta SIM, que sirve para que los niños puedan comunicarse por teléfono con los padres y los padres puedan llamar al niño además de geolocalizarle. IoT en estado puro.

El caso es que las aplicaciones existentes para geolocalizar son de pago o no funcionan, por ello me propuse crear mi propia aplicación para estos relojes, pero en vez de ser una APP de móvil, sería una aplicación donde se recogería el estado actual.

Estos relojes se configuran inicialmente a través de mensajes SMS. Para configurar el servidor a donde se conectará el reloj, se debe enviar un mensaje SMS al número de teléfono de la SIM del reloj con el siguiente contenido:

pw,<clave>,ip,<host>,<puerto>#

Donde:

  • clave: es la clave que tiene el móvil, por defecto es 123456
  • host: es la dirección IP o host del servidor
  • puerto: es el puerto TCP donde escucha el servidor

Cuando el reloj se conecte al servidor, los comandos que se utilizan se basan en un protocolo que no he encontrado el nombre, pero que es común a muchos relojes y dispositivos GPS. Se puede descargar de mi web, pero originalmente lo encontré aquí.

Como el objetivo es recuperar la posición GPS, sólo me centraré en los comandos Link remains, Location data reporting y Location order.

Link remains

El reloj envía cada 5 minutos un comando al servidor con el formato: [CS*YYYYYYYYYY*LEN*LK,A,B,C]

  • CS: El un código de dos caracteres que identifica al fabricante. En mi caso es 3G.
  • YYYYYYYYYY : Es el identificador del dispositivo.
  • LEN: Es el tamaño del mensaje/comando como 4 dígitos hexadecimales.
  • LK: Es el propio comando.
  • C: Indica el nivel porcentual de batería del reloj.

El servidor debe responder con otro comando con el formato :
[CS*YYYYYYYYYY*LEN*LK], que es lo mismo que ha enviado el reloj, pero sin los parámetros A, B y C.

Este comando sirve como heartbeat para que tanto el servidor sepa que el reloj está activo como que el reloj sepa que el servidor está activo. Si este último caso no se cumple, entonces el reloj intentará conectarse cada 5 minutos al servidor.

Location order

El reloj no está continuamente enviando la posición GPS porque acabaría con la batería muy rápido, por ello lo que se lanza es un comando desde el servidor al reloj para que informe de la posición GPS varias veces por minuto durante unos minutos. El formato del comando es: [CS*YYYYYYYYYY*LEN*CR]

El reloj informará con el mismo comando para indicar que lo ha recibido y que activará el GPS.

Location data reporting

Una vez activado el anterior comando, el reloj empieza a enviar cada pocos segundos la posición GPS con el siguiente formato: [CS*YYYYYYYYYY*LEN*UD,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] o [CS*YYYYYYYYYY*LEN*UD2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]

Los parámetros que importan para la geolocalización son:

  • C: Indica si hay una posición GPS válida (A) o inválida (V).
  • D: Latitud.
  • E: Indica si es norte (N) o sur (S).
  • F: Longitud.
  • G: Indica si es este (E) u oeste (W).

Los otros parámetros se pueden consultar en el apéndice del documento que he publicado más arriba sobre el protocolo.

He creado un programa en python 3 que crea un socket servidor y utiliza una BBDD sqlite para recibir los mensajes del protocolo del reloj, además de poder procesar los comandos:

  • ACTIVA: Activación de la geolocalización del reloj indicado por parámetro.
  • LISTA: Listado de relojes que hay registrados en la BBDD.
  • INFO: Información sobre el estado de un reloj pasado por parámetro.

Idealmente se necesita un servidor escuchando por internet, pero funcionaría utilizando ngrok si tienes un servidor local detrás de un router.

El programa, cuando se arranca, crea un socket de escucha y el reloj o un usuario/aplicación se podrá conectar a este. Cuando el reloj se enciende y se conecta a nuestro servicio, el programa muestra lo siguiente:

Donde se puede observar que el reloj envía un mensaje de link remains y otro de cuál es su configuración actual (pero este no está implementado).

Ahora si nos conectamos al servicio, podemos ver la lista de relojes que se han conectado a nuestro sistema simplemente enviando el comando LISTA:

En el reloj en concreto podemos activar la geolocalización, enviando el comando ACTIVA:

El programa mostrará lo siguiente:

Y nosotros ahora podremos consultar la información de ese reloj con el comando INFO:

Donde se muestra el identificador, la fecha de el último mensaje link remains, el porcentaje de la batería, la fecha de la última geolocalización y la latitud y longitud de esta.

Con todo esto se puede realizar un aplicación web que, o bien lea de la base de datos de sqlite si está en el mismo servidor, o bien que se conecte al servicio remotamente para enviar los comandos descritos. La aplicación web podría recuperar la lista de relojes, mostrarla y que el usuario elija el que desee, a continuación se mostraría la última actividad del reloj y en un mapa la última geolocalización (si existiese), dándole la opción de activarla para tener datos más recientes.

Como tarea pendiente queda implementar la seguridad en el acceso al servicio.

Ordenar comandos a un robot con tu propia voz y el altavoz de Google Home

Hace pocas semanas se lanzó al mercado español y al latinoamericano los altavoces de Google llamados Google Home. Mi motivación era probarlos diciendo por voz lo que quería que hiciese un robot.

Para este artículo voy a utilizar el robot de televigilancia para que ejecute unos comandos sencillos: avanzar o retroceder un número determinado de segundos (al no tener encoders no puedo decirle que avance distancias) y que haga una fotografía para que me la envíe a telegram. En este vídeo se puede ver cuál es el resultado:

Se puede utilizar tanto el altavoz de Google como el asistente de Google del móvil (si no tienes descárgatelo en Android o en IOS). A continuación explico los pasos que he seguido:

APACHE y PHP

Hay que instalar el servidor web apache y php para que la raspberry pueda recibir los comandos desde IFTTT.

Para crear las imágenes dentro del directorio de la web, hay que dar permisos al grupo www-data de escritura:

NGROK

Ngrok es una utilidad que puede crear un tunel http entre internet y el servidor web de la raspberry que está conectada a nuestro router, sin la necesidad de abrir ningún puerto al exterior.

Hay que darse de alta, pero para lo que se quiere hacer es un servicio gratuito. Después hay que bajarse el ejecutable Linux ARM, descomprimirlo y ejecutar el comando:

Donde token es el texto que se puede recuperar de esta página si ya se está logado en ngrok.

Ahora se procede a crear el tunel http con el comando:

En la ventana se verá qué host público se le ha asignado al tunel, este será el que se añada en las configuraciónes de los applet de IFTTT (y tendrás que hacerlo cada vez que arranques el ngrok de nuevo, puesto que cambia el subdominio).

IFTTT

Lo primero es crear una cuenta gratuita en IFTTT para crear los applets.

Después, se crea el primer applet, el que indica al robot que tiene que avanzar durante varios segundos. En la sección My Applets, seleccionar New Applet y pulsar el botón this.

A continuación elegir el servicio de Google Assistant.

Como aún no estará conectado, pulsar el botón Connect.

Esto abrirá una ventana nueva con las cuentas de google, si hay más de una cuenta, hay que seleccionar la que esté asociada a nuestro asistente de Google. A continuación Google preguntará si se otorga permisos para gestionar la voz del asistene de Google a IFTTT, hay que pulsar el botón Permitir.

Ahora ya se puede empezar a configurar el applet. Para el movimiento de avanzar unos segundos se selecciona el lanzador Say a phrase wih a number.

Ahora se configura la frase o frases que queremos que el asistente de Google reconozca, poniendo una almohadilla que será donde se guarde la variable numérica de los segundos. Procura poner frases que no estén predefinidas en Google assistant, de lo contrario no serán reconocidas. Después se escribe la respuesta que dará el asistente, se selecciona el idioma español y finalmente se pulsa el botón Create trigger.

Pulsar el botón that.

Escoger el servicio de acción Webhooks.

Seleccionar el botón Make a web request.

Rellenar el campo URL con el host dado por Ngrok y el fichero php que será llamado (en mi caso es comando.php) junto con los parámetros que queramos añadir. Pulsar el botón Add ingredient para introducir en la URL el campo numérico que el Google assistant habrá recuperado con los segundos solicitados. Pulsar el botón Create action.

Finalmente pulsar el botón Finish.

Con esto ya se habrá creado el applet para el avance del robot. Hay que hacer otro applet similar cambiando los textos de llamada (como por ejemplo Retrocede el robot # segundos y pasándole en el atributo tipo de la url del web request un 2).

Como último paso de IFTTT se van a crear dos applet más, uno para que se pueda pedir una foto y otro para que se envíe a Telegram. El primero de ellos es muy similar a los anteriores, sólo que el lanzador será Say a simple phrase, el texto será algo así como Toma una instantánea (no he podido hacerlo funcionar con la pabara foto) y la url del web request apuntará al script foto.php, que será el encargado de hacer la foto y luego llamar al siguiente applet desde la propia raspberry.

Para el otro applet hay que seguir los pasos descritos a continuación.

En la sección My Applets, seleccionar New Applet y pulsar el botón this.

A continuación elegir el servicio de Webhooks.

Seleccionar el lanzador Receive a web request.

Escribir el nombre del evento (en mi caso subir_foto) y pulsar el botón Create trigger.

Pulsar el botón that.

Escoger el servicio de acción Telegram.

Como aún no estará conectado, pulsar el botón Connect.

Esto abrirá una ventana nueva de telegram. En mi caso, previamente asocié la web de telegram para poder abrir los chats en el navegador web, por eso ahora puedo autorizarlo pulsando el botón OPEN IN WEB.

Después hay que pulsar el botón INICIAR y a continuación el botón Authorize IFTTT.

A continuación, seleccionar la acción Send photo.

Rellenar el campo Photo URL con el host dado por Ngrok, pulsar el botón Add ingredient y elegir el campo Value1. Pulsar el botón Create action.

Finalmente pulsar el botón Finish.

Así es como deberían quedar los applets en tu cuenta:

SCRIPTS DE PHP Y PYTHON

La implementación depende lo que quiera hacer cada uno con su robot. En mi caso utilizo un script php llamado comando.php, que a su vez lanza un script en python que es el que se comunica por el puerto serie con la placa arduino para enviarle los comandos de los motores.

comando.php

comando.py

El otro script, llamado foto.php, es el que toma la foto y llama al webhook de IFTTT con el nombre de la imagen generada. La api key del servicio webhook se puede recuperar de está página de IFTTT si estás logado (el que aparece después del campo use).

foto.php

Hay que añadir el usuario www-data al grupo dialout y al grupo video y reiniciar la raspberry para que funcionen el acceso al puerto serie y la cámara desde el entorno de apache.

Servidor central de películas para una o más tablets con la raspberry pi zero mediante wifi

La siguiente situación es conocida por muchos: vamos a hacer un viaje largo en coche que dura horas, pero los niños no aguantan y al poco rato de haber comenzado ya empiezan a preguntar cuanto queda o si hemos llegado ya. Para hacerles más ameno el viaje se les ponen películas para que vayan entretenidos una buena parte del viaje.

El objetivo de este artículo es reutilizar las tablets android e ipad (también funciona con los móviles) que tenemos por casa para que reproduzcan los vídeos que hay almacenados en una raspberry pi zero mediante wifi. Así los niños estarán entretenidos en el coche, en un restaurante, en la sala de espera espera del médico, etc., además cada uno podrá ver una película distinta y no tendremos que realizar ninguna inversión grande para lograrlo más allá de una tarjeta SD y una raspberry pi zero w.

Lo primero es descargarse la última versión del sistema operativo Raspbian Lite desde la web oficial.

Después hay que grabarla en una tarjeta SD (recomiendo una con class 10). Aquí se explica cómo hacerlo desde varios sistemas operativos.

Esta creará dos particiones. En la que es FAT32 y está etiquetada como boot hay que:

  • Crear un fichero vacío llamado ssh o ssh.txt para habilitar la conexión ssh a la raspberry pi.
  • Crear otro fichero llamado wpa_supplicant.conf e introducir en este lo siguiente (cambiando los valores ssid y psk por los de la red wifi correspondiente):

Ahora hay que introducir la tarjeta SD en la raspberry pi y alimentarla mediante un cargador usb de al menos 500mA.

Si todo va bien se podrá conectar a la raspberry mediante ssh a la IP que le ha dado el router.

Para asegurarse que instalaremos las últimas versiones del software hay que hacer una actualización de los repositorios:

Instalar hostapd (para que la raspberry haga de punto de acceso), dnsmasq (para que pueda dar direcciones IP), samba (para compartir ficheros) y lighttpd (para poder apagar la raspberry desde el navegador):

Para que los dispositivos se conecten a una red wifi creada por las raspberry hay que configurar el hostpad, para ello crear con el usuario root el fichero /etc/hostapd/hostapd.conf con el siguiente contenido (cambiando los valores ssid y wpa_passphrase por los de la red wifi que vamos a crear y el valor channel por el *canal de la red wifi del router):

*Cuando estamos en casa, para que funcionen correctamente en la raspberry tanto la red wifi creada como la red wifi que hemos configurado al principio para conectarse, hay que configurar el mismo canal wifi porque la raspberry no permite trabajar con varios canales a la vez.

Editar con el usuario root el fichero /etc/default/hostapd y añadir el siguiente contenido:

Después, cada vez que arranque la raspberry hay que ejecutar un script para activar correctamente la red wifi creada, para ello crear con el usuario root el fichero /usr/local/bin/hostapdstart con el siguiente contenido:

y editar con el usuario root el fichero /etc/rc.local y poner antes de la linea que tiene exit 0 el siguiente contenido:

A continuación hay que configurar el dnsmasq para que de IPs a los dispositivos que se conecten a la raspberry en la subred 192.168.50.0/24, para ello editar con el usuario root el fichero /etc/dnsmasq.conf y añadir al final del fichero el siguiente contenido:

Después hay que configurar la raspberry para que se conecte a nuestro router (otra vez como al principio), para ello editar con el usuario root el fichero /etc/network/interfaces y añadir al final el siguiente contenido:

Para compartir los ficheros se tiene que configurar samba. Primero ejecutar:

Después añadir con el usuario root al final del fichero /etc/samba/smb.conf el siguiente contenido:

En la carpeta /home/pi/share es donde se deben almacenar los vídeos que luego se quieran reproducir. Puedes enchufar un disco usb a la rasberry para copiar los vídeos; descargarlos de una NAS, de una página web, etc.; instalar un cliente de torrent o lo que se te ocurra.

Para apagar la raspberry fácilmente desde el navegador, hay que dar permisos de sudo a lighttpd, por tanto ejecutar:

Y añadir al final el siguiente contenido:

Después activar el módulo cgi para lighttpd:

Sustituir con el usuaro root el fichero /etc/lighttpd/conf-enabled/10-cgi.conf con el siguiente contenido:

Crear con el usuario root el fichero /var/www/html/index.html con el siguiente contenido:

Crear con el usuario root el fichero /var/www/html/apaga.sh con el siguiente contenido:

Como último paso en la raspberry, ejecutar:

Para que no haga falta esperar conexión a la red, seleccionar 3-Boot Options/B2 Wait for Network at Boot/NO y para tener la máxima memoria posible 7 Advanced Options/A3 Memory Split, poner 16 y pulsar OK. Seleccionar Finish y decir si a reiniciar la raspberry.

Finalmente instalar la aplicación VLC de videolan en los dispositivos, después configurarlos para que se conecten a la red wifi de la raspberry, arrancar el VLC, seleccionar la opción Red local, elegir RASPBERRYPI, escoger la carpeta Peliculas y pulsar sobre la película que se quiera reproducir.

En el coche, la rasberry se puede alimentar con un cargador de mechero a USB, en otro lugares se puede alimentar mediante una powerbank.

Para apagar la raspberry, sólo hay que abrir un navegador en uno de los dispositivos y acceder a la dirección http://192.168.50.1

Por último agradecer a este mensaje en los foros de la raspberry donde se explica cómo hacer funcionar como punto de acceso a la vez que cliente.

Espero que os sea tan útil como a mi para amenizar la espera a los niños o incluso utilizarlo tu sólo cuando vas en transporte público o estás en un hotel.

Dispensador de caramelos de colores

Tenía pendiente publicar el proyecto que presenté a la Maker Faire Madrid 2016 en la mesa de Spainlabs.

Consiste en que el usuario elija mediante un botón qué color de caramelo quiere recibir, entonces el sistema empezará a remover los M&M’s de un embudo para que caiga uno solo en una plataforma, después el sistema reconocerá el color del caramelo y si es el elegido caerá en un recipiente y sino en otro recipiente repitiendo la operación:

Así es como se ve el conjunto:

Este es el esquema del sistema:

El sistema está formado por un Arduino UNO, un motor paso a paso NEMA 17 con un driver pololu A4988 y un condensador electrolítico de 100µf, un servo sg90, una cmucam 3, un led blanco con una resistencia de 220Ω, un display HD44780 con un potenciómetro de 10KΩ y 6 botones con 6 resistencias de 1KΩ y 1 resistencia de 10KΩ. En el esquema los cable sueltos tienen el siguiente significado: los de color negro van a masa, los de color rojo a 5V y los de color naranja a 12V.

La cmucam 3 tiene instalado el fimrware que emula la cmucam 2. Está dentro de una «caja» de forex y contiene un led para que las condiciones de iluminación siempre sean las mismas.


Los botones están configurados de tal forma que al pulsar cada uno de ellos el voltaje cambia y puede ser medido por un sólo pin analógico de arduino.

Para el proyecto he tenido que diseñar e imprimir varias piezas en 3d:

Soporte de la cmucam 3 de 135°

Fijación del servo al embudo

Brazo removedor para el servo

Plato giratorio para recolectar un caramelo con ranuras para sujetarlo al eje del motor paso a paso con tornillo y tuerca

Plataforma para mantener el caramelo en el recorrido giratorio hasta que caiga en un recipiente

La mayoría de la estructura de soporte está basada en MakerBeam.

El embudo es uno normal, pero serrado para que un caramelo en horizontal pueda entrar sin problemas.

El código fuente del programa para arduino es el siguiente:

A grosso modo, cuando el sistema se enciende se requiere configurar la cmucam y calibrar tanto de los valores RGB máximos y mínimos del color de cada tipo de caramelo (incluido cuando el plato está vacío) como el votaje del botón para seleccionarlo:

Después el sistema ya está preparado a la espera de que el usuario elija el color del caramelo. Si en 10 intentos no se ha encontrado el caramelo deseado, se aborta el proceso:

Hay 4 posiciones que el motor paso a paso debe alcanzar. La primera, la de recolección, sitúa el hueco del plato justo debajo del embudo para recoger un caramelo. La segunda, la de reconocimiento, sitúa el hueco del plato en el objetivo de la cmucam para poder reconocer el color del caramelo que lleva dentro. La tercera, la de intento fallido, sitúa el hueco del plato en el contenedor para que caiga el caramelo que no es el buscado. Finalmente la cuarta, la del dispensación, sitúa el hueco del plato en el contenedor para que caiga el caramelo solicitado. Los pasos que debe realizar el motor paso a paso para alcanzar todas esas posiciones están medidos a pelo; se consigue haciendo varias pruebas aisladas para saber donde situar el plato.

Por desgracia el sistema no es perfecto y tiene dos fallos:
La forma de los caramelos M&M’s es de tipo lenteja. Esto hace que si caen en horizontal sólo caiga uno en el hueco del plato, pero si caen en vertical es posible que caigan dos a la vez. Esto se solucionaría utilizando caramelos esféricos completamente.
El sistema de medición a veces confunde colores parecidos como el naranja y el amarillo. Esto se solucionaría utilizando sólo los colores más definidos como rojo, azul, verde y amarillo. (en el vídeo se aprecia en el segundo 53 y en el 1:10)

Como mejoras se puede hacer que los caramelos que caigan en el recipiente de los no buscados se vuelvan a meter en el embudo.

Alimentar un proyecto con energía solar

Como parte de un proyecto de mayor alcance me propuse la medida de la temperatura y la humedad durante las 24 horas del día y enviar esos datos a una página web. Quería utilizar una fuente de energía limpia y renovable, siendo la más sencilla y extendida la energía solar.

El proyecto está finalizado y ya estoy enviando esos datos a intervalos de 15 minutos como se puede ver en las siguientes gráficas actualizadas:



Voy a dividir el artículo en dos secciones: la primera es la del hardware utilizado, tanto en el sistema de medición como en el sistema de alimentación; la segunda es el software utilizado.

Hardware

El sistema de medición está formado por:

  • Un ordenador C.H.I.P.: Este ordenador ARM de 9$ con una distribución linux basada en debian es ideal para el proyecto dado su bajo coste y sus características: puerto USB, pines GPIO y la posibilidad de conectarle una batería LiPo. Gestiona la alimentación (usb, chg-in o batería) a través de un chip AXP-209 incorporado a este.
  • Un dongle 3g: Se puede encontrar muy barato (20€ o  menos) y contiene una tarjeta SIM de freedompop para obtener acceso a internet gratuito.
  • Un sensor DHT22: Este sensor tiene diversidad de precios dependiendo de qué componentes traiga. Lee la temperatura y la humedad con un error máximo de 0,5Cº y 5% respectivamente.

El sistema de la alimentación está compuesto por:

  • Un UBEC: Es un regulador muy eficiente y cuesta unos 4$. Sirve para alimentar todo el sistema de medición proporcionando 5V constantes y permite hasta 3A.
  • Una batería de Litio-Ion: Esta es la batería principal de 11,1V y 5200mAh.  Su precio puede parecer elevado pero más adelante comento por qué, aunque hay alternativas más baratas.
  • Un panel solar rígido: De 12V y 25W de potencia por unos 38€.
  • Un controlador de carga solar: Este dispositivo, que cuesta unos 5$, alimenta el UBEC utilizando la batería principal (cuando no hay sol) o mediante el panel solar (cuando hay sol) al mismo tiempo que carga dicha batería. Esta versión funciona con baterías de Litio-Ion de 11,1V y permite una corriente de hasta 3A.
  • Una batería Lipo: Esta batería de 3,7V y 2000mAh por unos 13€ se conecta al ordenador C.H.I.P. para darle alimentación en caso de que la batería principal y el panel solar no pudieran hacerlo. Esto hace que el proyecto pueda funcionar más tiempo y que sabiendo su nivel de carga se pueda hacer una apagado ordenado.

El conjunto se guardará en una caja estanca de unos 9€ para evitar la entrada de polvo y líquidos de fuera, excepto el sensor DHT22 que irá en otra caja aparte.

En la caja principal se han hecho dos agujeros en los conos métricos, uno para sacar los dos cables que van al panel solar y otro para los tres cables que va al sensor DHT22. Hay que tener en cuenta que los cables se sacan desde el interior de la caja hacia afuera y no al revés para poder aislar mejor el conjunto de las condiciones climatológicas externas. Casi todos los elementos están sujetos por cinta de velcro para asegurarlos dentro de la cajas y también poderlos extraer con facilidad.

La otra caja tiene un agujero grande en el centro para que el sensor pueda medir la temperatura y humedad exterior y otros dos en el extremo donde salen los cables para poder drenar el posible agua que se introdujera, ya que esta caja estará puesta en vertical.

El procedimiento para conectar todo es el siguiente:

  • El dongle 3g al puerto USB del ordenador C.H.I.P.
  • La batería LiPo al conector correspondiente del ordenador C.H.I.P.
  • El cable amarillo del sensor DHT22 al pin 18 de la columna UT13 etiquetado como PWM0.
  • El cable rojo del sensor DHT22 al pin 5 de la columna UT13 etiquetado como VCC-3V3.
  • El cable negro del sensor DHT22 al pin 1 de la columna UT13 etiquetado como GND.
  • La batería principal y el regulador UBEC a los dos bornes centrales del controlador de carga respetando la polaridad (se encenderá la luz verde de «power» si tiene carga)
  • El panel solar a los dos bornes de la izquierda del controlador de carga respetando la polaridad (se encenderá la luz roja de «charge» si al panel le incide luz directamente)
  • El cable rojo de la salida del regulador UBEC al pin 2 de la columna UT13 etiquetado como CHG-IN.
  • El cable negro de la salida del regulador UBEC al pin 4 de la columna UT13 etiquetado como GND.

El panel solar debe estar orientado al sur si está situado en el hemisferio norte y viceversa. El ángulo de inclinación debe ser el mismo que la latitud geográfica en la que se encuentre, por ejemplo en Madrid son 40º de inclinación.

Para calcular el panel solar y la batería que he necesitado me he basado en los siguientes hechos:

El ordenador C.H.I.P. puede consumir unos 200mA, el dongle usb 3g consume unos 130mA (sólo se conecta cada 15 minutos), el sensor DHT22 consume unos 1,5 mA y el controlador de carga unos 6 mA . Con esto se tiene que cada hora consumirá alrededor de 340mA. En Madrid el peor de los casos es cuando sólo hay 10 horas de sol y 14 de oscuridad, que se produce a finales de noviembre y principios de diciembre; entonces 14h * 340mAh = 4760mAh, es decir, que se necesita una batería que al menos tenga una capacidad de 4760mAh para asegurarse que nuestro sistema de medición pueda funcionar cuando haya oscuridad. En mi caso tengo los 5200mAH de la batería principal más los 2000mAH de la batería conectada al C.H.I.P. por lo que hay más que suficiente. Aunque la batería conectada al C.H.I.P. consume 1000mA (además de los 340mA que comentaba) hasta que esté totalmente cargada, no lo he puesto para facilitar los cálculos y porque una vez cargada (una batería con capacidad de 2000 mAh se carga en 2 horas) ya no consume esos 1000mA el resto del tiempo.

En el caso del panel solar de 12V/25W se tiene hasta 2,08A cuando la luz del sol incide directamente en él sin nubes de por medio, por lo que 340mA se los proporciona al sistema de medición y el resto a la carga de la batería principal.

Finalmente ambas baterías las he comprado con garantías, es decir, en tiendas que son de fiar aunque el precio sea más caro, porque hay por ahí rondando muchas baterías que dicen tener una carga y luego ser otra de valor inferior con los problemas que ello puede ocasionar. También ambas tiene un circuito de protección contra sobrecarga, sobredescarga, sobrevoltaje, cortocircuito y además, en el caso de la batería principal, que permita el balanceo de carga de todas las celdas. Para la batería principal hay alternativas más baratas: puedes comprar 3 pares de pilas de litio del tipo 18650, dos portapilas de formato 18650 y dos circuitos de protección y balanceo.

En este mes y medio que lo he estado probando he llegado a las siguientes conclusiones:

  • En controlador de carga comprueba qué tiene más voltaje, si la batería principal o el panel solar. Si es la primera, no deja pasar la corriente desde el panel solar a la batería principal y entonces el sistema de medición sólo es alimentado por la batería principal; si es la segunda, entonces la batería se carga y el sistema de medición es alimentando a la vez por la energía que proporciona el panel solar.
  • Las baterías LiPo se cargan normalmente a 1C, por lo que el amperaje del panel solar nunca debe ser mayor que el de la batería, en mi caso 2,08A frente a 5,2A por lo que no hay problema.
  • Como el panel solar es de 25W, se puede dar el caso de que los días en los que el cielo está muy nuboso no pueda alimentar al conjunto con toda su potencia, rindiendo a veces tan solo un 10% de su potencia. Las baterías antes o después se descargarán y el conjunto estará sin funcionar durante horas o incluso días. Para evitar esto sólo sirve poner otro panel solar más potente, como de 100W para evitar el peor de los casos (10 horas de luz al día)
  • Si el ordenador C.H.I.P. está apagado y el chip axp209 detecta que por la entrada CHG-IN hay 5V y corriente suficiente para alimentarlo, entonces el axp209 enciende el ordenador C.H.I.P. Esto se produce cuando la batería principal está agotada y el panel solar proporciona la suficiente energía.

Software

Aunque el objetivo principal del artículo es mostrar cómo alimentar un circuito con un panel solar, voy a describir el software utilizado para el sistema de medición.

SISTEMA OPERATIVO

En el ordenador C.H.I.P. he instalado la versión 4.4 headless, porque ya contiene el módulo de kernel ppp y no hay que recompilar el kernel.

Para medir los valores del módulo DHT22 en el ordenador C.H.I.P. hay que instalar el módulo de kernel para el sensor DHT22 tal y como aparece en esta página.

Para poder realizar llamadas con el dongle 3g hay que instalar el paquete de wvdial:

Para poder leer el estado de la batería auxiliar en python hay que instalar el paquete pip para a continuación instalar la librería de axp209:

Para que el modo CD-ROM y lector de tarjetas del dongle 3g no moleste hay que acceder al puerto USB serie que se crea cuando se enchufa y ejecutar el comando AT:

En /etc/rc.local escribir lo siguiente:

Para la inicialización del DHT22 crear el fichero /home/chip/dht11.sh con el siguiente contenido:

En el fichero /etc/wvdial.conf

El programa de medida y envío de información se debe ejecutar cada 15 minutos. Crear el fichero /etc/cron.d/lectura_sensor con el siguiente contenido:

Finalmente crear el fichero /home/chip/lectura.py con el siguiente contenido:

Básicamente lo que hace el script en python es:

  • Comprobar si existe un dongle 3g, y si es así lanzar el programa wvdial para poder enviar los datos por internet.
  • Leer los valores de temperatura y humedad del DHT22 y el porcentaje de carga de la batería auxiliar (si este porcentaje fuese menor que 15 entonces se apaga el ordenador C.H.I.P. de una forma ordenada). Si hubiese algún problema se repite este proceso hasta 3 veces.
  • LLamar a la API de thingspeak para enviar los valores. Si hubiese algún problema se repite este proceso hasta 3 veces.
  • Cerrar el programa wvdial para desconectarse de internet.

Global Robot Expo

Desde hoy y hasta el Domingo se celebra la primera Global Robot Expo en Madrid. He tenido la suerte de visitarla el primer día de apertura y esto es con lo que me he encontrado:

Varios de los robots más conocidos nos dan la bienvenida a la exposición.

IMG_2316-1

IMG_2316-24

En la exposición había casi más stands de drones que de robots clásicos.

IMG_2316-0

IMG_2316-8

IMG_2316-10

IMG_2316-14

IMG_2316-17

IMG_2316-18

IMG_2316-25

IMG_2316-36

Robots emocionales.

IMG_2316-2

Brazos robóticos.

IMG_2316-3

IMG_2316-6

IMG_2316-7

IMG_2316-20

IMG_2316-21

Robótica educativa.

IMG_2316-4

IMG_2316-22

IMG_2316-26

IMG_2316-29

IMG_2316-30

IMG_2316-31

IMG_2316-34

IMG_2316-35

Robots manipuladores móviles.

IMG_2316-5

IMG_2316-11

IMG_2316-9

Recinto con red para demostraciones con drones.

IMG_2316-12

IMG_2316-37

Escenario para las competiciones de robots de la lnrc.

IMG_2316-13

Reconocimiento óptico.

IMG_2316-15

Manejando un robot desde un maletín.

IMG_2316-16

Cortadora de cesped robotizada.

IMG_2316-19

Robots bailarines

IMG_2316-23

Embajada de Japón

IMG_2316-27

Nanorobots

IMG_2316-32

IMG_2316-33

Y un artículo sin vídeo es como un día sin pan, así que aquí lo tenéis una pequeña muestra del evento:

Programar el chip wifi ESP8266 como si fuera un microcontrolador (2/2)

En el anterior artículo explicaba cómo generar el toolchain para poder compilar programas y subirlos a nuestro módulo ESP8266. En este artículo explicaré cómo hacer un programa en C. Para ello me voy a poner un reto: un firmware que cuando pulse un botón o la tecla p, haga una llamada a una página web que muestre la acción realizada. Con este ejemplo vamos a trabajar con el gpio, puerto serie, wifi, temporizadores y eventos. No hay mucha documentación sobre cómo programar el chip esp8266 más allá de los ejemplos de código, foros y páginas web con artículos dedicados al chip y de la SDK de Espressif que en el momento de escribir este artículo es la 1.0.1.

Empezaré por mostrar un vídeo de lo que he hecho para tener claro desde el principio lo que explicaré aquí.

Lo que veis en el vídeo es que primero programo el esp8266 con el firmware de este artículo. Luego abro una terminal al puerto serie del ESP8266. Pulso 3 veces el botón físico y otras 3 veces la tecla p en la terminal para que se envíe por el puerto serie. Estas acciones provocan en el esp8266 la llamada a una página web que lo registra, mientras en otra página web se visualiza casi en tiempo real lo que he hecho. Cuando compiléis vosotros el ejemplo podéis usar la misma página para hacer vuestras pruebas.

Este es el esquema del circuito para el botón (he obviado las conexiones al puerto serie para simplificarlo):

placa

Vamos a ver cómo lo hecho. Lo primero es crear una carpeta llamada proyectos-esp8266 en nuestra carpeta personal, entra dentro de esta y crear otra llamada reto. Dentro de esta copiaremos el fichero Makefile que modificamos en el anterior artículo. Después crearemos una carpeta llamada user y dentro de esta compiaremos los ficheros uart.h y uart_register.h del ejemplo de IoT que trae la SDK:

Dentro de la carpeta user crearemos dos ficheros.

user_config.h

user_main.c

Lo primero que salta a la vista es que no existe una función main eso es porque este chip se programa con una función de inicialización y el resto con eventos/interrupciones.

La función de inicialización es user_init (al final del código), como decía esta función es llamada cuando el módulo se enciende y se encarga de inicializar todo en el esp8266. El modificador de función ICACHE_FLASH_ATTR significa que la función se guarde en la flash en vez de en la RAM y que cuando se vaya a usar sea cacheada en esta última, ahorrando así espacio para poder tener más datos en la memoria. Dentro de esta función hay que destacar:

  • system_init_done_cb: Esta función tiene un parámetro que es la función callback que será llamada cuando termine la inicialización.
  • system_os_task: Esta función define la ejecución, como tarea, de la función callback pasada como primer parámetro. Podemos tener hasta 4 tareas (cada una con una prioridad distinta). Más adelante hablaré de ello.

La función inicializado es llamada cuando ha terminado la inicialización como comentába antes. Dentro de esta función hay que destacar:

  • os_printf: Es como el printf de toda la vida, pero su salida es enviada al puerto serie 0 (el esp8266 tiene un puerto serie con tx y rx y otro con tx sólo para hacer debug).

La función inicializa_uart configura el puerto serie. Dentro de esta función hay que destacar:

  • ETS_UART_INTR_ATTACH: Esta función configura a qué función callback se llamará cuando se reciba un caracter por el puerto serie. El segundo parámetro es una estructura que existe por defecto con información del puerto serie y el buffer de recepción, pero yo no lo usaré.
  • PIN_PULLUP_DIS: Desactiva la configuración de pull-up del pin indicado (La lista de pines está en el fichero eagle_soc.h de la sdk), en este caso del pin TX.
  • PIN_FUNC_SELECT: Configura el pin indicado para comportarse de una manera determinada, en este caso para funcionar como TX del puerto serie.
  • uart_div_modify: Configura la velocidad del puerto serie
  • WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| (EIGHT_BITS << UART_BIT_NUM_S)): Configura la comunicación como 8 bits, sin paridad y un bit de stop.
  • SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST) y CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST): Limpia la FIFO de TX y RX.
  • WRITE_PERI_REG(UART_CONF1(0), (UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S): Configura el disparador FIFO de RX.
  • WRITE_PERI_REG(UART_INT_CLR(0), 0xffff): Borrar el flag de todas las interrupciones del puerto serie.
  • SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RXFIFO_FULL_INT_ENA): Configura la interrupción de recepción del pin RX.
  • ETS_UART_INTR_ENABLE: Activa las interrupciones del puerto serie.

La función inicializa_gpio configura el pin GPIO 2 (el único disponible en el ESP-01, pero en otros módulos hay más pines gpio usables). Dentro de esta función hay que destacar:

  • ETS_GPIO_INTR_DISABLE: Desactiva la interrupción de los pines GPIO.
  • ETS_GPIO_INTR_ATTACH: Esta función configura a que función callback se llamará cuando haya una interrpción en el pin gpio indicado.
  • PIN_PULLUP_EN: Activa la configuración de pull-up del pin indicado.
  • gpio_output_set: Configura el pin gpio 2 como entrada.
  • GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(2)): Borrar el flag de la interrupcion del pin gpio 2.
  • gpio_pin_intr_state_set: Indica que en el pin gpio 2 sólo debe activarse la interrupción cuando detecta un flanco de bajada (conecta con masa/GND).
  • ETS_GPIO_INTR_ENABLE: Activa las interrupciones gpio.

La función inicializa_wifi configura la conexión a la wifi. Dentro de esta función hay que destacar:

  • wifi_set_opmode: Configura el módulo como estación cliente.
  • wifi_station_set_auto_connect: Indica que cuando se encienda el módulo se conecte automáticamente a la wifi establecida.
  • wifi_station_set_reconnect_policy: Indica que si se pierde la conexión con el punto de acceso, la vuelva a restablecer.
  • os_memcpy(&configuracion.ssid, ssid, 32) y os_memcpy(&configuracion.password, password, 64): Copia el nombre de la red wifi y la contraseña a la estructura del tipo station_config. Sirve para copiar datos de una posición de memoria a otra, sería equiparable al memcpy del C.
  • configuracion.bssid_set = 0: Para que conecte a cualquier wifi que tenga el nombre proporcionado anteriormente. Si hay varias wifis con el mismo nombre (SSID) puedes indicar a qué punto de acceso quieres acceder poniendo aquí su BSSID (su dirección MAC).
  • wifi_station_set_config: Inicializa la wifi con los valores proporcionados en la estructura del tipo station_config.
  • wifi_set_event_handler_cb: Esta función configura a que función callback se llamará cuando haya cambios en la wifi (conexión, desconexión, ip recibida…).

La función callback interrupcion_wifi es llamada por el chip cuando un evento en la wifi es generado. Quizá el más importante es cuando recibimos una IP de nuestro router. En el ejemplo pongo una variable a TRUE para indicar que tiene libertad para procesar las pulsaciones del teclado o del botón.

La función callback interrupcion_gpio es llamada por el chip cuando se ha detectado un evento en los pines GPIO. Dentro de esta función hay que destacar:

  • GPIO_REG_READ(GPIO_STATUS_ADDRESS): Devuelve el estado de los pones gpio y cual ha sido el que ha causado el evento.
  • os_timer_disarm: desactiva un temporizador si este estuviese activo.
  • os_timer_setfn: configura un temporizador indicando a qué función callback llamará cuando expire. Se le puede pasar un parámetro (en este caso NULL).
  • os_timer_arm: Activa el temporizador indicando cuanto tiempo dura en milisegundos y si debe o no repetirse. La idea de usarlo es para evitar los rebotes físicos cuando el botón es pulsado.
  • system_os_post: Indica al chip que, cuando pueda, ejecute la tarea de prioridad 0 que predefinimos en la función user_init con los parámetros 0,0.

La función callback boton_pulsado establece una variable a FALSE para indicar que el tiempo dado para mitigar los rebotes físicos del botón ya ha pasado y de nuevo permite reconocer la pulsación de éste.

La función callback caracter_recibido es llamada por el chip cuando se ha detectado un evento en el puerto serie. Dentro de esta función hay que destacar:

  • READ_PERI_REG(UART_INT_ST(UART0): Lee cual ha sido el motivo de la interrupción.
  • WRITE_PERI_REG(UART_INT_CLR(UART0): UART_RXFIFO_FULL_INT_CLR): Borra el bit de la interrupción correspondiente a carácter recibido.
  • READ_PERI_REG(UART_STATUS(UART0)): Lee el estado del puerto serie.
  • READ_PERI_REG(UART_FIFO(UART0)): Lee el caracter propiamente dicho. El chip ya tiene un buffer donde se pueden almacenar los carácteres recibidos, yo no lo he usado pero puede ser interesante.

La función callback conecta es llamada por el chip como una tarea. Inicia el proceso de envío de datos. Dentro de esta función hay que destacar:

  • os_zalloc: Sirve para reservar memoria, sería equiparable al malloc del C.
  • espconn_gethostbyname: Esta función hace una consulta dns para obtener la ip de un host dado y llamará a una función callback. Usa una estructura del tipo espconn donde se rellenarán todos los datos referentes a la conexión TCP

La función callback encontrado es llamada cuando se ha resuelto un nombre de host. Dentro de esta función hay que destacar:

  • espconn_port: Crea un puerto local para poder enganchar el socket con el puerto remoto 80 (http).
  • espconn_regist_connectcb: Esta función indica al chip que cuando se establece una conexión TCP, debe llamar a la función callback definida.
  • espconn_regist_disconcb: Esta función indica al chip que cuando hay una desconexión, debe llamar a la función callback definida.
  • espconn_regist_recvcb: Esta función indica al chip que cuando se reciben datos desde una conexión TCP, debe llamar a la función callback definida.

La función callback conectado es llamada por el chip cuando se establece una conexión TCP. Dentro de esta función hay que destacar:

  • os_sprintf: Sirve para rellenar un buffer con datos formateados, sería equiparable al sprintf del C.
  • espconn_sent: Envía los datos indicados a través del socket TCP.
  • os_strlen: Devuelve la longitud de una cadena, sería equiparable al strlen del C.

La función callback recibido es llamada por el chip cuando se reciben datos de una conexión TCP. En el ejemplo sólo los muestro directamente. Dentro de esta función hay que destacar:

  • os_free: Sirve para liberar memoria, sería equiparable al free del C.

La función callback desconectado es llamada por el chip cuando se desconecta la conexión TCP. En el ejemplo libero los buffers de memoria reservados previamente.

Quiero comentar es que no soy un experto en el esp8266, por lo que si que me preguntáis algo puede que no lo sepa responder, por ello os recomiendo ir a la página www.esp8266.com donde hay mucha gente que trabaja con el esp8266 y os podrán resolver vuestras dudas mejor que yo. Todo lo que he juntado aquí ha sido fruto de búsquedas por internet, mil y una pruebas con código fuente, etc. Sin embargo lo que aquí he explicado, aún siendo de las partes más importantes de la programación de un ESP8266, no cubre todo lo que se puede hacer con este chip, por lo que una vez te encuentres cómodo con lo aquí expuesto, te animo a que busques por tu cuenta más funcionalidades.

Programar el chip wifi ESP8266 como si fuera un microcontrolador (1/2)

IMG_20150504_230102

En esta tanda de dos artículos explicaré cómo olvidarse de los comandos AT del módulo ESP8266 ESP-01 (aunque lo escrito vale para toda la familia ESP) y poder programarlo como un chip independiente: conectando la wifi, manejando el puerto serie, usando los pines GPIO, etc. La gran ventaja es que tenemos un microprocesador más potente, más versátil, más rápido y además en muchos casos es más barato que si usáramos los microcontroladores PIC o AVR (como contrapartida tiene menos pines de E/S).

CONSTRUYENDO EL TOOLCHAIN

El primer paso que tenemos que hacer para programarlo es construir el toolchain para poder compilar los programas para este chip con el compilador cruzado. Para ello recomiendo tener un linux donde construirlo (ya sea físico o virtualizado), no recomiendo usar windows y cygwin. Yo estoy usando el ubuntu 14.04 LTS.

Lo primero es instalar las herramientas necesarias, para ello ejecutar:

Vamos a usar el toolchain de https://github.com/pfalcon/esp-open-sdk, con el que el proceso de creación es bastante sencillo (ejecútalo en la raíz de tu directorio personal):

Esto habrá creado una carpeta esp-open-sdk. Entra dentro de está y haz un make (con el parámetro STANDALONE=y) para crear todo el toolchain (puede tardar un rato dependiendo de tu ordenador):

Ahora vamos a poner en la variable de entorno PATH la ruta a los binarios, ya que el esptool no funciona si no se pone (cambia oscar por tu usuario):

COMPILANDO PROGRAMAS

Vamos a descargarnos unos ejemplos ya hechos:

Esto creará una carpeta llamada source-code-examples. Entra dentro de esta carpeta y edita el fichero example.Makefile.

Modifica las siguientes lineas (recuerda cambiar oscar por tu usuario):

POR

POR

POR

El campo ESPPORT debes cambiarlo si no coincide con la ruta al dispositivo asociado a tu dongle usb a serie.
Ahora entra dentro del direcotrio blinky, copia el fichero anteriormente editado como Makefile y haz un make para compilar el firmware:

Si todo ha ido bien habremos compilado el firmware para nuestro ESP8266:
shell1

PROGRAMANDO EL ESP8266

Para poder programar nuestro módulo ESP8266 necesitamos un dongle usb a serie (USB2TTL) como este:
IMG_20150501_165235
Después es necesario añadir al usuario que estemos utilizando (en el ejemplo, oscar) en el grupo dialout para poder acceder al dongle:

Ahora sólo queda subir el programa al módulo ESP8266, para ello debes cablear el módulo de la siguiente forma (estando éste sin alimentación):
conexiones
Las líneas rojas van a VCC (3,3V) y las negras a GND (masa). Ahora alimenta el módulo.

Si es la primera vez que vas a programar el módulo wifi, debes borrar las configuraciones por defecto, esto se consigue ejecutando el siguiente comando:

shell2
Las siguientes veces ya no será necesario repetir este paso. Si has hecho este paso vuelve a apagar y encender el módulo.

Finalmente para programar el firmware creado, ejecuta el comando:

shell3
Enhorabuena, acabas de programar por primera vez tu módulo ESP8266. Ahora desconecta el cable que va al pin de programacion (así el módulo no estará en modo de programación), conecta un led entre el GPIO 2 (el que no aparece conectado a ningún sitio en la fila de GND de la foto anterior de las conexiones) y masa. Así es como luce el «hola mundo» del chip ESP8266:

En el siguiente artículo explicaré cómo hacer tus propios programas en C para el esp8266.

Programando un Arduino remotamente con el módulo ESP8266

IMG_20141108_002938

Una de mis viejas aspiraciones cuando construyo robots es poder programarlos sin tener que recogerlos, enchufarles un cable usb o un programador ICSP y volverlos a dejar en su sitio.

En este artículo explicaré cómo con un Arduino UNO y un módulo ESP8266 (llamado WI07C) se puede programar un sketch de Arduino en la placa sin tener que estar cerca de esta, todo mediante wifi y sockets tcp/ip.

Descripción general

Como se puede ver en el vídeo tenemos un Arduino UNO conectado a un display HD44780 y a un módulo wifi ESP8266. Arduino envía cadenas hello world al servidor sockettest que está escuchando por el puerto 49000. Se modifica el código Arduino en el IDE poniendo hello folks, se compila y el fichero .hex generado (se puede ver donde está activandolo en Archivo/Preferencias/compilación) se copia a la carpeta del programa en python. Cuando Arduino recibe un comando reboot se conecta al servidor python por el puerto 50000 entrando en modo de datos, acto seguido se reinicia y empieza la programación remota de Arduino. El proceso se reliza dos veces en el vídeo.

Lo que se aprovecha es el método que tiene Arduino para programarse, ya que usando el puerto serie después de un reset se puede programar un Arduino si se sigue el protocolo STK500 implementado en el bootloader.

Esquema de conexiones

esquema

El Arduino y el display HD44780 se alimentan a 5 voltios, el módulo ESP8266 se alimenta a 3,3 voltios. Como el pin rx del módulo wifi sólo puede funcionar a 3,3V se usa un diodo zener de 3,3 voltios junto con una resistencia de 100 Ω.

En las placas Arduino, el pin de reset del microcontrolador está conectado a una resistencia y esta a su vez está conectada a VCC, con lo que para el microcontrolador el pin está a nivel alto. Cuando se pulsa el botón de reset lo que se hace es derivar la corriente hacia masa (ya que el bóton está conectado a esta) y el microcontrolador, al estar a nivel bajo el pin de reset, realiza un reseteo. Cuando el microcontrolador arranca, todos los pines están configurados como entradas (alta impedancia) y por eso no le afecta que el pin de reset esté conectado directamente al pin 12. Si se configura el pin 12 como salida y luego se conecta a masa (nivel bajo o LOW) se provoca el mismo efecto que si se pulsase el botón de reset, además, al existir la resistencia anteriormente mencionada, no hay que preocuparse de que se produzca un cortocircuito al unir VCC con masa (GND).

Sketch de Arduino

Lo que hace el skecth de Arduino es:

  • Inicializa el puerto serie a 115200 bps.
  • Elimina los caracteres que hubiera en el buffer de entrada del puerto serie.
  • Inicializa el módulo wifi en modo estación, lo resetea, se conecta al punto de acceso normal, configura las conexiones como simples en modo normal y se conecta al servidor normal por el puerto 49000. Si hubiese algún fallo en algún punto pararía la ejecución y lo indicaría en el display.
  • Envia una cadena de texto y un número consecutivo tanto al servidor como al display. Si hubiese algún fallo en algún punto pararía la ejecución y lo indicaría en el display.
  • Si entre el envío de las cadenas de texto se recibe una cadena reboot entonces resetea el módulo, se conecta al punto de acceso bootloader, configura las conexiones como simples en modo normal y se conecta al servidor de programación por el puerto 50000. Acto seguido envía una cadena hello y espera a recibir una cadena welcome, si ha sido así, entonces envía el nombre del fichero .hex con el que quiere ser programado el Arduino y espera a recibir una cadena ok, momento en el cual configura el pin 12 como salida y lo pone a nivel bajo, conectándolo a masa y provocando un reset en el Arduino. Si hubiese algún fallo en algún punto pararía la ejecución y lo indicaría en el display.

Aquí cabe destacar cómo funciona el sistema de reseteo: Justo después del reseteo, el pin de TX de Arduino está a nivel bajo durante un tiempo, lo que provoca que el módulo wifi vea eso como un byte 0, que enviará a través de la conexión TCP/IP. El servidor de programación aprovechará esta circunstancia para saber cuando ha empezado el reseteo e iniciar el protocolo STK500. El bootloader de Arduino entra en acción después del reseteo y espera a recibir ordenes del protocolo STK500, si las recibe actúa en consecuencia, si no, ejecuta el programa principal.

Servidor de programación

Lo que hace el servidor de programación es:

  • Crea un socket que escuche por el puerto 50000
  • Cuando un cliente de conecta espera a la cadena hello, si la recibe reponde con una cadena welcome.
  • Espera a que el cliente le envíe un nombre de fichero .hex. Trata de abrir el fichero en el mismo directorio y lo lee interpretando todas las líneas para guardar los datos del programa en memoria. Si todo va bien envía una cadena ok.
  • Espera a recibir el byte 0, y cuando lo recibe empieza el protocolo STK500 para comunicarse con el bootloader de Arduino y programarlo. Básicamente lo que hace es entrar en modo de programación, indicarle a que páginas quiere acceder y enviar los datos de cada página, así hasta que ha enviado todos los datos del programa, después sale del modo de programación cerrando la conexión

Aquí cabe destacar que cuando se cierra la conexión TCP/IP con el cliente (ya sea por un error o porque el proceso de programación ya ha terminado), el módulo ESP8266 sale del modo de datos automáticamente y no es necesario que el nuevo sketch tenga que enviarle la cadena de escape +++ para poder entrar otra vez en modo de comandos.

Conclusiones

Espero que esto os sirva para que en vuestros proyectos podais programar remotamente vuestros Arduinos a través de una red local o Internet.

Habría que tener en cuenta que el proceso de actualización puede quedarse a medias si la conexión a la red wifi es lenta y provocaría que el programa no se ejecutara correctamente. Así que que una mejora sería acoplar un chip aparte que reprogramase el Arduino por ICSP con un programa preestablecido en caso de que detectase que la programación no fue finalizada correctamente.

Comentar que la versión de firmware del módulo ESP8266 que he usado es la 0019000902 y el Arduino es un UNO. Ambos funcionan a 115200 bps, pero si quisierais utilizar otras velocidades (en otros Arduinos el bootloader configura el puerto serie a 19200 o 57600 bps) habría que cargar un firmware que lo permitiese, como por ejemplo la versión 0.922 de electrodragon y su comando AT+CIOBAUD.

Encender petardos y cohetes con Arduino y Android

Creo que a estas alturas todos hemos visto cómo se encienden petardos y cohetes: simplemente acercando la llama de un mechero a la mecha de estos y la magia de la pólvora hace el resto.

En este artículo voy a explicar cómo hacer el mismo proceso pero de una forma más segura, y por supuesto más tecnológica.

1402682187170

Pero antes unas reglas básicas:

  • Los petardos y los cohetes son peligrosos, por eso se cauteloso cuando los manejes.
  • No enciendas un petardo o un cohete en la mano ni cerca de ti, de otras personas o animales.
  • No molestes a la gente encendiéndolos en zonas residenciales ni en horarios intempestivos.
  • Muchos municipios tienen prohibido el uso de material pirotécnico en toda su zona metropolitana.
  • El hilo de nicrom alcanza temperaturas elevadas, cerciorate que no pasa corriente por él cuando lo estés manejando.
  • Las baterías de litio son peligrosas, sigue las instrucciones de seguridad que las acompañan.
  • Usa cableado que permita un valor de corriente en amperios mucho mayor que lo que va a consumir el sistema.

Este artículo es meramente divulgativo y no me hago responsable de cualquier incidencia que pudiera ocurrir si lo pones en práctica, por tanto si lo llevas a cabo será bajo tu propia responsabilidad.

La idea es encender la mecha de petardos o cohetes desde un móvil Android, tal y como se puede ver en el siguiente vídeo que grabé para la demostración:

El esquema de los componentes es el siguiente:

esquema

Empezamos por una batería LiPo de 3 celdas (11,1 V.) que será la encargada de la alimentación del conjunto. Todo el cableado está pensado para corrientes de 10 A, pero puede diferir según tus necesidades.

Seguimos con un fusible de 10A, que será el que corte la corriente si se produce un cortocircuito (por ejemplo en el caso de que debido a la explosión de un petardo se unieran directamente los terminales VCC y GND que sujetan el hilo de nicrom).

A continuación está el hilo de nicrom. Este cable, que tiene muy poca resistencia (2,2 Ω en mi caso), se pone al rojo vivo cuando pasa una corriente a través de el. La velocidad a la que se calienta depende del voltaje que se aplique, lo normal suele ser alrededor de los 12 voltios. Este hará las veces de encendedor de la mecha, ya que puede llegar a los 300º C. Se puede adquirir en cualquier tienda de electrónica o reciclarse de un secador de pelo o de una tostadora.

Después viene un transistor mosfet de canal N, que será el interruptor que hará que el hilo de nicrom se encienda o se apague. Hay muchos tipos de mosfet de canal N, por lo que nos interesa uno que pueda ser usado con microcontroladores con lógica TTL (como el de la placa Arduino). Yo he usado el STP55NF06L con encapsulamiento TO-220 ¿por qué?, pues en la hoja de características podemos verlo:

El Vds es de 60 V. Como voy a usar 12 V. Tengo más que de sobra.

El Id es de 55 A. Según la ley de Ohm, La fuente de alimentación de 12 V. partido por la resistencia del hilo de nicrom con 2,2 Ω nos dá que se consumen unos 5 A. Igualmente tengo mucho margen.

El Vgs(th) minima es de 1V. Eso significa que cuando el voltaje es menor que 1V el circuito está abierto y que por encima de esto cerrará el circuito dejando pasar la corriente. Ideal para el Arduino que trabaja con 5 V.

La Rds(on) máxima es muy baja: 0,020 Ω. Esto significa que prácticamente el mosfet no se calentará con la corriente con la que le hagamos trabajar (5 A. * 5 A. * 0,020 Ω = 0,5 Watios)

La gráfica Id/Vds indica que con 5 V en el pin Gate del mosfet, podemos conducir una tensión de 12 V. con una carga de mucho más de 120 A. Como sólo tenemos unos 5 A. tenemos más que suficiente.

idvds

Como se trata de un mosfet de canal N, el pin Source (3) tiene que ir a masa y el pin Drain (2) tiene que estar conectado a la carga. El pin Gate (1) tiene que estar conectado a Arduino, que será quien le dirá si tiene que estar abierto o no. Además entre la conexión del Arduino y Gate hay una resistencia de 10K que va a masa directamente, esto es para que:

  • La puerta lógica no quede flotante y su estado esté indeterminado (pudiendo activar el nicrom antes de tiempo), por lo que si el pin de Arduino esta puesto configurado como entrada (al arrancar siempre está asi) el Gate esté conectado a masa (0 V. o LOW).
  • Debido al caso anterior, cuando el pin de Arduino está configurado como salida y pone la entrada a 5 V. (o HIGH), la resistencia de 10K hace que no haya cortocircuito con masa.

Proseguimos con la placa Arduino, cuyo programa se puede descargar de aquí. La placa está alimentada también desde la batería LiPo, ya sea directamente a los pines Vin y GND o a través del conector de alimentación. Unido a Arduino está un módulo Bluetooth HC-06 que será el encargado de comunicarse con el móvil.

Finalmente en el móvil, que tiene que tener el sistema operativo Android, hay que instalar la aplicación ArduDroid desde la Play Store, que con su interfaz sencilla podemos manejar los pines de Arduino directamente.

Screenshot_2014-06-16-13-37-04