BMP280 BME280

¡Hola!

Hoy quería contaros un poco sobre este sensor. Se trata de un circuito integrado que vamos a encontrar en modulitos, como se hace todo ahora, para tener el acceso fácil. Vamos a dejar primero una cosa clara para que no os equivoquéis como yo:

- BMP280: sensor de temperatura y presión
- BME280: sensor de temperatura, humedad y presión

Los más baratos los encontraréis a 3.3V, y la diferencia con los más caros es, no nos engañemos, que estos últimos llevan un pequeño regulador de tensión y puedes conectarlo a 5V. Y luego están los muy caros que llevan adaptadores de nivel de tensión para que el módulo no sufra, lo cual es lo más indicado.

Aunque sea de 3.3V, se puede conectar con un puerto digital con un máximo de 5V, mientras alimentas la patita Vcc con 3.3V. Pero no es lo más recomendable. Se puede usar un Arduino Pro Mini o Due, o algún otro modelo que funcione a 3.3V.

Aquí uno caro con reguladores de Adafruit

¿Qué puedes hacer con estos sensores?
Lo que he hecho yo ha sido poner un módulo BMP280 conectado a la Raspberry Pi 3. Cada cierto tiempo, 5 minutos, hago que se lean los valores del sensor, se guarden los valores en un archivo de datos (dos archivos de datos distintos, de hecho, uno del día y otro de las últimas 24 horas) y mediante un extenso código creo una gráfica, que luego puedo visualizar en el navegador mediante un poco de código php y html. Aquí un resultado:

A ver, la temperatura está demasiado elevada, esto es porque está en un lugar bastante cerrado junto a la raspberry que suelta algo de calor (el procesador se pasa el día sobre los 50ºC). Hay picos de temperatura cuando encendemos el ventilador, lo cual es muy curioso. La presión tampoco es correcta y ahí ya no sé qué decir, pero la evolución, comparada con un sensor calibrado no muy lejos de aquí, es la misma.

Este es el comienzo de un proyecto mayor que tengo entre manos y aunque el resultado no parezca muy correcto, ya he conseguido tener algunas pinceladas del software y de paso ver cómo se comporta la temperatura de la habitación ante determinados eventos.

Otras cosas que se pueden hacer: antes de la raspberry probé el módulo con Arduino y daba valores bastante realistas tanto de temperatura como de presión. Conociendo la presión atmosférica a nivel del mar y la que da el sensor, puedes aproximar la altitud a la que te encuentras. Esto viene en el código de ejemplo de Arduino IDE con la librería Adafruit_BMP280.

Y si te compras el BME280, puedes medir la humedad y ya tienes un sensor ambiental completo.

Estos módulos se comunican mediante I2C, lo cual requiere dos cables de comunicación. Por ejemplo en el Arduino Uno R3 se conecta:

  • Pin SDI del módulo al pin A4 (analógico 4) del Arduino
  • Pin SCK del módulo al pin A5 (analógico 5) del Arduino

Debido a que el módulo ya contiene unas resistencias de pull-up, no es necesario preocuparse de nada más, sólo requiere la alimentación (recordad, Vcc a 3.3V) y GND.

Para el resto de placas y microcontroladores (Raspberry, STM32, ...) hay librerías, así que su uso sigue siendo igual de sencillo.

He generalizado mucho para el BMP280, porque el BME no lo he probado, pero las librerías se encuentran fácilmente poniendo en Google por ejemplo: Arduino bme280 library.

Mucho ánimo y espero que se os ocurran cosas geniales con este módulo.

Arduino serial plotter

Como ya avisé el otro día por twitter, Arduino ha introducido en la nueva versión del IDE (1.6.6) una gráfica de los datos numéricos que entran por el puerto serie. Ahora os enseñaré cómo usarlo.

Materiales

En primer lugar, necesitáis la nueva versión de Arduino IDE 1.6.6, que se puede descargar desde aquí: su página oficial.

Lo siguiente que necesitáis es una placa Arduino que se pueda conectar a un puerto serie virtual (mediante USB), con el ordenador. Si no me equivoco, todas tienen esta funcionalidad, pero las más simples son las que llevan un conector USB integrado y nos ahorran cables y adaptadores.

¿Qué datos enviaremos por el puerto serie? Usaremos un pin del puerto analógico (A0) para leer un sensor, o un valor analógico, de 10 bits. El valor irá de 0 a 1024, en números enteros. Para saber qué lectura de tensión hay, se hace un cálculo simple.

En lugar de un sensor, yo he usado un potenciómetro como divisor de tensión para la primera prueba. Luego lo he reemplazado por un condensador de gran capacidad que conectaba y desconectaba a mano para ver su carga y descarga, en paralelo a una resistencia.

Y éso es todo, la conexión del circuito es así:

Programación

Quizás os pensáis que hay que escribir alguna función especial, pero no. El serial plotter coge absolutamente todo lo que le entra por el puerto serie, entonces lo único que hay que hacer es enviar el dato y ya se visualiza. El código es el siguiente:

/*  Graph
created 2006
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe and Scott Fitzgerald

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/Graph
*/

void setup() {
// initialize the serial communication:
Serial.begin(9600);
}

void loop() {
// send the value of analog input 0:
Serial.println(analogRead(A0));
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(2);
}

 

Aquí tengo los resultados que he obtenido de la carga y descarga de un condensador:

plotter

¿Pero en serio es útil?

Bueno, la cuestión es que podemos visualizar instantáneamente lo que hay en la entrada analógica, pero no está muy bien preparada gráficamente. Para empezar no hay un eje temporal, y la resolución que muestra el eje de amplitud, como veis, desde 0 a 5 voltios apenas pasando por 2.5, es mínima. Esto continua ocurriendo incluso con números grandes. Ni siquiera hay una cuadrícula o rejilla que ayude a medir a ojo.

Los nuevos datos que van apareciendo creo que tardan en desaparecer por la izquierda unos dos segundos, sin duda no es una gráfica para frecuencias "altas", ni variaciones pequeñas.

Por otro lado, se trata de un código en processing, es decir, podemos pasar del plotter que nos trae el IDE de arduino y programarnos el nuestro propio... Esto mejoraría mucho la interfaz y las posibilidades.

En definitiva, está curioso para visualizar rápidamente una señal lo suficientemente lenta y con amplitud adecuada, pero no podemos aproximar su valor muy bien, y de medir gráficamente la frecuencia ni hablar, porque no hay eje de tiempos (ni de número de muestra).

Dimmer LED con arduino y mando a distancia

Voy a contar un poco de historia, si queréis ir al grano buscad la negrita. Hace tiempo en el chalet teníamos una tira de LEDs blanca, muy luminosa, que conectábamos a la batería e iluminaba el patio, donde nos sentábamos a cenar. Como era muy luminosa, al salir del techo y sentarnos fuera no podíamos ver bien las estrellas, así que le hice un dimmer.

Ese dimmer ya está posteado por aquí.

El problema es que antes del verano hicimos unas obras y se cambió la tira LED por un bar de bombillas, también LED, de bajo consumo y a 12 voltios. Se podían controlar igual, pero mi sistema necesitaba una mejora. Tenía que ser doble, y tenía que manejarse a distancia.

Así que revisé el material que tenía por casa y tuve una idea con el siguiente material: un arduino pro mini, unos MOSFET viejos, un sensor de infrarrojos y un mando a distancia.

De estos componentes ya he hablado en otras ocasiones, si queréis conocer las características y funcionamiento:

Si no tenéis un Pro Mini no os preocupéis, podéis usar otra placa distinta como un UNO, o un Nano.

El circuito es más simple que el mecanismo de un botijo. En primer lugar se regula la tensión con un 7805 para no quemar el arduino conectándolo directamente a los 12 voltios de la batería. Concretamente el Mini puede funcionar tanto a 5 como a 3.3 voltios.

Lo siguiente es conectar dos salidas PWM del arduino a los MOSFET. Para asegurar la conmutación, se suelen poner resistencias de 1 Megaohmio a masa en la puerta. Para hacer más simple la conexión, se pueden usar unos terminales con tornillos.

Por otro lado, se conecta el sensor de infrarrojos a una pata cualquiera del arduino, la alimentación de 5V y a masa.

arduinodimmer

A mí me quedó la placa así:

arduinodimmer2

Para poder reutilizar el arduino cuando no se gaste (lógicamente el circuito está desmontado, lo tengo en casa otra vez desde verano), le puse unos conectores hembra, entonces el arduino va clavado ahí y se saca cuando quieras. Detrás a la derecha se ve el 7805, más al frente el sensor de infrarrojos y delante del todo ya los MOSFET.

Ahora falta la programación. Para ello hay que conocer los códigos que envía el mando, lo que se puede conseguir refiriéndonos otra vez al primer ejemplo con el mando de infrarrojos.

#include <IRremote.h>
// 1 = 16724175
// 2 = 16718055
// 3 = 16743045
// - = 16754775
// + = 16748655
// Mute = 16769565
// ON/OFF = 16753245
// Derecha = 16761405
// Izquierda = 16712445
// PlayPause = 16720605

#define m1 16724175
#define m2 16718055
#define m3 16743045
#define m4 16716015
#define m6 16734885
#define menos 16754775
#define mas 16748655
#define mute 16769565
#define ONOFF 16753245
#define derecha 16761405
#define izquierda 16712445
#define PlayPause 16720605

int IRpin = 9, PWM1 = 5, PWM2 = 6, PWM1_val = 0, PWM2_val = 0; //Asignamos pines para la entrada del sensor IR, y las dos salidas PWM para los MOSFET
//También dos variables que indiquen el valor del PWM que se va a asignar a cada pin
IRrecv irrecv(IRpin); //Se declara el objeto sensor de IR para el pin que hemos asignado antes
decode_results results; //Se crea una variable para guardar los datos decodificados

void setup()
{
//Serial.begin(9600); //No necesitamos conexión serial
pinMode(PWM1,OUTPUT); //Pines PWM como salida, que se inicien apagados
pinMode(PWM2,OUTPUT);
digitalWrite(PWM1, LOW);
digitalWrite(PWM2, LOW);
irrecv.enableIRIn(); // Inicializar el receptor

}

void loop()
{
if (irrecv.decode(&results)) //Si tenemos un resultado de la decodificación, vamos a ver la acción
{
if(results.value==ONOFF){ //Si se ha pulsado el boton ONOFF
if((PWM1_val > 0)||(PWM2_val > 0)){ //Si alguno de los PWM está en marcha
PWM1_val = 0; //Apagar los dos pines
PWM2_val = 0;
}
else{ //Y si los dos están apagados
PWM1_val = 255; //Encender ambos al máximo
PWM2_val = 255;
}
}

if(results.value==izquierda){ //Si se ha pulsado el botón izquierda
if(PWM1_val > 0) PWM1_val = 0; //Si el PWM1 está encendido, apagalo
else PWM1_val = 255; //Y si esta apagado ponlo al máximo
}

if(results.value==derecha){ //Si se ha pulsado el botón derecha
if(PWM2_val > 0) PWM2_val = 0; //Si el PWM2 está encendido, apagalo
else PWM2_val = 255; //Y si está apagado ponlo al máximo
}

if(results.value==m1) PWM1_val -= 15; //Si se ha pulsado el botón 1 del mando
//Resta 15 al valor del PWM1, disminuye la luminosidad
//Este valor se puede cambiar si deseas tener que pulsar más o menos veces el botón

if(results.value==m3) PWM1_val += 15; //Si se ha pulsado el botón 3 del mando
//Suma 15 al valor del PWM1, aumenta la luminosidad

if(results.value==m4) PWM2_val -= 15; //Lo mismo con el PWM2 y los botones 4 y 6

if(results.value==m6) PWM2_val +=15;
irrecv.resume(); // El IR está listo para recibir el siguiente valor
}
//Ahora vamos a controlar que los valores del PWM no están por debajo del 0 ni por encima del 255
if(PWM1_val<0) PWM1_val = 0; if(PWM1_val>255) PWM1_val = 255;
if(PWM2_val<0) PWM2_val = 0; if(PWM2_val>255) PWM2_val = 255;

//Y ahora se escriben los valores en el pin correspondiente
analogWrite(PWM1, PWM1_val);
analogWrite(PWM2, PWM2_val);
}

El mercado de arduino

Placas Arduino

Con un simple vistazo a la web https://www.arduino.cc/ encontraréis todas las placas de éste simpático fabricante/diseñador. Y cuando digo simpático no es sin razón, pues el diseño de los Arduinos es liberado para que cualquiera pueda hacerse una copia. Es más, otros fabricantes (por ejemplo en China) rediseñan la placa y la fabrican en masa. Además, sus creadores llevan a cabo importantes tareas en el ámbito educativo.

¿Por qué elegir un Arduino? Por un mínimo coste obtienes una placa de desarrollo con los puertos en conectores hembra, de fácil conexión, listo para usar. También tienen distintas placas para distintas necesidades. Vamos a enumerarlas.

Arduino UNO

Ésta placa, la más conocida de todas, usa un ATMEL ATmega328P, a 16 MHz y 5 voltios.

Tiene 14 pines de entrada/salida digital, de los cuales 6 de ellos se pueden usar como PWM, y otros 6 analógicos, que también se pueden usar como digitales.

Aunque es perfecto para empezar, una vez con los conocimientos suficientes e intentando hacer algo grande, la memoria puede ser insuficiente.

El precio de ésta placa original es de 25$ (USA), sin embargo sus copias pueden estar cerca de los 6€

Arduino Nano

Más enfocado hacia el desarrollo de placas de prototipos donde el arduino nano pueda encajarse y fijarlo, ya no lleva pines hembra.

Al igual que el Arduino UNO, funciona con 5 voltios y a 16 MHz

Tiene un puerto analógico completo, de 8 pines, y 14 pines digitales, de los cuales 6 son PWM.

La ventaja principal frente al siguiente de la lista, el arduino pro mini, es que lleva el USB integrado, por lo que su programación sigue siendo cosa de conectar y subir el programa. Aunque ésto lo haga un poco más grande.

Su precio original es de 18€ sin contar con impuestos, y sus copias se venden por algo más de 2.30€

Arduino Pro Mini

El rey para los proyectos pequeños, pero que no os engañe: se atreve con todos.

Para usar esta placa, sin USB incorporado, deberás comprar un adaptador USB a TTL, por lo que su uso es recomendado para fijar en un proyecto. Programar y desconectar. Ésto hace que sea más pequeño.

Algunas placas están limitadas a 3.3 voltios y 8 MHz pero lo más normal es encontrarlas a 5 voltios y 16 MHz, pudiendolas conectar también a 3.3 voltios sin perder velocidad de reloj.

Al igual que el Arduino Nano, contiene 14 pines digitales (de los cuales 6 pueden obtener PWM) y 6 analógicos.

Su precio original es de 12€ más impuestos, aunque las copias pueden costar algo más de 1.30€, sin tener en cuenta que hay que comprar un adaptador USB a TTL que costará más o menos lo mismo.

Estas tres placas son las más básicas, si bien las tres tienen una característica común: la falta de memoria en proyectos grandes. Ésto se soluciona en la gama más alta de Arduino.

Arduino Mega

Esta placa usa un ATmega2560 como microcontrolador principal.

A pesar de que funciona a 5 voltios y 16 MHz, como las anteriores, contiene 54 pines digitales (15 PWM) y 16 analógicos. Entre tantos pines podremos encontrar 4 módulos UART para comunicación serial.

Su precio es de 35€ más impuestos, pero podemos encontrar sus copias por unos 11€

Arduino Due

El primero en incorporar un procesador con núcleo ARM de 32 bits.

Aunque se conecta a un USB a 5 voltios, ésta placa funciona únicamente, y tiene sus entradas y salidas, a 3.3 voltios y 84 MHz. Es una limitación a tener en cuenta para no quemar el integrado.

Tiene 54 pines digitales (12 PWM), 12 entradas analógicas, 2 salidas analógicas, 4 UARTs y 2 puertos de i2c de 2 pines cada uno.

Su precio es de 34€ más impuestos pero se puede encontrar una copia a algo menos de 20€

Arduino Yún

Ésta placa contiene dos módulos separados: una parte es similar a un arduino UNO pero tiene un pequeño apartado donde se contiene un procesador Atheros que se conecta a internet mediante Wifi y Ethernet, también tiene un USB host y un lector de tarjetas SD

La gracia es que el Atheros incorpora una distribución Linux que se comunica con el ATmega mediante la programación.

Tiene 20 pines de entrada/salida digital, de los cuales 12 pueden ser usados como entrada analógica

Su precio es muy alto, de 52€, y no se le conocen copias.

Arduino Zero

Es la última incorporación al mercado de Arduino oficial, también basado en un núcleo ARM de 32 bits, funciona a 3.3 voltios y tiene un reloj de 48 MHz

Es muy similar al Arduino UNO, contiene 14 pines digitales de los cuales pueden usarse 12 como PWM. Tiene 6 entradas y 1 salida analógicas.

Su precio es todavía muy elevado, alcanzando los 50€, y tampoco tiene copias baratas en el mercado.

Mando a distancia (IR)

Hace mucho me puse a trabajar en ésto, pero por errores que me daba la librería, la versión del IDE, y tras probar mil veces, lo dejé pasar. Pero ahora he encontrado la forma de que funcione. Vamos a manejar el arduino con un mando a distancia.

Para demostrar cómo funciona (las aplicaciones las dejamos a vuestra imaginación) usaremos unos LEDs.

En primer lugar, es necesario tener la librería. Hay varias, una llamada NECIRrcv (con el protocolo NEC), y otra que es IRremote, al parecer sin ningún tipo de descodificación. Ésta última es la que usaremos, la única que he conseguido que funcione. Podréis descargarla aquí. Tenéis que descomprimirla y pegar la carpeta IRremote en el directorio Program Files (Archivos de programa) / Arduino / libraries. Tras hacer ésto y abrir el Arduino IDE, aparecerá en Ejemplos.

Ahora vamos a proceder a conocer nuestro mando a distancia. Con mi pack de Arduino recibí uno como éstos:

Que venía acompañado por un receptor de IR:

Lo que nos interesa ahora es, cuando pulsamos un botón del mando ¿Qué código envía al receptor? Para ello utilizaremos un simple circuito de 3 cables y un programa que lea lo que recibe y lo envíe mediante puerto Serial al Monitor Serial.

Visto desde ésta perspectiva el receptor, la patilla de la izquierda es la transmisora de datos, la central es GND y la derecha del todo la de alimentación. Dicho con Paint:

receptorir

 

Simplemente hay que hacer  la conexión debida de alimentación (no necesita resistencia) y poner Datos en un pin de arduino que podamos configurar como entrada, en mi caso está en el pin 11.

Ahora cargamos el sketch:

 

#include 
int IRpin = 11
IRrecv irrecv(IRpin);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  
}

void loop() 
{
  if (irrecv.decode(&results)) 
    {
      Serial.println(results.value); // Print the Serial 'results.value'
      irrecv.resume();   // Receive the next value
    }  
}

Cuando se cargue el programa, abrís el Monitor Serial y apretáis botones del mando. Veréis que para cada botón corresponde un número diferente, anotadlo. Por ejemplo, mis números son:

 

// 1 = 16724175
// 2 = 16718055
// 3 = 16743045
// - = 16754775
// + = 16748655
// ON/OFF = 16753245

Otros mandos, como los de Sony, tienen números "más amigables", del orden de 1000-4000. Ahora que ya tenéis los códigos, sólo es necesario modificar el programa inicial para que lleve a cabo unas acciones, por ejemplo, encender y apagar unos LED:

 

#include 
// 1 = 16724175
// 2 = 16718055
// 3 = 16743045
// - = 16754775
// + = 16748655
// ON/OFF = 16753245
int IRpin = 11, L1 = 3, L2= 4, L3=5;
IRrecv irrecv(IRpin);
decode_results results;

void setup()
{
  Serial.begin(9600);
  pinMode(L1,OUTPUT);
  pinMode(L2,OUTPUT);
  pinMode(L3,OUTPUT);
  irrecv.enableIRIn(); // Start the receiver
  
}

void digitalSwitch(char PIN){
  if(digitalRead(PIN)==1) digitalWrite(PIN,LOW);
  else digitalWrite(PIN,HIGH);
}

void loop() 
{
  if (irrecv.decode(&results)) 
    {
      if(results.value==16724175) digitalSwitch(L1);
      if(results.value==16718055) digitalSwitch(L2);
      if(results.value==16743045) digitalSwitch(L3);
      if(results.value==16748655) i=i+15;
      if(results.value==16753245){
        digitalSwitch(L1);
        digitalSwitch(L2);
        digitalSwitch(L3);
      }
      Serial.println(results.value); // Print the Serial 'results.value'
      irrecv.resume();   // Receive the next value
    }  
}