1 de diciembre de 2019

Listado de entradas Botón del Pánico


Proyecto Botón del Pánico


Proyecto BOTPA (0): pasos previos.

Hola a todos/as,

Empezando con la máquina CNC (Vogvigo 3018 Pro CNC) ... ¡Y aún no he abierto la caja!

Caja CNC con maderas mártires y cajita de taladros flecha

En algún momento de esta semana me pondré con ello. Quizás en el puente. Este trimestre ha sido de locos; casi todas las tardes he tenido cosas que hacer de papeleo para el instituto. 😫😫

Pero he sacado un rato, investigado algo por internet, y dado los primeros pasos para el primer proyecto total: el botón del pánico (BOTPA).

¿En qué consiste? ¿Por qué es total? Porque el objetivo es construir un dispositivo, desde cero, diseñando la electrónica, implementándola en una placa, y construyendo su carcasa. 

Por partes. Primero necesito el IDE de Aruino y un ordenador para programar nuestro dispositivo. En este caso usaré NodeMCU, componentes parecidos a las placas de Arduino.

Una vez prototipado y en funcionamiento, con el programa Fritzing o Kicad, se diseña el circuito en placa (PCB). Tengo, de cuando usaba dibujos a tinta en la placa (con rotuladores Edding) y necesitaba el ácido, bastante baquelita de una cara de cobre. Creo que será suficiente dado que el número de conexiones y componentes no es muy alto. Así que, lo segundo, es obtener los ficheros en formato GERBER con Fritzing.

Podría, en este punto, obtener los dibujos de las pistas, y pasarlo de forma manual a la baquelita, consiguiendo las pistas después con el ácido. Pero para eso me he comprado la máquina de CNC, para que talle las pistas y haga los agujeros. Si el resultado es el esperado, habrás sido un gran paso para el proyecto total. Otra solución es encargar a algún fabricante de placas PCB las mismas (Por ejemplo, https://aisler.net/partners/fritzing). Pero me hace ilusión fabricarlas por mí mismo. 

Por lo que he investigado, necesito convertir los ficheros GERBER a GCODE, tercer paso. Tenemos una aplicación online https://carbide3d.com/apps/rapidpcb/ que realiza esta función. Básicamente te guía a través del proceso: pide el fichero de pistas (*_copper_bottom.gbl) y el fichero de taladros (*_drill.txt) y con esa información junto a los diversos parámetros que necesita cada parte de lproceso, construye el fichero GCODE. Este tipo de ficheros es el que leería la máquina CNC.

Una vez construida la placa, se armaría con los componentes y se probaría. Pero aún queda una cuarta fase para el proyecto total: la construcción de la carcasa. Y aquí entraría la impresora 3D.

Impresora 3D Anet A6

Con la impresora 3D puedo "empaquetar" los componentes para presentar un dispositivo completo.

26 de septiembre de 2019

Listado de tareas de 2º BAC TIC

Instalación de un SO de software libre en un ordenador.

Usaremos un ordenador de 32 bits portátil, al cual le instalaremos un SO linux. Los pasos que tienes que dar para realizar esta tarea son:
Primer paso (1-2 sesiones)
  1. Usando el ordenador de clase, que es de 64 bits, formatea el pen con extensión ext4 (si es que se puede especificar la extensión).
  2. Usando el ordenador de clase, localiza en internet una versión de linux que te guste. Hay muchísimas. Eso sí, debe ser compatible con 32 bits y es muy conveniente que elijas una que tenga entorno gráfico (la mayoría).
  3. Usando el ordenador de clase, descarga una imagen para grabar de la versión que hayas elegido.
  4. Usando el ordenador de clase, graba la imagen en el pen descomprimiéndola en el mismo para que pueda ejecutarse en el arranque. Lee en internet como "crear un disco de arranque" desde el ordenador de clase, que tiene instalada la versión Ubuntu 18.04 o Linux Mint 19.
Segundo paso (1 sesión)
  1. Nota: este paso hay que hacerlo "del tirón", es decir, tenemos una hora para instalar el SO en el ordenador. Si no lo conseguimos, apagamos y debemos empezar de nuevo al día siguiente.
  2. Averigua como entrar en la BIOS del ordenador portátil y comprobar el orden de arranque. Deberás poner el pen USB como primer dispositivo de arranque.
  3. Una vez arranques con el pen sigue las instrucciones. Los SO tipo linux son parecidos. Es importante seguir las instrucciones que aparecen en pantalla y, si lo necesitas, usa el ordenador de clase para conseguir información del proceso.
  4. Entre otras informaciones deberás crear al menos un usuario (si sólo es uno también será administrador; anota la contraseña) o un usuario normal y otro administrador. En todo caso, anota siempre las contraseñas que pongas. No las pierdas.
  5. Si llega a un paso en que pide un particionado, elige la opción "borrar disco completo" o similar.
  6. Todo saldrá bien cuando puedas usar el ordenador.
Tercer paso (de la primera a la tercera sesión)
  1. Redacta un documento en el que anotes el proceso que hayas realizado, los avances y dificultades que te has encontrado. ¿Te ha resultado sencillo o difícil? Detallar lo más posible cada paso.
= = = = = = = = =

Manejo del shell de Linux.

En nuestro recién instalado SO abrimos una terminal de comandos (también llamado shell). Aunque nuestro SO tenga instalado un entorno gráfico y muchos comandos sean a través de una interfaz gráfica, todos los SO aceptan órdenes por comando escritas. Es fundamental conocer algunas órdenes importantes.
shell linux

Modo normal

  1. Abre el terminal. Según tu sistema operativo puede estar en el menú APLICACIONES >> HERRAMIENTAS DEL SISTEMA, o bien ves el símbolo Tutorial: The best tips & tricks for bash, explained (doble click sobre él) o parecido. En todo caso, siempre se puede acceder pulsando a la vez CTRL+ALT+T.
  2. Si no encuentras información en estos vídeos (del 6º en adelante), busca información en internet. Te voy a pedir que aprendas lo siguiente, como mínimo:
    • Moverte por las carpetas del SO (comando cd)
    • Listar ficheros de una carpeta (comando ls). Observar bien la información de salida que ofrece: usuario, grupo, permisos.
    • Crear un directorio llamado "otros" dentro de la carpeta /home/[nombre de tu usuario] (comando mkdir). Dentro de la carpeta otros crea las subcarpetas primera y segunda.
      • Nota: directorio y carpeta se usan como sinónimos. Subcarpeta es una carpeta dentro de otra, y es sinónimo de subdirectorio.
    • Crear dentro del directorio primera (accede primero a él con cd), un fichero de texto llamado grupo.txt que contendrá los nombres de los componentes del grupo. Primero con la orden cat (obligatoria), o también con la orden nano (y hay más opciones). 

    • Usa el comando mv para mover el fichero de la carpeta primera a la segunda. Observa que este comando sirve también para renombrar, incluso dentro de la misma carpeta. Así que al final debes tener el fichero grupo.txt en la carpeta segunda pero cambiando el nombre a miembros_del_grupo.txt.
    • Vamos a poner una copia del fichero (no moverlo, sino copiarlo). Utiliza el comando cp para copiar el fichero miembros_del_grupo.txt de la segunda carpeta a la primera con el nombre de grupo_members.txt
    • Borra el fichero grupo_members.txt con el comando rm. Importante: debes estar dentro de la carpeta segunda para hacerlo. Echa un vistazo a la web https://esgeeks.com/comando-rm-en-linux/
      • Nota: ten mucho cuidado. El comando rm mal usado puede borrar todo tu disco duro.
      • Comprueba que se ha borrado el fichero haciendo ls -l en la carpeta segunda.
    • Borra la carpeta segundahttps://lignux.com/como-eliminar-carpetas-desde-la-terminal-en-gnu-linux/
      • Llegados a este punto, sabremos usar comandos básicos para crear, mover, copiar y borrar ficheros y carpetas en linux. Deberemos tener una carpeta primera dentro de la carpeta otros con un fichero llamado miembros_del_grupo.txt
    • Hay algunos atajos de teclado básicos en linux. Una lista completa puedes encontrarla aquí: https://picodotdev.github.io/blog-bitix/2016/06/atajos-de-teclado-basicos-de-la-terminal-en-gnu-linux/. Pero te voy a pedir que practiques los siguientes:
      • Ya conocemos CTRL+ALT+T que abre la terminal.
      • Las flechas arriba y abajo harán aparecer órdenes que hemos ejecutado anteriormente (historial de órdenes). Es muy útil cuando necesito ejecutarlas varias veces.
      • La tecla TAB autocompleta. Por ejemplo, haz un cd a una carpeta pero no termines de escribir su nombre. Empieza a escribir las primeras letras y pulsa TAB. Verás como se termina de escribir.
      • Ctrl+c: termina el proceso que se esté ejecutando, útil para recuperar el control del sistema. A veces se queda bloqueado.
      • Ctrl+d: sale de la terminal, similar al comando exit.
      • Ctrl+z: suspende la ejecución del proceso que se está ejecutando y lo pone en segundo plano, con el comando fg podremos volver a continuar su ejecución.
      • Y el comando clear, que borrar la pantalla de órdenes o Ctrl+l
      • Copiar/pegar en el terminal sería ctrl+c y ctrl+v pero también pulsando la tecla mayúsculas.
    • Obtener información de las unidades de almacenamiento: df -hlsblk -fm. Intenta también fdisk -l ¿qué ocurre?
    • Obtener información sobre nuestros puertos USB: lsusb.
= = = = = = = =

Modo administrador

  1. Hasta ahora, hemos realizado un montón de operaciones básicas. Pero quiero que te fijes en lo siguiente. Nada más ejecutar el terminal, antes del cursor que espera órdenes te encuentras "algo" escrito. En mi caso usuario. Primero aparece el nombre del usuario activo y separado con el símbolo @ el nombre del equipo. Y después los símbolos ~ y $
  2. El símbolo ~ (virgulilla)  indica que estoy en mi directorio /home/[nombre de mi usuario]. Si me muevo por el árbol de directorios, irá cambiando. Observa usando cd y ls.
  3. El símbolo $ (dolar) indica que estoy accediendo como usuario normal. 
  4. ¿Te acuerdas de esa contraseña que cuando instalamos el SO tenías que tener, de superusuario o usuario root, o usuario administrador? Pues tenla a mano, porque la vamos a necesitar.
  5. Para entrar en modo administración, en la mayoría de linux se usa el comando sudo o su:
    • Por ejemplo, escribe sudo -i. Y te pedirá la contraseña de administración.  O bien sudo su -.
    • O escribe su - (en sistemas como Debian).
    • ¿Qué ha cambiado? Pues si te fijas, en la línea de comandos, cambia el nombre del usuario a root y en lugar del símbolo $ aparece #
    • Ahora deberás tener cuidado, sobre todo con los comandos que puedan borrar o cambiar elementos. Porque has entrado, en lo que al ordenador respecta, en el "modo dios". Ahora tienes control total sobre el ordenador. Y si no, prueba. ¿Te acuerdas que fdisk -l daba permisos denegados? Hazlo ahora como root (acuérdate de que debe aparecer almohadilla).
  6. Para salir del modo administrador, escribe el comando exit. Recuerda siempre que con los comandos pwd y whoami sabrás siempre en qué ruta estas y quién eres. 
= = = = = = = =

Creando usuarios y grupos

  1. Los SOs mantienen políticas de acceso a los ficheros y carpetas a través de la creación de usuarios y grupos. Un usuario puede, dentro del SO, personalizar aspectos tales como el escritorio o el juego de iconos que usa, y poseer un lugar específico en el que guardar su información independientemente de otros usuarios. A una personalización concreta de un SO asociada a un usuario se le denomina perfil. Un archivo cualquiera, creado por un usuario, pertenece a dicho usuario y lógicamente éste puede verlo, editarlo o borrarlo. Sin embargo, puede controlar lo que pueden hacer con él otros usuarios. A lo mejor simplemente deja que los demás puedan acceder a él, pero no cambiarlo o borrarlo. O permite todo menos el borrado. Las combinaciones son muchas.
  2. Un grupo son asociaciones de usuarios. Normalmente los grupos tienen permisos específicos dentro del SO para hacer algo. Por ejemplo, los usuarios que pertenecen al grupo lpadmin pueden gestionar las impresoras o los usuarios que pertenecen al grupo sudo son administradores del sistema (hay que incluirlos también en el fichero sudoers). Esos grupos vienen definidos por defecto, pero puedo crear más grupos (por ejemplo, profesores y alumnos) y se suelen usar para dar permisos específicos sobre carpetas y usuarios.
  3. Todo este apartado viene muy bien explicado en la web: http://www.ubuntu-guia.com/2009/09/gestion-de-usuarios-y-grupos-en-ubuntu.html
  4. Para ver los usuarios y los grupos existentes puedes escribir en la consola cat /etc/passwd y cat /etc/group respectivamente.
  5. Entra como usuario administrador y...
    • Crea el usuario friki (contraseña friki)Rellena los campos que te pide el comando adduser
    • Se crea el grupo friki automáticamente, pero vamos a crear otro llamado losfrikis. Comando addgroup
    • Añade el usuario friki al grupo losfrikis. Con adduser también.
    • Sal de la consola de administración con exit.

Dando permisos a usuarios

  1. Si todo lo hiciste correctamente, has añadido un nuevo usuario (friki) y un nuevo grupo (losfrikis) al sistema. Pero en la consola estás logueado como el usuario de siempre.
  2. Navega a tu carpeta home hacia la carpeta otros, que tenía la carpeta primera y el fichero miembros_del_grupo.txt. Si haces ls -l dentro de la carpeta primera aparece en el listado esta información: -rw-rw-r-- 1 usuario1 usuarios 4819 sep 15 08:01 miembros_del_grupo.txt
  3. El primer conjunto de letras (drwx) se refieren a los permisos del fichero. Ahora los explicamos. La segunda palabra es el nombre del usuario al que pertenece el fichero y la siguiente al grupo que pertenece, el tamaño en kilobits, y la fecha y hora en que se creó el fichero.
  4. Estando dentro de la carpeta primera, usamos chown para cambiar el usuario y el grupo del fichero. Hay que hacerlo como administrador, así que escribimos sudo chown friki:losfrikis miembros_del_grupo.txt (nos pedirá la contraseña).
  5. Si hacemos ls -l veremos como ha cambiado el propietario y el grupo: -rw-rw-r-- 1 friki losfrikis 4819 sep 15 08:01 miembros_del_grupo.txt
  6. Comprueba que estás como el usuario normal que tengas (usuario1??) y escribe cat > miembros_del_grupo.txt. Te dará un error porque ¡¡ya no es tu fichero!! ¡¡Permiso denegado!! pero todavía deja leerlo con cat miembros_del_grupo.txt
  7. Fíjate bien en las primeras letras. La primera suele ser un guión, indicando que es un fichero, pero podría ser una d indicando un directorio. Y después viene una agrupación de tres letras repetidas 3 veces. En el primer grupo de letras tenemos rw-, lo que indica que el usuario (u) propietario del fichero puede leer y escribir en el fichero, pero no usarlo como ejecutable (aparecería una x); lo mismo con las siguientes letras para el grupo (g) al que pertenece y lo mismo con las tres últimas para los demás (o). Pero claro, en este ejemplo, los demás tienen permiso r-- (sólo de lectura). Por eso el usuario1 no puede editar el fichero miembros_del_grupo.txt, porque entra en la categoría de otros.
  8. Vamos a darle permisos a otros (o) para poder editarlo. Escribe sudo chmod o+w miembros_del_grupo.txt
  9. chmod es el comando para modificar los permisos de los ficheros y carpetas. Y añado (+) el permiso de escritura (w) a otros (o) usuarios en ese fichero. Podría quitarlo con (-). Si hago un ls -l ahora aparecen las letras -rw-rw-rw-, y, ahora, el usuario usuario1 puede editar el fichero con la orden nano miembros_del_grupo.txt.
  10. Para saber más de chmod: https://blog.desdelinux.net/permisos-basicos-en-gnulinux-con-chmod/
  11. Para saber más sobre chmod, chown y carpetas (cuidado): https://www.hostinger.es/tutoriales/cambiar-permisos-y-propietarios-linux-linea-de-comandos/
  12. Devuelve el fichero a su propietario con el comando chown.
  13. Borrar el usuario friki y el grupo losfrikis. ¿Queda algún resto?

Instalando programas y paquetes

  1. Instalar programas en los SO linux es un proceso variado (siempre hacerlo como root). El comando apt-get o apt es el más sencillo. Por ejemplo, hacer un apt-get install [nombre_del_programa] instala el programa desde un repositorio (biblioteca de programas) que mantenga la distribución correspondiente. O bien podemos instalarlo mediante un paquete debian o rpm (red hat). Para ello usamos las órdenes dpkg -i [nombre_del_paquete].deb rpm -ivh paquete-a-instalar.rpm. O incluso usando el método más complicado (y muy poco recomendable para novatos) que es compilando un código fuente.
  2. Usa el contenido de las direcciones https://www.atareao.es/software/utilidades/instalar-paquetes-en-ubuntu-apt-vs-apt-get/ y https://www.freecadweb.org/wiki/Install_on_Unix/es. Consigue la instalación en tu SO del programa freecad.
  3. Es posible que necesites primero hacer un add-apt-repository ppa:[ndpreccion_del_repositorio] para añadir la dirección de los repositorios y un apt-get update para actualizar la información de los mismos ; apt-get autoremove y apt-get autoclean para quitar los paquetes no necesarios y limpiar la caché de entradas de paquetes que no se usan.
  4. Si encuentras en el menú del entorno gráfico a freecad habrás realizado el proceso correctamente.

Otros

  1. https://maslinux.es/uso-de-los-comandos-du-y-df-con-ejemplos/
  2. https://es.wikibooks.org/wiki/Manual_de_consola_Bash_de_Linux
  3. https://blog.desdelinux.net/uso-del-comando-dd/
= = = = = = = = =


21 de septiembre de 2019

Listado de tareas 4º ESO. Curso 2019_2020. Herramientas de Google

Listado de tareas

T2_01: Enviar un correo electrónico (trabajo individual)


Como tarea tendrás que enviar un correo electrónico desde tu nueva dirección a la del profesor (aurelio@seritium.es). En asunto debes poner el nombre de los componentes del grupo, y en el texto debéis contarme algo sobre tus hobbies.


T2_02: Enviar un correo electrónico adjuntando fichero


Imagina que tienes un amigo/a extranjero. Te ha pedido que cuentes cómo es tu ciudad, así que cuéntale los monumentos más importantes que tiene Jerez, qué fiestas celebra a lo largo del año. Acompaña tu relato de varias fotos que adjuntarás por internet. Búscalas primero en Google Imágenes y descárgalas al ordenador.

Tendrás que enviarlo para que te lo corrija a la dirección email del profesor (aurelio@seritium.es). En asunto debes poner el nombre de los componentes del grupo.

NOTA: vuestro profesor debe explicaros cómo descargar una imagen desde los navegadores.


T2_03: Escribe un documento de Google Drive


¡Chicos/as, tenemos trabajo!

Llevamos ya varias semanas que los contenedores de basura de nuestra calle están colapsados. Antes había dos, y no sabemos por qué, ahora sólo hay uno. Los vecinos no tienen más remedio que dejar las bolsas de basura fuera del contenedor, en la acera. Y claro, las bolsas se rompen, se desparraman los desperdicios, huele mal...

Vamos escribirle una carta al concejal de infraestructuras de Jerez. Explica la situación lo mejor que puedas y pídele que solucione el problema de los contenedores. Esta carta debe escribirse directamente en Google Drive.

La forma de entregarla es la siguiente: cuando termines, busca "descargar documento" y la descargas como PDF. Una vez la tengas descargada en el ordenador, la adjuntas a esta tarea.

T2_04: Presentación: organización de una prueba deportiva.


Nos gusta mucho el deporte, y correr es lo nuestro...

Tanto que nos han encargado la organización de una prueba deportiva: una carrera solidaria.

La organización de esta carrera implica:

    Elegir cinco lugares significativos de nuestra ciudad.
    Trazar un recorrido por las calles entre ellos. El recorrido total debe estar entre los 5 y los 10 km.
    Elegir las normas de la carrera.

Toda esta información se verá plasmada en un documento Presentación de Google. Esta presentación deberá incluir:

    Información de cada lugar significativo: breve descripción, fotografías.
    Mapas de los tramos de la carrera, indicando la distancia entre ellos, y las principales calles por donde discurre.
    Mapa de la prueba completa. Indica la distancia total del recorrido.
    Normas de la prueba.

Una vez lo termines,

    comparte la información con el correo aurelio@seritium.es, y...
    ...escribe la dirección de visualización en la caja de texto.


= = = = = = = = = =

T3_01: Hardware de ordenadores

El siguiente trabajo que realizaremos en el curso consiste en el estudio de las partes de un ordenador. Imaginemos que vamos a montar una empresa y necesitaremos comprar uno (tipo torre, portátil no vale), pero nos atreveremos a montarlo nosotros mismos, comprando las piezas por separado.
  1. Elaborar una presentación usando Google Drive.  En el trabajo hay que poner el nombre de todos los componentes del mismo.
  2. Tendremos 1 semana para hacerlo.
  3. Estudiaremos los componentes uno a uno:
    1. Accede a la web:
    2. Elige un  microprocesador o procesador (1 hora): Indicar el modelo (i3,i5,i7), frecuencia en GHz, zócalo o socket, memoria caché, núcleos, memorias compatibles y velocidades de acceso a la memoria, potencia (Potencia de diseño térmico (TDP)).
    3. Elige una placa base: importante, tiene que ser compatible con el modelo de microprocesador que hayas escogido. Hay que ver si la placa es para un i3, un i5 o un i7 y tener el mismo zócalo o socket.
    4. Elige un disco duro SSD SATA. Indica velocidad de lectura  500 MB/s, velocidad de escritura (350 MB/s) y velocidad de transmisión de datos (Ej: 6Gbits/s).
    5. Elige un disco duro HDD SATA. Indica tamaño de disco duro  (ej: 3.5" pulgadas) y velocidad de rotación de disco duro (ej: 7200rpm), y velocidad de transmisión de datos (Ej: 6Gbits/s).
    6. Elige una memoria: hay que fijarse en la capacidad ("Gigas" que tiene, mínimo 8GB), y que la velocidad y el tipo de memoria coincida con las compatibles con el microprocesador y la placa base. Por ejemplo, si elegí un procesador PROCESADOR INTEL CORE i5-7600 , compatible con DDR3L-SDRAM,DDR4-SDRAM (con velocidad de memoria 1333,1600,2133,2400 MHz), puedo escoger, por ejemplo, MEMORIA 16 GB DDR4 2400 CRUCIAL BALLISTIX SPORT GRIS CL16. También es posible comprar un KIT, un juego de normalmente dos memorias. Sus capacidades se suman. Por ejemplo, 8GB+8GB=16GB.
    7. Elige:
      • Ratón y teclado, el que queráis, pero que sean de conexión USB. También hay ofertas de kits ratón + teclado. Si los queréis inalámbricos...
      • La caja escogeremos una tipo ATX SEMITORRE. 
      • Fuente de tensión o fuente de alimentación: el factor más importante es la potencia, que se mide en vatios. Escogeremos fuentes de tensión entre 500W y 1000W.
    8. Tarjeta Gráfica: escogeremos tarjetas nvidia pci express o amd pci express. Una tarjeta gráfica es como un pequeño ordenador en sí mismo, que, en la parte gráfica, hace el trabajo de mostrar las imágenes en la pantalla y realizar los cálculos asociados. Sólo nos vamos a fijar en los "gigas" que tengan.
    9. Pantalla o Monitor: nos fijaremos simplemente en su tamaño, en pulgadas. Por ejemplo, pantallas de 21.5" (veintiún coma 5 pulgadas).
  4. Importante: anota lo que te va a costar cada componente, porque tendrás que sumarlo para decir lo que te va a costar.
Te pueden ayudar más varias páginas web, aunque no es aconsejable seguir ninguna al pie de la letra. Mejor como referencia:
CÓMO ENTREGAR EL TRABAJO.  IMPORTANTE:
  1. Compartir el documento en Google Drive de forma PÚBLICA (todo el mundo puede ver).
  2. En la entrega del trabajo, copiar el enlace de compartición del documento.

T3_02: Periféricos interesantes

Entra en el documento anexo y averigua qué son cada uno de los periféricos que están en la lista. Escribe en un documento de Google Drive qué es cada uno, para qué sirve y algunas de sus características. Estos periféricos pueden servirte en una tienda o en una empresa pequeña ¿por qué? Escribe también por qué pueden ser importantes en una tienda.

La entrega se realiza compartiendo el documento de forma pública (todo el mundo puede ver) y escribiendo el enlace en la caja de texto de entrega.

1 de septiembre de 2019

Viejas Tecnologías de verano

No todo van a ser nuevas tecnologías.

Este verano me he dedicado a arreglar un cuarto que tengo como despacho. Suelo vinílico y mesas-estanterías.














14 de julio de 2019

NodeMCU: comunicación con Firebase y google Spreadsheet (VII-D).

La idea principal de esta entrada es que la estación escriba el dato enviado el mismo a dos lugares: la base de datos Realtime de Firebase y la hoja de cálculo de Google Spreadsheet. La primera para una comunicación fluida con la central y con otros posibles dispositivos en un futuro; la segunda con propósitos de registro y tratamiento de datos.

Tengo dos posibilidades de hacerlo:
  1. Que el NodeMCU de la estación envíe los datos a ambos lugares. Primero a Firebase y después a Google Spreadsheet.
  2. Que el NodeMCU de la estación envíe los datos a Google Spreadsheet y el script de la hoja de cálculo envíe a su vez los datos a Firebase. 
La primera opción me pareció más adecuada en un principio, pero también es verdad que ocuparía más espacio en la memoria del dispositivo, pues usamos 4 bibliotecas. De todas formas el código presenta muchas instrucciones con salidas al Monitor Serie que se pueden obviar.



Paso pues a indicar los códigos de programación....

NodeMCU


/*
 * Created by Aurelio Gallardo Rodríguez
 * Based on: K. Suwatchai (Mobizt)
 *
 * Email: aurelio@seritium.es
 *
 * ESTACION. Escritura. Envío de información a Firebase y Google Spreadsheet
 *
 * Julio - 2019
 *
*/


//FirebaseESP8266.h must be included before ESP8266WiFi.h
#include "FirebaseESP8266.h"
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

#define FIREBASE_HOST "[mibasededatosfirebase].firebaseio.com"
#define FIREBASE_AUTH "kfcm8934jf7894ch93c092342039h2309h" // token o secreto inventado
#define WIFI_SSID "miSSID"
#define WIFI_PASSWORD "miCONTRASEÑA"

const char* host = "script.google.com"; // Este es el host de los scripts de google.
const int httpsPort = 443;
// Huella digital del script de Google:
// D4:9E:40:F4:53:7A:04:93:38:F7:6B:4B:DC:70:02:A9:03:98:C2:DE
const char* fingerprint = "D4 9E 40 F4 53 7A 04 93 38 F7 6B 4B DC 70 02 A9 03 98 C2 DE";
// const char* fingerprint = "46 B2 C3 44 9C 59 09 8B 01 B6 F8 BD 4C FB 00 74 91 2F EF F6";

String googleSheetsID = "[Identificación de Google web app]"; // El que me da al implementar una aplicación web en el script.


// objeto comunicación con Google Spreadsheet
WiFiClientSecure cliente;

//Define FirebaseESP8266 data object
FirebaseData bd;

DynamicJsonDocument doc(1024);


String path = "/Estaciones"; // path a FireBase
String estacion = "A"; // Estacion que voy a controlar

int i=1; // contador general

int activo=0;

#define LED 5 // D1(gpio5)
#define BUTTON 4 //D2(gpio4)

int estado=0;
int estadoAnterior=0;
int estadoLuz=0;

void setup()
{

  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT);

  // conectando a la WIFI
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Conectando a la WiFi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Conectado con IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  // Conectando a la bd real Time Firebase
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);

  //Set database read timeout to 1 minute (max 15 minutes)
  Firebase.setReadTimeout(bd, 1000 * 60);
  //tiny, small, medium, large and unlimited.
  //Size and its write timeout e.g. tiny (1s), small (10s), medium (30s) and large (60s).
  Firebase.setwriteSizeLimit(bd, "unlimited");

  wFB(0); // Escribe un cero en la estación al arrancar
   
}

// Bucle principal
void loop() {

  estado=digitalRead(BUTTON);
  if (estado!=estadoAnterior){
    // el estadoAnterior ahora es el estado
    estadoAnterior=estado;
    // si estado es alto, se pasa de bajo a alto
    if (estado) {
       estadoLuz=!estadoLuz; // El estado de la luz cambia
       // sendDataToGoogleSheets(estacion,estadoLuz); // envío a googleSheet esa información
       wFB(estadoLuz); // en vez de enviarlo a Google Spreadsheet, se lo envío a Real Time BD Firebase
       digitalWrite(LED,estadoLuz);
       Serial.println("Estado del LED: "String(estadoLuz)); //Manda al monitor serie ese estado.
       delay(10);
       sendDataToGoogleSheets(estacion,estadoLuz); // envío a googleSheet esa información
    }
  }

  digitalWrite(LED,estadoLuz);
  // digitalWrite(LED,rFB()); // Escribe el estado en un LED, PERO leyéndolo de la BD.
}



// Función que escribe un dato en Firebase.
// Además, actualiza el dato si tiene la misma ruta, no genera un error.
void wFB(int dato) { //Write Data in FB

  if (Firebase.setInt(bd,path+"/"+estacion,dato)) {
      Serial.println("PASSED");
      Serial.println("PATH: " +bd.dataPath());
      Serial.println("TYPE: " +bd.dataType());
      Serial.println("ETag: " + bd.ETag());
      Serial.print("VALUE: ");
      if (bd.dataType() == "int")
        Serial.println(bd.intData());
      else if (bd.dataType() == "float")
        Serial.println(bd.floatData(), 5);
      else if (bd.dataType() == "double")
        printf("%.9lf\n", bd.doubleData());
      else if (bd.dataType() == "boolean")
        Serial.println(bd.boolData() == 1 ? "true" : "false");
      else if (bd.dataType() == "string")
        Serial.println(bd.stringData());
      else if (bd.dataType() == "json")
        Serial.println(bd.jsonData());
      Serial.println("------------------------------------");
      Serial.println();
  } else {
      Serial.println("FAILED");
      Serial.println("REASON: "+ bd.errorReason());
      Serial.println("------------------------------------");
      Serial.println();
  }
}

// Función de lectura
int rFB(){// lee el dato de la entrada correspondiente

  if (Firebase.getInt(bd, path+"/+"estacion)) {

    if (bd.dataType() == "int") {
      Serial.println("Dato leído: "+ (String) bd.intData());
      return bd.intData();      
    }

  } else {
    Serial.println(bd.errorReason());  
  }
}

/* Función de conexión. Importante la instrucción  cliente.setInsecure(); para conectar de forma anónima
 */


void sendDataToGoogleSheets(String nombreEstacion, int Activacion) {

  String cadena="";
 
  Serial.print("Conectando a: ");
  Serial.println(host);

  // cliente.setInsecure();
 
  if (!cliente.connect(host, httpsPort)) {
    Serial.println("Falla la conexión a Google Sheets -->" String(host) ": " String(httpsPort) );
    return;
  }
 
  if (cliente.verify(fingerprint, host)) {
    Serial.println("Certificado OK");
  }
  else {
    Serial.println("Debes comprobar certificado");
  }

  String url = "/macros/s/"+ googleSheetsID + "/exec?estacion="+ nombreEstacion+ "&activo="+ (String) Activacion;
 
  Serial.print("Petición  URL ");
  Serial.println(url);

  cliente.print(String("GET ") url " HTTP/1.1\r\n"
               "Host: " host "\r\n"
               "User-Agent: BuildFailureDetectorESP8266\r\n"
               "Connection: close\r\n\r\n");

  // Es necesario leer las cabeceras  
  Serial.println("Request enviada");
  while (cliente.connected()) {
    String line = cliente.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("Cabeceras Recibidas");
      Serial.println(line);
      break;
    }
  }

  // lee el contenido de la respuesta y lo almacena en la variable cadena
  while (cliente.available()) {
      char c = cliente.read();    
      cadena = cadena (String) c;
  }
  Serial.println("Respuesta directa del servidor");
  Serial.println(cadena);
  Serial.println("==============================");
  Serial.println();
 
  // PROBLEMA: la respuesta, por motivos de seguridad, no es jamás el texto, o el html, sino que está codificada.
  // He resuelto este problema encerrando la respuesta (JSON) entre dos palabras, EMPEZAR y TERMINAR.
  // Una vez localizada la información, la extraigo con la función midString.
  // Los caracteres, en codificación unicode, los transformo en sus caracteres con varias líneas de código...
  // Y voalá... ¡obtiene la respuesta en formato JSON de texto!
  String respuesta =midString(cadena,"EMPEZAR","TERMINAR");
  char comillas = 34;
  respuesta.replace("x7b","{");
  respuesta.replace("x7d","}");
  respuesta.replace("x22",String(comillas));
  respuesta.replace("\\",""); // doble slash para que lo reconozca ??
  // Serial.println(respuesta);

  Serial.println("Respuesta filtrada desde el servidor");
  Serial.println(respuesta);
  Serial.println("==============================");
  Serial.println();

  // Usar bibliteca JSON
  deserializeJson(doc,respuesta);
  JsonObject obj = doc.as<JsonObject>();

  String exito = obj[String("exito")];
  String comentario = obj[String("comentario")];  

 
  Serial.println("Respuesta extraída en variables deserializando la cadena en un objeto JSON");
  Serial.println("Ha tenido éxito: "exito);
  Serial.println("Envía el comentario: "comentario);
  Serial.println("==============================");
  Serial.println();

  delay(500);
 
  cliente.stop(); //cierra la conexión  
}


/* función texto intermedio */
String midString(String str, String start, String finish){
  int locStart = str.indexOf(start);
  if (locStart==-1) return "";
  locStart += start.length();
  int locFinish = str.indexOf(finish, locStart);
  if (locFinish==-1) return "";
  return str.substring(locStart, locFinish);
}

  1.  El código es una fusión de las llamadas a Firebase y a Google Spreadsheet que hemos visto en anteriores entradas. Lo único reseñable es que el método cliente.setInsecure() genera un error, pero el programa funciona sin él. No sé por qué.
  2. Solo cambia la definición de estacion="A"; en el programa anterior estaba escrito como estacion="/A".

Script Web App de Google Spreadsheet.


function doGet(e) {
 
  var estacion = e.parameter.estacion; // variables que se han recibido. ESTACION
  estacion = estacion.toUpperCase();
  var activo = e.parameter.activo; // variables que se han recibido. ACTIVO
  var columna = estacion.charCodeAt(0)-62; // Código ascii -62; la "A" es 65, luego da el valor 3, correspondiente a la tercera columna
 
  // Dirección de la base de datos RealTime de Firebase
  var bd = "[mibasededatosfirebase].firebaseio.com" ;
  // Secreto de la base de datos Firebase
  var secreto = 'lkfjweo45roi56oifUIUEoierfioerfncoc'; // inventado
  // Ruta de la base de datos RealTime
  var ruta = "Estaciones";
 
  var options = { method:'get', contentType: 'application/json' }; //opciones de la llamada a fetch
  var firebaseURL = 'https://'+bd+'/'+ruta+'.json?auth='+secreto; // construyo la ruta
 
  if (columna>=3 && columna<=7 && estacion.length==1) { // si es una sola letra, una columna
    var resultado = UrlFetchApp.fetch(firebaseURL, options);    
   
    // Hoja de cálculo activa
    var sheet = SpreadsheetApp.getActiveSheet();
    var ultimalinea = sheet.getLastRow(); // obtiene la última línea
   
    // Fechas y horas actuales.
    var fecha=Utilities.formatDate(new Date, "GMT+1", "dd/MM/yyyy");
    var d = new Date();
    var hora = d.toLocaleTimeString();
   
    // Objeto JSON según el resultado
   
    var e = JSON.parse(resultado);
   
    for (clave in e) {
      var columna = clave.charCodeAt(0)-62; // columna de cada valor
      var valorActual = sheet.getRange(2,columna).getValue();
      if (valorActual!=e[clave]) { // Si los valores son distintos
        // 1) Cambio fecha y hora en la fila dos
        sheet.getRange(2,1).setValue(fecha);
        sheet.getRange(2,2).setValue(hora);
        // 2) Cambio valor actual en la fila dos
        sheet.getRange(2,columna).setValue(parseInt(e[clave]));
        // 3) Pongo fecha y hora en la última línea
        sheet.getRange(ultimalinea1,1).setValue(fecha);
        sheet.getRange(ultimalinea1,2).setValue(hora);
        // 4) Escribo en la última línea un registro de lo que acontece
        segunActivo(clave,e[clave],ultimalinea1,columna,sheet);
      }  
     
      // Logging de los datos...
      Logger.log(clave);
      Logger.log(e[clave]);
 
     } // Fin del for
   
    // *** Refresco ***
    SpreadsheetApp.flush();
 

var output = HtmlService.createHtmlOutput('EMPEZAR'JSON.stringify(construyeJSON("1","Estación "estacion" activo: "activo))'TERMINAR');
 

    // output.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
 

    return output;
   
  } else { // Fin del if que reconoce la columna
   
    Logger.log("Estación fuera del rango");
   
  }
   
}

// funcion que escribe en el registro según si está activo o no
function segunActivo(estacion,dato,fila,columna,sheet) {
  if (dato==1) {
      sheet.getRange(fila,columna).setValue("Estación "estacion" se activa");
      sheet.getRange(fila,columna).setFontColor("darkgreen");
      sheet.getRange(fila,columna).setBackground("#AAFFAA");
  } else if (dato==0) {
      sheet.getRange(fila,columna).setValue("Estación "estacion" se desactiva");
      sheet.getRange(fila,columna).setFontColor("darkred");
      sheet.getRange(fila,columna).setBackground("#FFAAAA");
  }
}

function construyeJSON(success, comentario) {
  var json = {
    'exito':success,
    'comentario':comentario,
  };
  return json;
}

  1. El código del script es también una fusión de scripts a los que ya nos hemos referido. 
  2. Básicamente recibe una petición GET (por eso el script es una función doGet) y extraigo los valores de la estación, y si está activo o no.
  3. Si tengo un valor correcto de estación, accedo a Firebase y leo los datos registrados (que deberían haberse escrito ANTES desde el NodeMCU), detecta los cambios, y, si estos existen los refleja en la hoja de cálculo.

= = = = = = = = =