¡Enciende un ventilador cuando la temperatura sea demasiado alta! - Tutorial de Electric Imp
En nuestro último tutorial de Electric Imp , aprendimos a medir la temperatura, la humedad y el confort térmico general con Ubidots . Esta vez, crearemos un sencillo control de encendido y apagado de ventiladores. Registraremos la temperatura en Ubidots y activaremos un evento cuando supere los 30 °C para que Electric Imp encienda un ventilador, y luego un disparador para apagarlo cuando la temperatura baje de 27 °C.
Realmente funciona de maravilla, así que aquí vamos:
Materiales


- Tres cables hembra a hembra

- resistencia de 10k

- Sensor de humedad y temperatura DHT11

-Un pequeño abanico

-Una cola PowerSwitch

Alambrado
Así es como deben conectarse todos los componentes:

…y sólo falta una cosa: ¡enchufar el ventilador!
Codificación
- Inicie sesión en el IDE de Electric Imp y tome nota de la URL de su Imp:

Copia los siguientes dos códigos. En el código del Agente, usaremos una función para manejar solicitudes HTTP a Ubidots, no olvides poner el token de Ubidotsy el id de las variables.
- Código del agente:
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:ubidots.com/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(); }); device.on("hum", function(value) { //server.log("Intentando enviar a Ubi el valor:hola"); //server.log(value); local headers = { "Content-Type": "application/json", "X-Auth-Token": "NBbF3PWPxWc2IaO40aXOKnhIu8tOv92rYN3ibiEc7Jh6GV3KZUUCHtXuNz7Y" }; // Reemplaza el token por el tuyo local url = "http:ubidots.com/api/v1.6/variables/53e541e57625422c7d900a1d/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(); }); function requestHandler(request, response) { try { // verificar si el usuario envió led como parámetro de consulta if ("relay" in request.query) { server.log("entre"); // si lo hicieron, y led=1... establece nuestra variable en 1 if (request.query.relay == "1" || request.query.relay == "0") { // convertir el parámetro de consulta led a un entero local relayState = request.query.relay.tointeger(); // enviar el mensaje "led" al dispositivo y enviar ledState como los datos device.send("relay", relayState); } } // enviar una respuesta diciendo que todo estaba bien. response.send(200, "OK"); } catch (ex) { response.send(500, "Error interno del servidor: " + ex); } } // registrar el controlador HTTP http.onrequest(requestHandler);
- Código del dispositivo:
Tenga en cuenta la última parte del código donde hay una función para encender/apagar el ventilador con la cola Powerswitch.
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); } } relé <- hardware.pin8; spi <- hardware.spi257; rele.configure(DIGITAL_OUT); función setRelay(relayState){ servidor.log("relayState:" + relayState ); relé.write(relayState); } agente.on("relay", setRelay); función mainLoop(){imp.wakeup(1.0, mainLoop); clkspeed <- spi.configure(MSB_FIRST, SPICLK); dht11 <- DHT11(spi, clkspeed); datos <- dht11.read(); servidor.log(formato("Humedad relativa: %0.1f",datos.rh)+" %"); servidor.log(formato("Temperatura: %0.1f C",datos.temp)); agente.send("temp",datos.temp); agente.send("hum",datos.rh); }mainLoop();
Configurar eventos Ubidots
-
En su cuenta Ubidots , cree una fuente de datos con dos variables: Temperatura y Humedad
-
Haga clic en la sección “Eventos” y agregue uno:

- Elija Imp eléctrico como fuente y temperatura (temp) como variable.

- Poner una condición cuando la temperatura sea superior a 30ºC.

- Seleccione "URL de solicitud" y escriba su URL de Imp más "?relay=1"

- Añade otro evento con este condicional.

- Seleccione “Solicitar URL” y escriba su URL de Imp más “?relay=0”

Concluyendo
En este proyecto, pudimos controlar un ventilador eléctrico desde internet con Electric Imp. Al igual que controlábamos un ventilador usando datos de temperatura, también podías registrar cualquier otro dato y tomar medidas en función de él. Por ejemplo, podrías abrir la puerta del garaje cuando tu gato se acercara a un sensor de movimiento (¡lo que significa que quiere salir!).
No olvides consultar algunas de nuestras últimas publicaciones:
- Conecte un Imp eléctrico (imp002) a Ubidots
- Creación de un widget de mapas en tiempo real con Ubidots
Si eres nuevo en Ubidots , ¡mira esta excelente pieza de inicio y regístrate gratis hoy!