Registro de temperatura, humedad y punto de rocío con imp. eléctrico

El Electric Imp es un dispositivo increíble para IoT y su integración con Ubidots facilita enormemente la creación de gráficos y alertas por SMS/correo electrónico en cuestión de minutos. En este tutorial del Electric Imp, aprenderás a usar la placa de desarrollo del Electric Imp con un sensor DHT11 para medir la temperatura y la humedad relativa, y luego calcular el punto de rocío con Ubidots.

El punto de rocío se puede utilizar como un índice de la percepción humana de comodidad en relación con el clima; un punto de rocío entre 13-16 °C (55-59 °F) te hace sentir cómodo, pero un punto de rocío por encima de 21 °C (70 °F) te hará sentir demasiado caliente porque el aire tendría demasiada humedad y tu cuerpo no podría enfriarse:

Punto de rocío Percepción humana
24-26 °C / 75-80 °F Extremadamente incómodo y opresivo
21-24 °C / 0-74 °F Muy húmedo, bastante incómodo
18-21 °C / 65-69 °F Algo incómodo para la mayoría de las personas en edge superior
16-18 °C / 60-64 °F Está bien para la mayoría, pero todos perciben la humedad en edge superior
13-16 °C / 55-59 °F Cómodo
10-12 °C / 50-54 °F Muy cómodo
Menos de 10 °C / 50-54 °F Muy cómodo
Menos de 10 °C / Menos de 50 °F Un poco seco
Menos de 10 °C / Menos de 50 °F Afortunadamente, existe una función lineal para calcular el punto de rocío en función de la temperatura y la humedad relativa.

Materiales

  • Un diablillo

  • Una placa de conexión eléctrica Imp

  • Tres cables hembra a hembra

  • resistencia de 10k

  • Sensor de humedad y temperatura DHT11

Alambrado

Así es como se conecta el sensor DHT11 a su placa Electric Imp:

Código

¡A programar! Al trabajar con Electric imp, necesitarás dos secciones de código: una para el dispositivo y otra para el agente. Aquí está el código del dispositivo (un poco largo, ya que tiene la clase para manejar el DHT11):

const SPICLK = 937.5; // Clase para leer el sensor de temperatura/humedad DHT11. // Estos sensores utilizan un protocolo propietario de un solo cable. El imp. // emula este protocolo con SPI. // Para usar: // - Conectar MOSI a MISO con una resistencia de 10 k. // - Conectar MISO a la línea de datos del sensor. class DHT11 { static STARTTIME_LOW = 0.001000; // 1 ms de tiempo bajo para el inicio. static STARTTIME_HIGH = 0.000020; // 20 µs de tiempo alto mínimo para el inicio. static STARTTIME_SENSOR = 0.000080; // 80 µs de bajo / 80 µs de alto. "ACK" del sensor al iniciar. static MARKTIME = 0.000050; // 50 µs de pulso bajo entre 0 y 1 marcas. static ZERO = 0.000026; // 26 us alto para "0" static ONE = 0.000075; // 70 us alto para "1" spi = null; clkspeed = null; bittime = null; bytetime = null; start_low_bits = null; start_low_bytes = null; start_high_bits = null; start_high_bytes = null; start_ack_bits = null; start_ack_bytes = null; mark_bits = null; mark_bytes = null; zero_bits = null; zero_bytes = null; one_bits = null; one_bytes = null; // constructor de clase // Entrada: // _spi: un periférico SPI preconfigurado (por ejemplo, spi257) // _clkspeed: la velocidad a la que se ha configurado el SPI para ejecutarse // Devolución: (Ninguno) constructor(_spi, _clkspeed) { this.spi = _spi; this.clkspeed = _clkspeed; bittime = 1.0 / (clkspeed * 1000); bytetime = 8.0 * bittime; inicio_bits_bajos = TIEMPO_INICIO_BAJO / bittime; inicio_bytes_bajos = (inicio_bits_bajos / 8); inicio_bits_altos = TIEMPO_INICIO_ALTO / bittime; inicio_bytes_altos = (inicio_bits_altos / 8); inicio_bits_ack = SENSOR_TIEMPO_INICIO / bittime; inicio_bytes_ack = (inicio_bits_ack / 8); marca_bits = TIEMPO_INICIO / bittime; marca_bytes = (marca_bits / 8); cero_bits = CERO / bittime; cero_bytes = (cero_bits / 8); un_bit = UNO / bittime; un_byte = (un_bits / 8); } // Función auxiliar // Dado un blob largo, encuentra los tiempos entre transiciones y lo analiza para obtener valores de temperatura y humedad. Asume un valor de retorno de 40 bits (humedad: 16 / temperatura: 16 / suma de comprobación: 8). // Entrada: // hexblob (blob de longitud arbitraria). // Retorno: // tabla que contiene: // "rh": humedad relativa (float). // "temp": temperatura en grados Celsius (float). // Si la lectura falla, rh y temperatura devolverán 0. function parse(hexblob) { local laststate = 0; local lastbitidx = 0; local gotack = false; local rawidx = 0; local result = blob(5); // Humedad: 2 bytes, temperatura: 2 bytes, suma de comprobación: 1 byte. local humid = 0; local temp = 0. // itera a través de cada bit de cada byte de la señal devuelta for (local byte = 0; byte < hexblob.len(); byte++) { for (local bit = 7; bit >= 0; bit--) { local thisbit = (hexblob[byte] & (0x01 << bit)) ? 1:0; if (thisbit != laststate) { if (thisbit) { // transición de bajo a alto; observa cuánto tiempo es alto laststate = 1; lastbitidx = (8 * byte) + (7 - bit); } else { // transición de alto a bajo; laststate = 0; local idx = (8 * byte) + (7 - bit); local hightime = (idx - lastbitidx) * bittime; // ahora tenemos un bit válido de información. Averigua qué símbolo es. local resultbyte = (rawidx / 8); local resultbit = 7 - (rawidx % 8); //server.log(format("bit %d del byte %d",resultbit, resultbyte)); if (hightime < ZERO) { // esto es un cero if (gotack) { // no registres ningún dato antes de que se vea el ACK result[resultbyte] = result[resultbyte] & ~(0x01 << resultbit); rawidx++; } } else if (hightime < ONE) { // esto es un uno if (gotack) { result[resultbyte] = result[resultbyte] | (0x01 << resultbit); rawidx++; } } else { // esto es un START ACK gotack = true; } } } } } //server.log(format("parsed: 0x %02x%02x %02x%02x %02x",result[0],result[1],result[2],result[3],result[4])); húmedo = (resultado[0] * 1.0) + (resultado[1] / 1000.0); si (resultado[2] y 0x80) { // temperatura negativa resultado[2] = ((~resultado[2]) + 1) y 0xff; } temperatura = (resultado[2] * 1.0) + (resultado[3] / 1000.0); si (((resultado[0] + resultado[1] + resultado[2] + resultado[3]) y 0xff) != resultado[4]) { devolver {"rh":0,"temp":0}; } de lo contrario { devolver {"rh":húmedo,"temp":temp}; } } // lee el sensor // Entrada: (ninguna) // Retorno: // tabla que contiene: // "rh": humedad relativa (flotante) // "temp": temperatura en grados Celsius (flotante) // si la lectura falla, rh y temp devolverán 0 function read() { local bloblen = start_low_bytes + start_high_bytes + (40 * (mark_bytes + one_bytes)); local startblob = blob(bloblen); for (local i = 0; i < start_low_bytes; i++) { startblob.writen(0x00,'b'); } for (local j = start_low_bytes; j < bloblen; j++) { startblob.writen(0xff,'b'); } //server.log(format("Enviando %d bytes", startblob.len())); local result = spi.writeread(startblob); return parse(result); } } rele <- hardware.pin9; spi <- hardware.spi257; while(1){ clkspeed <- spi.configure(MSB_FIRST, SPICLK); dht11 <- DHT11(spi, clkspeed); data <- dht11.read(); server.log(format("Humedad relativa: %0.1f",data.rh)+" %"); server.log(format("Temperatura: %0.1f C",data.temp)); agent.send("temp",data.temp); imp.sleep(1); }

Gracias a Thomas Byrne por proporcionar la clase para manejar el sensor DHT11 en Github.

Como puedes ver, el código del Agente es realmente simple, solo no olvides poner tu propio token de autenticación y el ID de variable en la llamada HTTP:

device.on("temp", function(value) { server.log("Intentando enviar a Ubi el valor:"); server.log(value); local headers = { "Content-Type": "application/json", "X-Auth-Token": "NBbF3PWPxWc2IaO40aXOKnhIu8tOv92rYN3ibiEc7Jh6GV3KZUUCHtXuNz7Y" }; // Reemplaza el token por el tuyo local url = "http://things.ubidotsubidots/api/v1.6/variables/53d2beb37625424630223dac/values"; // Reemplaza el ID de la variable por el tuyo local string = {"value": value}; local request = http.post(url, headers, http.jsonencode(string)); local response = request.sendsync(); });

Crea una variable sintética en Ubidots.

Tal como agregarías una nueva variable, ve a “Fuentes”–> “Electric Imp (nombre de tu fuente de datos)”–>”Agregar nueva variable”:

Ahora ingrese esta ecuación para calcular el valor del punto de rocío:

Así es como debería verse:

¡Ahora deberías comenzar a ver los datos de punto de rocío actualizados cada vez que tu Imp envíe datos de temperatura y humedad a Ubidots!

Terminando

En este proyecto, pudimos conectar un Imp a Ubidots, midiendo y calculando variables físicas para comprender mejor nuestro entorno. Puedes explorar más funciones, como la creación de alertas cuando el punto de rocío es demasiado alto, o crear gráficos para compartir, como los que se muestran al principio de este artículo.

No olvides consultar algunas de nuestras últimas publicaciones:

Si eres nuevo en Ubidots, ¡ haz clic aquí para empezar!