# data[].attributes.headline
SEMAFORO MEDIDOR DE RUIDO en las aulas, comedor... http://tinyurl.com/semaforoarduino

# data[].attributes.subject
SEMAFORO MEDIDOR DE RUIDO en las aulas, comedor... http://tinyurl.com/semaforoarduino

# data[].attributes.attachment_link.title
La aventura del saber. Pensamiento Computacional en Secundaria

# data[].attributes.attachment_link.description
202 centros de educación secundaria participan de la Escuela de Pensamiento Computacional. Se trata de un proyecto dirigido a formar profesores que,...

# data[].attributes.body
ENVIAR ALARMA POR WIFI MODULO ESP8266

# data[].attributes.attachment_link.title
Tutorial NodeMCU con Scratch para dar alarma por correo electrónico.

# data[].attributes.headline
Arduino cloud Temperatura, presión luz... ADAFRUIT

# data[].attributes.subject
Arduino cloud Temperatura, presión luz... ADAFRUIT

# data[].attributes.attachment_link.readable_text
En esta sección vamos a ver como enviar los valores de temperatura, humedad, presión atmosférica y luminosidad leídos por los sensores de la primero al Arduino IoT Cloud y posteriormente al A dafruit IoT Cloud utilizando para este último la librería y el Adafruit IO REST API (v2.0.0) .

También utilizaremos el Adafruit 1.44″ Color TFT LCD Display con MicroSD-ST7735R para visualizar los valores que estamos leyendo en la MKR ENV SHIELD y de esta manera verificar que son los mismos valores que estamos enviando y visualizando en el Cloud.

El circuito que montaremos quedará de la siguiente manera:

ARDUINO IOT CLOUD

Seguiremos los siguientes pasos:

Paso 1: Ir al Arduino IoT Cloud: https://create.arduino.cc/iot/things

Paso 2: Pulsar el botón "NEW THING".

Paso 5: Conectar la placa MKR WiFi 1010 al ordenador mediante un cable micro USB.

Paso 6: Una vez detectada la placa le pondremos un nombre para identificarla.

Paso 7: El siguiente paso configurará el Crypto Chip de la placa.

Si todo ha ido bien ya tendremos nuestra placa MKR WiFi 1010 habilitada para utilizarla en el Arduino IoT Cloud .

Paso 9: Crearemos 4 propiedades: TEMPERATURE, HUMIDITY, PRESSURE y LIGHT_INTENSITY que se actualizarán cada 2s y serán solo de lectura.

Paso 10: Si pulsamos el botón "EDIT CODE" podemos ver el sketch y los ficheros que se han generado. Solo faltará completar la programación y añadir en el fichero arduino_secrets.h los valores SECRET_SSID y SECRET_PASS de nuestra WiFi.

El sketch completo lo podeis descargar del siguiente repositorio:
https://github.com/avilmaru/iot_arduino_adafruit/tree/master/readsensors_sendtoarduino_iotcloud
NOTA: Recordad que que teneis que cambiar los siguientes valores por los vuestros:

thingProperties.h

const char THING_ID[] = "xxxxxx-cxxx-xxxx-xxxx-xxxxxxxx";

arduino_secrets.h

#define SECRET_SSID "XXX"
#define SECRET_PASS "YYY"

Paso 11: Cargar el sketch en la placa y ver como cada 2s los valores leídos por la son enviados al Arduino IoT Cloud :

ADAFRUIT IOT CLOUD
https://learn.adafruit.com/welcome-to-adafruit-io/getting-started-with-adafruit-io https://io.adafruit.com/api/docs/
Seguiremos los siguientes pasos:

Paso 1: Ir al Adafruit IoT Cloud: https://io.adafruit.com/
https://learn.adafruit.com/adafruit-io-basics-feeds/overview
Paso 3: Crearemos un " " para poder visualizar los datos de los " " anteriores. En nuestro caso crearemos 4 bloques (el equivalente a los en Arduino IoT Cloud ) de tipo " indicador" que llamaremos: TEMPERATURE, HUMIDITY, PRESSURE y LIGHT_INTENSITY que estarán asociados a los 4 " que hemos creado en el apartado anterior.
https://learn.adafruit.com/adafruit-io-basics-dashboards/creating-a-dashboard
Si miramos la documentación del API vemos que para enviar la información necesitamos hacer la siguiente llamada:

... y generar un con los datos con la siguiente estructura:

{
 "location": {

   "lat": 0,
   "lon": 0,
   "ele": 0
 },
 "feeds": [
   {
     "key": "string",
     "value": "string"
   }
 ],
 "created_at": "string"
}

https://arduinojson.org/v6/doc/serialization/
Paso 5: Finalmente cargaremos en la placa el sketch del siguiente repositorio y comprobaremos que los valores leídos por la son enviados al Adafruit IoT Cloud cada 7s:
https://github.com/avilmaru/iot_arduino_adafruit/tree/master/readsensors_sendtoadafruit_iotcloud
NOTA: Recordad que que teneis que cambiar los siguientes valores por los vuestros:

arduino_secrets.h

#define SECRET_SSID "XXX"
#define SECRET_PASS "YYY"
#define IO_USERNAME  "ZZZZ"
#define IO_KEY       "XXXX"

ARDUINO IOT CLOUD

Seguiremos los siguientes pasos:

Paso 1: Añadiremos una nueva propiedad a las ya existentes que llamaremos ON_OFF. Será de tipo "ON/OFF (boolean)" de lectura/escritura y se actualizará solo cuando su valor cambie .

Paso 2: Si pulsamos el botón "EDIT CODE" podemos ver el sketch y los ficheros que se han generado. Solo faltará completar la programación y añadir en el fichero arduino_secrets.h los valores SECRET_SSID y SECRET_PASS de nuestra WiFi.

El sketch completo lo podeis descargar del siguiente repositorio:
https://github.com/avilmaru/iot_arduino_adafruit/tree/master/onoff_getfromarduino_iotcloud
NOTA: He suprimido las variables de entorno del tutorial anterior para dejar únicamente el código referente a esta nueva propiedad.

NOTA: Recordad que que teneis que cambiar los siguientes valores por los vuestros:

thingProperties.h

const char THING_ID[] = "xxxxxx-cxxx-xxxx-xxxx-xxxxxxxx";

arduino_secrets.h

#define SECRET_SSID "XXX"
#define SECRET_PASS "YYY"

Paso 3: Cargar el sketch en la placa y ver cómo al variar el estado del botón "ON/OFF" provoca que aparezca el texto "ON" en color verde (si es el estado del botón es "ON") o el texto "OFF" en color rojo (si el estado del botón es "OFF") en la .

ADAFRUIT IOT CLOUD

Los pasos a seguir serán:

Paso 2: Modificaremos la propiedad " Feed History " para que no guarde el historial de valores de este feed ya que para este ejemplo no es necesario. Para ello pondremos a "OFF" esta propiedad.

Si miramos la documentación del API vemos que para coger esta información necesitamos hacer la siguiente llamada:

{
 "id": "string",
 "value": "string",
 "feed_id": 0,
 "group_id": 0,
 "expiration": "string",
 "lat": 0,
 "lon": 0,
 "ele": 0,
 "completed_at": "string",
 "created_at": "string",
 "updated_at": "string",
 "created_epoch": 0
}
https://arduinojson.org/v6/doc/deserialization/
Paso 5: Finalmente cargaremos en la placa el sketch del siguiente repositorio y comprobaremos que al variar el estado del botón "ON/OFF" provoca que aparezca el texto "ON" en color verde (si es el estado del botón es "ON") o el texto "OFF" en color rojo (si el estado del botón es "OFF") en la .
https://github.com/avilmaru/iot_arduino_adafruit/tree/master/onoff_getfromadafruit_iotcloud
NOTA: Recordad que que teneis que cambiar los siguientes valores por los vuestros:

arduino_secrets.h

#define SECRET_SSID "XXX"
#define SECRET_PASS "YYY"
#define IO_USERNAME  "ZZZZ"
#define IO_KEY       "XXXX"

# data[].attributes.attachment_link.title
Internet of Things: Arduino/Adafruit IoT Cloud - Mecatrónica Lab

# data[].attributes.attachment_link.description
INTRODUCCIÓN En este tutorial vamos a ver como enviar los valores de temperatura, humedad, presión atmosférica y luminosidad leídos por los sensores de la MKR ENV SHIELD al Arduino IoT Cloud y al Adafruit IoT Cloud. Por otro lado también veremos cómo mostrar el mensaje "ON" (en color verde) y "OFF" (en color rojo) en ...

# data[].attributes.attachment_link.readable_text
En este tutorial vamos a crear un enchufe de corriente "inteligente" WiFi para poder activar o desactivar la luz de una lámpara remotamente mediante el uso de comandos de voz utilizando el asistente de voz de Google.

Para realizar este proyecto vamos a utilizar el servicio Web IFTTT (" IF This, Then T hat", lo que traducido al español significaría "Si Esto, Entonces Aquello").

Este servicio nos permite crear/programar acciones entre diferentes aplicaciones. En nuestro caso vincularemos el asistente de voz de Google con el Adafruit IO Cloud.

El funcionamiento será el siguiente:

Utilizando el asistente de voz de Google y al decir el comando de voz "encender la luz o encender luz" se grabará en un " " del Adafruit IO Cloud el valor "ON" y cuando digamos "apagar la luz o apagar luz" se grabará el valor "OFF".

Estos valores a su vez serán leídos continuamente mediante una placa MKR WiFi 1010 de . Si el valor leído es "ON" se activará un relé que hará que se encienda la luz de lámpara (se cerrará el circuito) por el contrario si el valor es "OFF" se apagará la luz de la lámpara (se abrirá el circuito).

Arduino MKR WiFi 1010.

Arduino MKR Connector Carrier .

KS0011 Keyestudio 5V Relé o equivalente.

2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para dos pilas 18650 con cable alimentación.

Cable conversor de 4 pines hembra de conector Grove a Dupont.

Cables de electricidad (fase, neutro, tierra).

Regletas de conexión eléctrica.

Caja de conexión eléctrica.

Clavija eléctrica macho 220 VCA.

Clavija eléctrica hembra 220 VCA.

Madera de 3 mm de espesor.

Separadores y tornillería de Métrica 3.

Paso 1: Ir al Adafruit IO Cloud: https://io.adafruit.com/

Paso 2: Crearemos un " llamado "ON_OFF" dentro del " DEFAULT (grupo que existe por defecto).
https://learn.adafruit.com/adafruit-io-basics-feeds/overview
Paso 3: Modificaremos la propiedad " Feed History " para que no guarde el historial de valores de este ya que para este proyecto no es necesario. Para ello pondremos a "OFF" esta propiedad.

Paso 2: Crearemos dos acciones, una para apagar la luz y otra para encender la luz.

Para crear el servicio que hará que se apague la luz seguiremos los siguientes pasos que se muestran en las siguientes imágenes:

Para crear el servicio que hará que se encienda la luz realizaremos los mismos pasos pero cambiando los siguientes parámetros de las siguientes pantallas:

El circuito que montaremos será como el que se muestra en la siguiente imagen:

El circuito estará formado por los siguientes elementos:

Arduino MKR Connector Carrier .

KS0011 Keyestudio 5V relé o equivalente.

2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para dos pilas 18650 con cable alimentación.

Cable conversor de 4 pines hembra de conector Grove a Dupont.

Alimentaremos la MKR Connector Carrier con 2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V) a través de los pines de la regleta de conexión etiquetados como GND y VIN. Por otro lado conectaremos el conector etiquetado como D0 al módulo relé de 5V mediante un cable conversor de 4 pines hembra de conector Grove a Dupont (solo necesitaremos 3 de los 4 cables).

El conector D0 tiene un conector Grove estándar de cuatro pines y por normal general los cables que se conectan a estos conectores tienen cuatro colores estándar:

pin 1 - Amarillo (salida/entrada digital primaria)

pin 2 - Blanco (salida/entrada digital secundaria)

pin 3 - Rojo - VCC

pin 4 - Negro - GND

En nuestro caso la conexión entre el conector D0 de la MKR Connector Carrie r y el Módulo Relé de 5V será de la siguiente manera:

NOTA: El Arduino MKR WiFi 1010 solo suministra 3,3V en las salida de sus pines por eso necesitamos la MKR Connector Carrier la cual proporcionará los 5V necesarios en todos los pines de salida de sus conectores (además de los 5V y GND en los pines de alimentación). Estos 5V son necesarios para el correcto funcionamiento del módulo Relé de 5V.

Una vez visto el circuito que tenemos que montar fijaremos todos estos componentes a un soporte de madera de 3 mm de espesor para finalmente introducir todo el conjunto en la caja de conexión eléctrica.

NOTA: Para fijar la MKR Connector Carrier y el módulo Relé de 5V al soporte de madera utilizaremos separadores hexagonales de 20 mm de M3 para de esta manera dejar espacio en la parte inferior de estos módulos para el paso de los cables.

Utilizaremos del módulo Relé de 5V los pines N.C (normalmente cerrado) y los conectaremos a la regleta de conexión de la siguiente manera:

Ahora solo faltará conectar en la regleta de conexión los cables de corriente (fase, neutro y tierra) y poner todo el conjunto dentro de la caja de conexión eléctrica:

Como se comentó al principio del tutorial utilizaremos una placa MKR WiFi 1010 de para leer el valor del del Adafruit IO Cloud . Si el valor leído es "ON" se activará un relé que hará que se encienda la luz de lámpara (se cerrará el circuito) por el contrario si el valor es "OFF" se apagará la luz de la lámpara (se abrirá el circuito).

Para recoger el valor del " " que indica si se tiene que apagar ("OFF") o encender la luz ( "ON") utilizaremos la opción de coger el último valor de un feed del Adafruit IO REST API (v2.0.0) utilizando la librería

Si miramos la documentación del API vemos que para coger esta información necesitamos hacer la siguiente llamada:

{
  "id": "string",
  "value": "string",
  "feed_id": 0,
  "group_id": 0,
  "expiration": "string",
  "lat": 0,
  "lon": 0,
  "ele": 0,
  "completed_at": "string",
  "created_at": "string",
  "updated_at": "string",
  "created_epoch": 0
}
https://arduinojson.org/v6/doc/deserialization/
Finalmente cargaremos en la placa el sketch del siguiente repositorio y comprobaremos que al variar el valor del ("ON/OFF") utilizando el asistente de voz de Google provoca que el relé se active o desactive provocando el apagado / encendido de la lámpara:
https://github.com/avilmaru/iot_arduino_adafruit/tree/master/onoff_getfromadafruit_iotcloud
NOTA: Recordad que que teneis que cambiar los siguientes valores por los vuestros:

arduino_secrets.h

#define SECRET_SSID "XXX"
#define SECRET_PASS "YYY"
#define IO_USERNAME  "ZZZZ"
#define IO_KEY "XXXX"

# data[].attributes.attachment_link.title
Enchufe inteligente WiFi - Mecatrónica Lab

# data[].attributes.attachment_link.description
INTRODUCCIÓN En este tutorial vamos a crear un enchufe de corriente "inteligente" WiFi para poder activar o desactivar la luz de una lámpara remotamente mediante el uso de comandos de voz utilizando el asistente de voz de Google. Para realizar este proyecto vamos a utilizar el servicio Web IFTTT ("IF This, Then That", lo que ...

# data[].attributes.attachment_link.readable_text
En este proyecto vamos a utilizar la IMU ( Unidad de Medición Inercial) presente en la placa Arduino Nano 33 BLE Sense para controlar un robot. La idea es que en función de la inclinación que le demos a la placa generemos los movimientos correspondientes para controlar el robot.

El robot estará formado por una placa Arduino MKR WiFi 1010 acoplada a la placa Arduino MKR Motor Carrier .

La comunicación entre el Arduino Nano 33 BLE Sense y el robot se realizará mediante Bluetooth Low Energy .

La placa Arduino Nano 33 BLE Sense actuará como nuestro mando a distancia y por tanto representará el dispositivo central o máster en la comunicación BLE ( Bluetooth Low Energy).

Por otra parte el Arduino MKR WiFi 1010 acoplado al la placa Arduino MKR Motor Carrier actuará como receptor y representará el dispositivo periférico o esclavo en la comunicación BLE.

El funcionamiento será el siguiente:

El dispositivo central se conectará al dispositivo periférico buscando la característica del servicio especificado.

Una vez establecida la conexión, el dispositivo central enviará (escribirá) los ángulos de inclinación detectados por la IMU del Arduino Nano 33 BLE Sens e (será una cadena de texto tipo: " ánguloRotaciónY,ánguloRotaciónX" ) en la característica del servicio del dispositivo periférico que a su vez traducirá estos ángulos en movimientos que harán mover al robot.

Motores y ruedas

Electrónica

Arduino Nano 33 BLE Sense.

Arduino MKR WiFi 1010.

Arduino MKR Motor Carrier.

4 cables de tipo Dupont macho - macho de 20 cm de longitud.

Mini protoboard de 170 puntos de color blanco.

Alimentación

2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para dos pilas 18650 con cable alimentación.

Conector Hembra JST PH 2.54 mm.

Portapilas 4 x AAA 6v con cable alimentación, tapa e interruptor.

El control remoto lo crearemos acoplando la placa Arduino Nano 33 BLE Sense a una mini protoboard de 170 puntos que a su vez engancharemos al portapilas gracias a la cinta adhesiva que tiene en su base. En la terminación de los cables de alimentación del portapilas hemos puestos dos conectores macho de tipo Dupont para poder alimentar de una manera sencilla la placa a través de los pines GND y VIN.

Los movimientos quedarán definidos en función de la inclinación que le demos al control remoto.

En la siguiente tabla se muestra la relación de los ángulos de los ejes X e Y (inclinación del control remoto) con los movimientos que se generan en el robot:

La placa Arduino Nano 33 BLE Sense tiene un LED RGB incorporado y lo utilizaremos para indicar distintos los siguientes estados:

Color rojo: No se ha establecido todavía la conexión con el robot.

Color azul: Se ha establecido la conexión con el robot pero no se están enviando todavía datos.

Color verde: Se ha establecido la conexión con el robot y se están enviado los datos de orientación pitch y roll.

Opcionalmente mediante dos gomas elásticas podemos acoplar el control remoto en la mano tal y como se muestra en la siguiente imagen y de esta manera controlar el robot:

El robot estará formado por la placa Arduino MKR WiFi 1010 acoplada al la placa Arduino MKR Motor Carrier que estará fijada a un chasis de aluminio (chasis que es un clon del utilizado en el robot de ) . Todo el conjunto será movido por dos motores con reductora DC 3V - 6V 1:48 a los cuales soldaremos 2 cables de tipo Dupont macho - macho de 20 cm de longitud.

Tendremos que hacer 4 agujeros de 3 mm de diámetro en el chasis de aluminio del robot para poder poner 4 separadores hexagonales metálicos hembra - hembra de 20 mm de M3 (métrica 3) que servirán para fijar la placa Arduino MKR Motor Carrier al chasis del robot.

Todo el conjunto lo alimentaremos con 2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V) que estarán albergadas en un portapilas con cable de alimentación al que hemos añadido un conector hembra JST PH 2.54 mm. El portapilas quedará sujeto entre los 4 separadores hexagonales.

NOTA: Alternativamente también se puede alimentar la placa Arduino MKR Motor Carrier mediante las regletas azules de conexión y de esta manera no sería necesario disponer del conector hembra JST PH 2.54 mm en el portapilas pero en mi caso he optado por alimentarlo a través del conector de batería que tiene la propia placa porque resulta más fácil a la hora de quitar/poner la batería.

En la siguientes imágenes podemos ver todo el proceso comentado anteriormente:

La IMU de la placa Arduino Nano 33 BLE Sense está formada por el chip que posee 9 grados de libertad (9DOF), es decir, este chip es capaz de medir 9 magnitudes independientes correspondientes a:

En nuestro caso para controlar el robot nos interesa obtener la rotación del eje X ( Roll) y la rotación del eje Y ( Pitch) prescindiendo del eje Z ( Yaw).

¿Pitch, Roll, Yaw? pero esto ¿qué es?... existe mucha literatura al respecto pero os recomiendo que visiteis el blog de Luis Llamas donde tiene una entrada donde explica claramente los conceptos básicos de este tipo de dispositivos y así os quedará todo mucho más claro:
https://www.luisllamas.es/medir-la-inclinacion-imu-arduino-filtro-complementario/
Como bien se explica en el post anterior los acelerómetros no son fiables a corto plazo y los giroscopios tienen deriva (drift) a medio plazo con lo que la mejor manera de obtener los ángulos que nos interesan es combinar los mejor de ambos sensores y eso se realiza mediante la utilización del denominado " filtro complementario" el cual se comporta como un filtro de paso alto para la señal del giroscopio y un filtro de paso bajo para la señal del acelerómetro para hacer de esta manera que la señal del giroscopio mande a corto plazo y la señal de del acelerómetro a medio y largo plazo.

El filtro complementario obedece a la siguiente fórmula:

El problema es que una vez implementado el sketch con el filtro complementario he visto que la variación de los ángulos no se produce de forma inmediata y si por ejemplo se pasa rápidamente de una inclinación de 0º a 90º este incremento se hace de manera progresiva (tarda del orden de segundos) y por consecuencia no resulta útil en nuestro caso para controlar el robot puesto que queremos una respuesta más inmediata.

Por tanto una vez visto que la utilización del filtro complementario no era válido para el propósito de este proyecto he optado por utilizar solo la señal del acelerómetro para determinar la inclinación de la placa que a pesar que éstos se ven influenciados por los movimientos del sensor y el ruido para nuestro propósito será más que suficiente.

Por tanto las fórmulas que finalmente usaremos para obtener el Pitch y el Roll serán las siguientes:

NOTA: Estos ángulo irán varían de -90º a + 90º.

A nivel de código utilizaremos las siguientes instrucciones para representar las fórmulas anteriores:

pitch = atan2(accelX, sqrt(accelY*accelY + accelZ*accelZ));
roll =  atan2(accelY, sqrt(accelX*accelX + accelZ*accelZ));

Utilizaremos la librería de Arduino LSM9DS3 para obtener la información del acelerómetro, giroscopio y magnetómetro.
https://www.arduino.cc/en/Reference/ArduinoLSM9DS1
Los rangos que se pueden ajustar son:

La librería de Arduino LSM9DS3 nos viene con estas inicializaciones por defecto:

Pero tenemos el problema que la librería nos proporciona los valores en el sistema internacional, es decir, los valores del acelerómetros los expresa en en G's, el giroscopio en °/sec y el magnetómetro en uT y a nosotros nos interesan los valores en bruto (RAW) para poder utilizarlo en las fórmulas que hemos visto anteriormente. Por ello tendremos que modificar ligeramente la librería para que nos devuelva los valores en bruto.

Para ello tendremos que comentar el trozo de código que utiliza la librería para expresar los valores de los sensores al sistema internacional y dejar el código para que exprese los valores en bruto. Realizaremos los siguientes cambios en fichero LSM9DS1.cpp de la librería:

nt LSM9DS1Class::readAcceleration(float& x, float& y, float& z)
{
  int16_t data[3];

  if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_XL, (uint8_t*)data, sizeof(data))) {
    x = NAN;
    y = NAN;
    z = NAN;

    return 0;
  }
/* Esta parte es la que hay que comentar *//*
  x = data[0] * 4.0 / 32768.0;
  y = data[1] * 4.0 / 32768.0;
  z = data[2] * 4.0 / 32768.0;
*/

/* Esta parte es la que hay que añadir */
  x = data[0];
  y = data[1];
  z = data[2];

  return 1;
}

int LSM9DS1Class::readGyroscope(float& x, float& y, float& z)
{
  int16_t data[3];

  if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_G, (uint8_t*)data, sizeof(data))) {
    x = NAN;
    y = NAN;
    z = NAN;

    return 0;
  }
/* Esta parte es la que hay que comentar *//*
  x = data[0] * 2000.0 / 32768.0;
  y = data[1] * 2000.0 / 32768.0;
  z = data[2] * 2000.0 / 32768.0;
*/

/* Esta parte es la que hay que añadir */
  x = data[0];
  y = data[1];
  z = data[2];

  return 1;
}


int LSM9DS1Class::readMagneticField(float& x, float& y, float& z)
{
  int16_t data[3];

  if (!readRegisters(LSM9DS1_ADDRESS_M, LSM9DS1_OUT_X_L_M, (uint8_t*)data, sizeof(data))) {
    x = NAN;
    y = NAN;
    z = NAN;

    return 0;
  }

/* Esta parte es la que hay que comentar *//*
  x = data[0] * 4.0 * 100.0 / 32768.0;
  y = data[1] * 4.0 * 100.0 / 32768.0;
  z = data[2] * 4.0 * 100.0 / 32768.0;
*/

/* Esta parte es la que hay que añadir */
  x = data[0];
  y = data[1];
  z = data[2];

  return 1;
}

NOTA: Aunque solo vamos a utilizar los valores del acelerómetro también hemos dejado los valores en bruto del giroscopio y el el magnetómetro para mantener la coherencia.
Skecth a cargar en el dispositivo central Arduino Nano 33 BLE Sense: https://github.com/avilmaru/robotRCporAcelerometro/blob/master/central/central.ino Skecth a cargar en el dispositivo periférico Arduino MKR WiFi 1010: https://github.com/avilmaru/robotRCporAcelerometro/blob/master/peripheral/peripheral.ino

# data[].attributes.attachment_link.title
Robot controlado por acelerómetro - Mecatrónica Lab

# data[].attributes.attachment_link.description
INTRODUCCIÓN En este proyecto vamos a utilizar la IMU (Unidad de Medición Inercial) presente en la placa Arduino Nano 33 BLE Sense para controlar un robot. La idea es que en función de la inclinación que le demos a la placa generemos los movimientos correspondientes para controlar el robot.

# data[].attributes.attachment_link.description
Índice de contenido Introducción Listado de componentes Maderas del chasis Montaje de componentes Conexionado Montaje final Programación del robot

# data[].attributes.attachment_link.readable_text
Sí, ya se que el nombre no es muy original y tampoco digamos que queda muy "chic" para un robot pero es lo que tiene preguntarle a tu hijo de 6 años como quieres que se llame el robot...la próxima vez me callo 🙂

El robot que os presento se me ocurrió después de que "Papá Noel" trajera a mi hijo un juguete cuyo juego se basaba en un sensor de movimiento y pensé ... ¿porqué no trasladar este concepto a un robot?.

La idea es la siguiente: construir un robot de dos ruedas motrices el cual tendrá un sensor de movimiento (PIR) y un sensor de proximidad de ultrasonidos (entre otros elementos) cuyo juego consistirá en intentar pulsar el botón rojo que se encuentra en la parte superior sin ser detectado.

El robot tendrá dos modos de operación: modo juego (el comentado anteriormente) y modo automático. Veamos qué características tendrá cada modo:
Modo juego:

Para entrar en modo juego se deberá mantener pulsado el botón de la parte superior entre 1 y 3 segundos (no más de 3 segundos).

Se iniciará una secuencia de inicio de juego con sonido donde el robot girará a izquierda y a derecha y se moverá hacia adelante durante unos segundos. Una vez que se pare se iniciará una cuenta atrás para señalar que el juego está a punto de comenzar.

El robot tendrá un LED que aleatoriamente se pondrá de color rojo, verde o azul durante un tiempo determinado.

Si se pone el LED de color verde te podrás acercar hacia el robot e intentar apretar el botón rojo antes de que cambie de color. Cuando está en verde nunca podrás ser detectado. Si logras apretar el botón rojo mientras se encuentra el color verde activo "habrás ganado" y el robot realizará una secuencia de fin de juego con sonido.

Si se pone el LED de color rojo tendrás que quedarte quieto porque ahora el robot sí que te podrá detectar. Si has sido detectado el robot emitirá una señal y empezará a moverse hacia adelante para no ser atrapado durante un periodo de tiempo. Si has sido detectado más de 3 veces mientras el color del LED está en rojo "habrás perdido" y el robot emitirá una secuencia de sonido de "fin de juego".

Cuando el LED se ponga de color azul significará "precaución" ya que en breve el LED se pondrá en verde o en rojo, por tanto o bien decides quedarte quieto o por el contrario puedes decidir seguir acercándote al robot con el riesgo de que se pueda poner el LED en rojo y ser detectado.

Modo automático:

Para entrar en modo automático se deberá mantener pulsado el botón de la parte superior más de 3 segundos.

El robot correrá indefinidamente hasta que se apriete nuevamente el botón rojo.

En ambos modos el sensor de ultrasonidos hará que cuando el robot se encuentre con un obstáculo no choque y lo esquive.

El chasis del robot constará de 4 partes: una central, una superior, una frontal y una inferior que iremos construyendo a lo largo de este tutorial el cual consta de más de 100 imágenes para ilustrar lo mejor posible todo el proceso.

Terminaremos realizando el montaje final uniendo cada una de las partes para finalizar con la programación del Arduino que será el "cerebro" de nuestro robot.

Aquí os dejo el vídeo demostrativo:

# data[].attributes.attachment_link.description
Sí, ya se que el nombre no es muy original y tampoco digamos que queda muy "chic" para un robot pero es lo que tiene preguntarle a tu hijo de 6 años como quieres que se llame el robot...la próxima vez me callo 🙂 El robot que os presento se me ocurrió después de que ...

# data[].attributes.attachment_link.readable_text
El objetivo de este tutorial es medir durante aproximadamente 9 horas la temperatura, humedad y presión atmosférica de dos habitaciones (la de matrimonio y la de mi hijo) para ver las variaciones que hay durante las noche de estos tres parámetros en cada habitación y posteriormente comparar los valores obtenidos entre ambas habitaciones.

Toda esta información la almacenaremos en una tarjeta microSD para posteriormente analizar los datos.

NOTA: Si quereis saber como enviar la información al Cloud podéis ver mi otro tutorial en el siguiente enlace: http://www.mecatronicalab.es/internet-of-things-arduino-adafruit-iot-cloud/

Arduino MKR WiFi 1010.

Arduino MKR Zero.

Arduino MKR ENV SHIELD.

Arduino MKR CONNECTOR CARRIER.

Sensor GROVE - Barometer Sensor (BMP280)

Sensor GROVE -Temperature&Humidity Sensor Pro (DHT22, AM2302)

3 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para pilas 18650 con cable de alimentación.

2 tarjetas micro SD.

Tanto la placa Arduino MKR Zero como la placa Arduino MKR WiFi 1010 están basadas en arquitecturas SAMD y podremos usar el RTC interno (reloj de tiempo real) para poder hacer un seguimiento de la hora en que hacemos las mediciones. La librería RTC nos permitirá usar y controlar este reloj interno en nuestras placas.

Para más información sobre la librería RTC:
https://www.arduino.cc/en/Reference/RTC

NOTA: Cada vez que la placa se enciende el RTC se reinicia y comenzará desde la fecha y hora que hayamos indicado en el sketch. Para mantener el tiempo y el RTC en funcionamiento, es necesario mantener la placa alimentada.

Tanto la MKR Zero como la MKR ENV dispone de una slot para poder poner una microSD. La librería SD nos permitirá gestionar la escritura en un archivo de texto plano de toda la información que vayamos leyendo de los sensores.

Para más información sobre la librería de SD:
https://www.arduino.cc/en/Reference/SD

HABITACIÓN 1

En la siguiente imagen podemos ver el circuito que montaremos en la habitación 1 para realizar las mediciones:

El circuito estará formado por los siguientes elementos:

Arduino MKR Zero.

Arduino MKR CONNECTOR CARRIER.

Sensor GROVE - Barometer Sensor (BMP280)

Sensor GROVE -Temperature&Humidity Sensor Pro (DHT22, AM2302)

2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para pilas 18650 con cable de alimentación.

El sensor Sensor GROVE - Barometer Sensor (BMP280) irá conectado al conector etiquetado en la placa MKR CONNECTOR CARRIER como TWI y el Sensor GROVE -Temperature&Humidity Sensor Pro (DHT22, AM2302) en el conector etiquetado como D0.

HABITACIÓN 2

En la siguiente imagen podemos ver el circuito que montaremos en la habitación 2 para realizar las mediciones:

El circuito estará formado por los siguientes elementos:

Arduino MKR WiFi 1010.

Arduino MKR ENV SHIELD.

1 pila Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para pilas 18650 con cable de alimentación.

Ahora solo faltará cargar en cada placa el sketch correspondiente teniendo en cuenta que debemos poner los valores de fecha y hora correctos para que el RTC (reloj interno) se inicialice con los valores de fecha y hora en los que queramos empezar a adquirir los datos. Recordad que para mantener el tiempo y el RTC en funcionamiento, es necesario mantener la placa alimentada. Por tanto cuando conectemos la batería a los distintos circuitos debemos tener presente que el reloj interno se iniciará con el valor que hayamos especificado en el sketch.

En nuestro caso concreto debemos especificar la fecha y hora en las siguientes constantes dentro de nuestro sketch:

/* Change these values to set the current initial time !!! */
const byte seconds = 0;
const byte minutes = 17;
const byte hours = 22;

/* Change these values to set the current initial date  !!!*/
const byte day = 4;
const byte month = 5;
const byte year = 19;

Con los valores de las constantes anteriores el reloj interno se iniciaría con el día 4/5/2019 a las 22:17:00.

Por último comentar que se grabarán los datos en la tarjeta microSD cada 10 minutos, de esta manera tendremos por cada hora 6 registros con la información ambiental que para nuestro propósito será más que suficiente. Si queréis variar este intervalo bastará con modificar la siguiente constante dentro del código:

const unsigned long postingInterval = 1000 * 60 * 10;

→ 1000 milisegundos = 1 segundo, si lo multiplicamos por 60 nos dará 1 minuto y si lo multiplicamos por 10 tendremos los 10 minutos.
Cargar el siguiente sketch para el circuito con la MKR Zero + MKR CONNECTOR CARRIER:
#include <SPI.h>
#include <SD.h>
#include <RTCZero.h>
#include <Wire.h>

#include "DHT.h"
#define DHTPIN 0
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

#include "Seeed_BMP280.h"
BMP280 bmp280;

float _temperature = 0;
float _humidity = 0;
float _pressure = 0;

unsigned long lastTime = 0;                   // last time you write to the SD, in milliseconds
const unsigned long postingInterval = 1000 * 60 * 10;   // delay between updates, in milliseconds


/* Change these values to set the current initial time !!! */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 22;

/* Change these values to set the current initial date  !!!*/
const byte day = 15;
const byte month = 5;
const byte year = 19;

const int chipSelect = SDCARD_SS_PIN;

File myFile;
RTCZero rtc;

void setup() {

  Serial.begin(9600);
  // Descomentar la siguiente linea solo para ver las trazas con el monitor serie. Si no dejarla comentada
  //while (!Serial);

  // initialize RTC
  rtc.begin();

  // Set date and time
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);


  Serial.println("Initializing DHT sensor...");
  dht.begin();
  Serial.println("DHT sensor initialized.");

  Serial.println("Initializing BMP280 sensor...");
  if(!bmp280.init()) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("BMP280 sensor initialized.");


  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card failed, or not present!");
    while (1);
  }
  Serial.println("SD card initialized.");

  // open file
  Serial.println("Opening file...");
  myFile = SD.open("data.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile)
  {
    Serial.println("file opened");

    myFile.println("DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)");
    myFile.println("-----------------  ---------------  -----------  -------------");

    Serial.println("DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)");
    Serial.println("-----------------  ---------------  -----------  -------------");

    // close the file:
    myFile.close();

  }


}

void loop() {

  // if 10 minutes have passed since your last connection,
  // then connect again and send data:
  if (millis() -  lastTime > postingInterval)
  {
     readSensors();
     saveInfoToSD();
     lastTime = millis();
  }

}

// Read sensors value: Temperature, Humidity, Atmospheric Pressure
void readSensors()
{
   // DHT Sensor
  _temperature = dht.readTemperature();
  _humidity  = dht.readHumidity();

  // BMP280 Sensor
  _pressure = bmp280.getPressure();  // Pa
  // 1 bar = 100.000 Pa = 1000 hPa = 100 kPa
  _pressure = (_pressure/100);      // hPa


}

// Write info to SD card
void saveInfoToSD()
{
  // open file
  myFile = SD.open("data.txt", FILE_WRITE);

  // if the file opened ok, write to it:
  if (myFile)
  {
    printDateTime();

    myFile.print(_temperature);
    Serial.print(_temperature);
    myFile.print("         ");
    Serial.print("         ");
    myFile.print(_humidity);
    Serial.print(_humidity);
    myFile.print("         ");
    Serial.print("         ");
    myFile.print(_pressure);
    Serial.print(_pressure);
    myFile.println("");
    Serial.println("");

    // close the file:
    myFile.close();

  }

}

void printDateTime()
{
  // Print date...
  print2digits(rtc.getDay());
  myFile.print("/");
  Serial.print("/");
  print2digits(rtc.getMonth());
  myFile.print("/");
  Serial.print("/");
  print2digits(rtc.getYear());
  myFile.print(" ");
  Serial.print(" ");

  // ...and time
  print2digits(rtc.getHours());
  myFile.print(":");
  Serial.print(":");
  print2digits(rtc.getMinutes());
  myFile.print(":");
  Serial.print(":");
  print2digits(rtc.getSeconds());

  myFile.print("       ");
  Serial.print("       ");

}


void print2digits(int number) {

  // print a 0 before if the number is < than 10
  if (number < 10)
  {
     myFile.print("0");
     Serial.print("0");
  }
  myFile.print(number);
  Serial.print(number);

}

Cargar el siguiente sketch para el circuito con la MKR WiFi 1010 + MKR ENV Shield:

#include <SPI.h>
#include <SD.h>
#include <Arduino_MKRENV.h>
#include <RTCZero.h>

float _temperature = 0;
float _humidity = 0;
float _pressure = 0;

unsigned long lastTime = 0;                   // last time you write to the SD, in milliseconds
const unsigned long postingInterval = 1000 * 60 * 10;   // delay between updates, in milliseconds


/* Change these values to set the current initial time !!! */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 22;

/* Change these values to set the current initial date  !!!*/
const byte day = 15;
const byte month = 5;
const byte year = 19;

const int chipSelect = 4;

File myFile;
RTCZero rtc;

void setup() {

  Serial.begin(9600);
  // Descomentar la siguiente linea solo para ver las trazas con el monitor serie. Si no dejarla comentada
  //while (!Serial);

  // initialize RTC
  rtc.begin();

  // Set date and time
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);

  Serial.print("Initializing MKR ENV shield...");
  if (!ENV.begin()) {
    Serial.println("Failed to initialize MKR ENV shield!");
    while (1);
  }
  Serial.println("MKR ENV shield initialized.");

  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card failed, or not present!");
    while (1);
  }
  Serial.println("SD card initialized.");

  // open file
  Serial.println("Opening file...");
  myFile = SD.open("data.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile)
  {
    Serial.println("file opened");

    myFile.println("DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)");
    myFile.println("-----------------  ---------------  -----------  -------------");

    Serial.println("DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)");
    Serial.println("-----------------  ---------------  -----------  -------------");

    // close the file:
    myFile.close();

  }


}

void loop() {

  // if 10 minutes have passed since your last connection,
  // then connect again and send data:
  if (millis() -  lastTime > postingInterval)
  {
     readSensors();
     saveInfoToSD();
     lastTime = millis();
  }

}

// Read sensors value: Temperature, Humidity, Atmospheric Pressure
void readSensors()
{
  _temperature = ENV.readTemperature();
  _humidity = ENV.readHumidity();
  _pressure = ENV.readPressure();  // kPa
   // 1 bar = 100.000 Pa = 1000 hPa = 100 kPa
  _pressure = (_pressure  * 10);      // hPa

}

// Write info to SD card
void saveInfoToSD()
{
  // open file
  myFile = SD.open("data.txt", FILE_WRITE);

  // if the file opened ok, write to it:
  if (myFile)
  {
    printDateTime();

    myFile.print(_temperature);
    Serial.print(_temperature);
    myFile.print("         ");
    Serial.print("         ");
    myFile.print(_humidity);
    Serial.print(_humidity);
    myFile.print("         ");
    Serial.print("         ");
    myFile.print(_pressure);
    Serial.print(_pressure);
    myFile.println("");
    Serial.println("");

    // close the file:
    myFile.close();

  }

}

void printDateTime()
{
  // Print date...
  print2digits(rtc.getDay());
  myFile.print("/");
  Serial.print("/");
  print2digits(rtc.getMonth());
  myFile.print("/");
  Serial.print("/");
  print2digits(rtc.getYear());
  myFile.print(" ");
  Serial.print(" ");

  // ...and time
  print2digits(rtc.getHours());
  myFile.print(":");
  Serial.print(":");
  print2digits(rtc.getMinutes());
  myFile.print(":");
  Serial.print(":");
  print2digits(rtc.getSeconds());

  myFile.print("       ");
  Serial.print("       ");

}


void print2digits(int number) {

  // print a 0 before if the number is < than 10
  if (number < 10)
  {
     myFile.print("0");
     Serial.print("0");
  }
  myFile.print(number);
  Serial.print(number);

}

Como se ve en los sketchs anteriores la información se ha grabado en un archivo de texto plano que hemos llamado: DATA.txt cuya muestra de datos recogidos se muestra a continuación:
HABITACIÓN 1 ( HABITACIÓN HIJO)
DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)
-----------------  ---------------  -----------  -------------
15/05/19 22:09:59       19.96         68.57         759.48
15/05/19 22:19:59       20.58         65.14         1007.08
15/05/19 22:29:59       20.77         65.20         1007.10
15/05/19 22:39:59       20.77         64.39         1007.20
15/05/19 22:49:59       20.75         63.89         1007.38
15/05/19 22:59:59       20.80         63.89         1007.38
15/05/19 23:09:59       20.82         63.58         1007.42
15/05/19 23:19:59       20.84         63.55         1007.44
15/05/19 23:29:59       20.78         63.66         1007.46
15/05/19 23:39:59       20.82         63.58         1007.39
15/05/19 23:49:59       20.82         63.25         1007.43
15/05/19 23:59:59       20.82         63.25         1007.31
16/05/19 00:09:59       20.80         63.02         1007.23
16/05/19 00:19:59       20.82         63.06         1007.24
16/05/19 00:29:59       20.78         62.95         1007.10
16/05/19 00:39:59       20.69         62.74         1007.13
16/05/19 00:49:59       20.75         62.61         1007.13
16/05/19 00:59:59       20.75         62.61         1007.31
16/05/19 01:09:59       20.71         62.62         1007.27
16/05/19 01:19:59       20.69         62.47         1007.18
16/05/19 01:29:59       20.71         62.42         1007.18
16/05/19 01:39:59       20.69         62.30         1007.09
16/05/19 01:49:59       20.73         62.26         1006.97
16/05/19 01:59:59       20.66         62.31         1006.83
16/05/19 02:09:59       20.66         62.13         1006.62
16/05/19 02:19:59       20.69         62.05         1006.43
16/05/19 02:29:59       20.69         62.14         1006.24
16/05/19 02:39:59       20.69         61.99         1006.25
16/05/19 02:49:59       20.66         61.89         1006.23
16/05/19 02:59:59       20.62         61.99         1006.19
16/05/19 03:09:59       20.64         61.70         1006.18
16/05/19 03:19:59       20.62         61.48         1006.07
16/05/19 03:29:59       20.58         61.32         1006.01
16/05/19 03:39:59       20.62         61.30         1005.87
16/05/19 03:49:59       20.49         61.15         1005.75
16/05/19 03:59:59       20.55         61.19         1005.72
16/05/19 04:09:59       20.56         61.06         1005.71
16/05/19 04:19:59       20.49         60.96         1005.76
16/05/19 04:29:59       20.53         60.73         1005.73
16/05/19 04:39:59       20.49         60.68         1005.63
16/05/19 04:49:59       20.53         60.67         1005.55
16/05/19 04:59:59       20.47         60.53         1005.43
16/05/19 05:09:59       20.51         60.34         1005.43
16/05/19 05:19:59       20.45         60.24         1005.41
16/05/19 05:29:59       20.44         60.22         1005.22
16/05/19 05:39:59       20.44         60.07         1005.11
16/05/19 05:49:59       20.36         60.50         1005.05
16/05/19 05:59:59       20.38         60.26         1004.96
16/05/19 06:09:59       20.38         60.07         1004.91
16/05/19 06:19:59       20.36         60.06         1004.98
16/05/19 06:29:59       20.34         60.10         1004.91
16/05/19 06:39:59       20.33         60.02         1004.93
16/05/19 06:49:59       20.33         60.22         1004.95
16/05/19 06:59:59       20.33         60.01         1004.97
HABITACIÓN 2 ( HABITACIÓN MATRIMONIO)
DateTime           Temperature(ºC)  Humidity(%)  Pressure(hPa)
-----------------  ---------------  -----------  -------------
15/05/19 22:10:00       22.20         59.70         1005.80
15/05/19 22:20:01       22.10         60.00         1005.78
15/05/19 22:30:01       22.00         59.50         1005.94
15/05/19 22:40:02       22.10         59.30         1006.06
15/05/19 22:50:03       22.00         59.10         1006.05
15/05/19 23:00:03       22.00         59.30         1006.08
15/05/19 23:10:04       22.00         59.00         1006.14
15/05/19 23:20:05       22.10         59.60         1006.17
15/05/19 23:30:05       22.10         59.20         1006.12
15/05/19 23:40:06       22.10         59.10         1006.09
15/05/19 23:50:07       22.10         59.60         1006.02
16/05/19 00:00:07       22.00         59.70         1005.95
16/05/19 00:10:08       22.00         59.90         1005.93
16/05/19 00:20:09       22.00         59.70         1005.79
16/05/19 00:30:09       22.00         59.80         1005.84
16/05/19 00:40:10       22.00         60.00         1005.83
16/05/19 00:50:11       22.00         59.80         1005.97
16/05/19 01:00:11       22.00         60.00         1005.96
16/05/19 01:10:12       22.00         60.00         1005.91
16/05/19 01:20:13       22.00         60.10         1005.89
16/05/19 01:30:13       22.00         60.10         1005.77
16/05/19 01:40:14       21.90         60.20         1005.66
16/05/19 01:50:15       21.90         60.20         1005.50
16/05/19 02:00:15       22.00         60.00         1005.30
16/05/19 02:10:16       21.90         60.00         1005.13
16/05/19 02:20:17       21.90         60.00         1004.98
16/05/19 02:30:17       21.90         60.00         1004.98
16/05/19 02:40:18       21.90         60.30         1004.92
16/05/19 02:50:19       21.90         60.00         1004.93
16/05/19 03:00:19       21.90         60.00         1004.92
16/05/19 03:10:20       21.90         60.00         1004.79
16/05/19 03:20:21       21.90         60.00         1004.68
16/05/19 03:30:21       21.90         59.80         1004.56
16/05/19 03:40:22       21.80         59.80         1004.42
16/05/19 03:50:23       21.80         59.50         1004.42
16/05/19 04:00:23       21.80         59.40         1004.43
16/05/19 04:10:24       21.80         59.40         1004.42
16/05/19 04:20:25       21.80         59.30         1004.42
16/05/19 04:30:25       21.80         59.20         1004.31
16/05/19 04:40:26       21.80         59.10         1004.20
16/05/19 04:50:27       21.80         59.10         1004.10
16/05/19 05:00:27       21.80         58.80         1004.12
16/05/19 05:10:28       21.80         58.80         1004.05
16/05/19 05:20:29       21.80         58.70         1003.94
16/05/19 05:30:29       21.70         58.90         1003.84
16/05/19 05:40:30       21.80         58.90         1003.77
16/05/19 05:50:31       21.70         58.50         1003.62
16/05/19 06:00:31       21.70         58.40         1003.61
16/05/19 06:10:32       21.70         58.20         1003.68
16/05/19 06:20:33       21.60         57.90         1003.62
16/05/19 06:30:33       21.70         58.00         1003.65
16/05/19 06:40:34       21.70         57.80         1003.65
16/05/19 06:50:35       21.70         57.70         1003.71

# data[].attributes.attachment_link.title
Data loggers: Temperatura, Humedad y presión atmosférica - Mecatrónica Lab

# data[].attributes.attachment_link.description
INTRODUCCIÓN El objetivo de este tutorial es medir durante aproximadamente 9 horas la temperatura, humedad y presión atmosférica de dos habitaciones (la de matrimonio y la de mi hijo) para ver las variaciones que hay durante las noche de estos tres parámetros en cada habitación y posteriormente comparar los valores obtenidos entre ambas habitaciones.

# data[].attributes.attachment_link.description
Índice de contenido Introducción Listado de componentes Montaje Control por App Control por acelerómetro

# data[].attributes.headline
Semaforo con barretra y detección de obstáculos

# data[].attributes.subject
Semaforo con barretra y detección de obstáculos

# data[].attributes.attachment_link.readable_text
En este proyecto vamos a crear un semáforo con barrera que permita la detección de obstáculos cuyo control se realizará con una placa Arduino UNO y su estructura estará formada con piezas de Makeblock.

La funcionalidad será la siguiente:

1. El semáforo irá cambiando automáticamente entre los distintos colores (verde, amarillo y rojo).

2. Cuando el semáforo se encuentre en color verde la barrera se encontrará levantada.

3. Cuando la barrera esté a punto de bajarse el semáforo empezará a parpadear en color amarillo acompañado de un aviso sonoro.

4. Cuando la barrera esté bajando el semáforo se pondrá en color amarillo fijo y entrará en funcionamiento el sensor de ultrasonidos para detectar un posible obstáculo. Si se detecta un objeto a menos de 20 cm la barrera se levantará automáticamente y el semáforo se pondrá de color verde. Si no se detecta ningún obstáculo la barrera permanecerá bajada y el semáforo en color rojo.

5. Únicamente se detectarán los obstáculos cuando la barrera esté bajando.

Para este proyecto he utilizado una placa basada en Arduino UNO de la marca Keyestudio con " pin header interface " que posee por cada pin una entrada de alimentación +5V y GND lo que nos facilitará y simplificará el interconexionado de los distintos elementos pero podéis utilizar como alternativa un Arduino UNO con un Arduino Sensor Shield. Con el fin de simplificar también el diseño he utilizado de la misma marca el módulo Keyestudio Traffic Light para la realización del semáforo.

Electrónica

Placa Keyestudio UNO con pin header interface (también se puede usar un Arduino UNO con un Arduino Sensor Shield).

Sensor de ultrasonidos HC-SR04.

Micro Servo 9g SG90 TowerPro.

Módulo Buzzer pasivo de Keyestudio.

Módulo Keyestudio Traffic Light.

11 cables de tipo Dupont hembra - hembra de 20 cm de longitud de diferentes colores.

4 cables de tipo Dupont macho - hembra de 20 cm de longitud de diferentes colores.

Conector de alimentación tipo jack de 5.5 x 2.1mm.

Alimentación

2 pilas Panasonic NCR18650B de Li-Ion recargables ( 3400 mAh, 3.7V).

Portapilas para dos pilas 18650 con cable alimentación.

Estructura

1 placa 7×9 B (Makeblock).

3 ángulos 3×3 (Makeblock).

1 viga 0824 176mm (Makeblock).

4 vigas recortables 80mm (Makeblock).

1 placa l1(Makeblock).

4 separadores de 20 mm de longitud para tornillería de M4 (métrica 4).

1 separador de 20 mm de longitud para tornillería de M3 (métrica 3).

5 tornillos de M3 de 8 o 10 mm de longitud.

3 tuercas para tornillos de M3.

7 tornillos Allen Planos de M4 de 14 mm de longitud (Makeblock).

7 tornillos Allen Planos de M4 de 8 mm de longitud (Makeblock).

9 tuercas para tornillos de M4.

Empezaremos por el montaje de la base que la realizaremos mediante la placa 7×9 B y 4 separadores de 20 mm de longitud de M4:

Previo al montaje del servomotor en la estructura necesitaremos aumentar el diámetro de los agujeros que por defecto trae el chasis del servo que son de M2 a M3 para de esta manera poder acoplar correctamente el servomotor en la estructura mediante tornillería de M3.

Una vez realizado el aumento del diámetro ya podemos acoplar el servomotor mediante dos tornillos y dos tuercas de M3 en las estructuras (ángulos 3×3) tal y como se muestra en la siguientes fotografías:

Ahora toca acoplar el módulo Keyestudio Traffic Light a una viga recortable de 80 mm mediante un tornillo y tuerca de M3 tal y como se muestra en las siguientes imágenes:

Seguidamente fijaremos la viga que contiene el semáforo a la viga 0824 de 176 mm mediante 2 tornillos Allen Planos de M4 de 14 mm de longitud junto con sus respectivas tuercas:

Para poder acoplar el sensor de ultrasonidos HC-SR04 a la estructura de ángulo 3 x 3 necesitaremos cortar una viga recortable de 80 mm para dejar una pieza de solo 3 agujeros tal y como se muestra en la siguiente imagen:

Por otro lado uniremos 4 conectores de cable dupont hembra - hembra mediante cinta aislante negra con el fin de facilitar el montaje:

Mediante 2 tornillos Allen Planos de M4 de 14 mm de longitud junto con sus respectivas tuercas aprisionaremos (lo justo para que quede bien sujeto) los 4 conectores dupont entre la estructura de ángulo 3 x 3 y la pieza recortada de la viga de 80 mm para finalmente conectar el sensor de ultrasonidos:

Para la creación de la barrera uniremos dos vigas recortables de 80 mm mediante un tornillo Allen Plano de M4 de 8mm de longitud con su respectiva tuerca:

Ahora ya tenemos todos los elementos necesarios para empezar el montaje final.

Para comenzar el montaje final fijaremos el servomotor a la base mediante un tornillo Allen Plano de M4 de 8 mm de longitud junto a una tuerca de M4 en la parte inferior:

Posteriormente fijaremos el sensor de ultrasonidos a la base mediante un tornillo Allen Plano de M4 de 14 mm de longitud junto a una tuerca de M4 en la parte inferior (fijaros que superponemos el ángulo 3 x 3 del servomotor con el ángulo 3 x 3 del sensor de ultrasonidos):

Ahora toca unir la viga 0824 de 176 mm que contiene el semáforo a la base a través de dos tornillos Allen Planos de M4 de 8 mm de longitud.

La barrera la uniremos con el servomotor con el tornillo y la pieza que se muestran en la siguiente imagen y que ya vienen junto al servomotor cuando lo compramos:

Ahora añadiremos un separador de 20 mm de longitud de M3 a la base para posteriormente acoplar el módulo Buzzer pasivo de Keyestudio. Los tornillos que usamos tanto para fijar el separador a la base así como el módulo al separador serán de unos 8 / 10 mm de longitud de M3:

Ahora uniremos 4 cables de tipo Dupont hembra - hembra de 20 cm de longitud de diferentes colores con 4 cables de tipo Dupont macho - hembra de 20 cm de longitud (haciendo coincidir los mismos colores) con el fin de aumentar la longitud y poder conectar el módulo Keyestudio Traffic Light (semáforo) con la placa de Arduino.

Posteriormente conectamos los cables al módulo y pasamos los cables por la ranura central de la viga 0824 de 176 mm que taparemos con la placa placa l1 (la cual fijaremos con dos tornillos Allen Planos de M4 de 14 mm de longitud junto a tuercas de M4) tal y como se muestra en la siguiente imágen:

En este punto solo nos faltará conectar todos los elementos a la placa Arduino y poner la alimentación.

Las conexiones a la placa Arduino UNO serán las siguientes:

Por último alimentaremos nuestra placa mediante 2 pilas recargables Panasonic NCR18650B de Li-Ion (las cuales nos darán muchas horas de juego) a través de un conector de alimentación tipo jack de 5.5 x 2.1mm que hemos conectado al portapilas.

Ahora ya solo nos faltará cargar el Sketch a nuestra placa.

El Sketch que debemos cargar en el Arduino con la funcionalidad descrita en la introducción de este tutorial es el que se muestra a continuación:

NOTA: Se ha utilizado la librería para el sensor de Ultrasonidos.

#include <Servo.h>
#include <NewPing.h>

///////////////////////////////
// Definición de pines
///////////////////////////////

// Sensor de ultrasonidos
int TRIGGER_PIN = 3;
int ECHO_PIN = 4;
int MAX_DISTANCIA = 200;

// Semáforo
int SEMAFORO_LUZROJA_PIN  = 10;
int SEMAFORO_LUZAMARILLA_PIN  = 11;
int SEMAFORO_LUZVERDE_PIN  = 12;


// Servo
int SERVO_PIN = 9;

// Buzzer
int BUZZER_PIN = 7;

///////////////////////////////

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCIA);
Servo servo;

bool saltarojo = false;
int velocidad_barrera = 20;

void setup()
{

  // Semáforo
  pinMode(SEMAFORO_LUZROJA_PIN, OUTPUT);
  pinMode(SEMAFORO_LUZVERDE_PIN, OUTPUT);
  pinMode(SEMAFORO_LUZAMARILLA_PIN, OUTPUT);

  // Buzzer
  pinMode (BUZZER_PIN, OUTPUT);

  // Servo
  servo.attach(SERVO_PIN);

  // Si el servo (la barrera) no se encuentra en su posicion inicial (levantada) la ponemos
  if (servo.read() != 180)
  {
     servo.write(180);
     delay(2000);          // Damos 2 seg para que de tiempo a volver a la posicion
  }

}

void loop()
{

  if (saltarojo == true)
    velocidad_barrera = 5;
  else
    velocidad_barrera = 20;

  saltarojo = false;

  // Semáforo en verde y subiendo barrera
  digitalWrite(SEMAFORO_LUZVERDE_PIN, HIGH);

  int posicion_barrera = servo.read();
  for (int j=posicion_barrera; j <= 180; j++)
  {
    servo.write(j);
    delay(velocidad_barrera);
  }

  // Dejar el semaforo en verde durante 5 segundos
  delay(5000);
  digitalWrite(SEMAFORO_LUZVERDE_PIN, LOW);


  // Semáforo en amarillo parpadeando 3 veces con sonido de aviso
  for(int i=0;i<3;i++)
  {
    digitalWrite(SEMAFORO_LUZAMARILLA_PIN, HIGH);

    // Aviso acústico
    for (int j = 0; j <250; j++)
    {
      digitalWrite(BUZZER_PIN, HIGH);
      delay (1);
      digitalWrite(BUZZER_PIN, LOW);
      delay (1);
    }

    digitalWrite(SEMAFORO_LUZAMARILLA_PIN, LOW);
    delay(500);

  }

  // Semáforo en amarillo fijo y bajando barrera
   digitalWrite(SEMAFORO_LUZAMARILLA_PIN, HIGH);

   for (int j = 180; j > 90 ; j--)
   {

      unsigned int distancia = sonar.ping_cm();
      if (distancia < 20 && distancia != NO_ECHO)
      {
        digitalWrite(SEMAFORO_LUZAMARILLA_PIN, LOW);
        saltarojo = true;
        break;
      }
      servo.write(j);
      delay(20);

   }


  // Dejar el semaforo en rojo durante 5 segundos
  if (saltarojo == false)
  {
    digitalWrite(SEMAFORO_LUZAMARILLA_PIN, LOW);
    digitalWrite(SEMAFORO_LUZROJA_PIN, HIGH);
    delay(5000);
    digitalWrite(SEMAFORO_LUZROJA_PIN, LOW);

  }

}

# data[].attributes.attachment_link.title
Semáforo con barrera y detección de obstáculos - Mecatrónica Lab

# data[].attributes.attachment_link.description
INTRODUCCIÓN En este proyecto vamos a crear un semáforo con barrera que permita la detección de obstáculos cuyo control se realizará con una placa Arduino UNO y su estructura estará formada con piezas de Makeblock. La funcionalidad será la siguiente: El semáforo irá cambiando automáticamente entre los distintos colores (verde, amarillo y rojo).

# data[].attributes.body
con visualino