Proyectos IoT Destacados

Interruptor WiFi para electrodomésticos con ESP8266

Christopher Méndez
- 10 min read
Enviar por correo electrónico

Aprende a construir tu propio interruptor WiFi con el módulo ESP y a controlar cualquier aparato de tu lugar favorito.

¿Qué son los conmutadores WiFi?

Hoy en día vivimos en la era del Internet de las Cosas y los Interruptores WiFi son básicamente la base de ello. Son dispositivos que pueden encender, apagar o atenuar electrodomésticos como luces, ventiladores, etc. de forma remota o autónoma, controlados por nuestros teléfonos móviles, nuestra voz, la temperatura ambiente o incluso los informes meteorológicos.

¿Cómo funcionan?

Se basan en comunicaciones inalámbricas (comúnmente conocidas como WiFi) que les permiten conectarse a Internet y procesar datos, de modo que pueden actuar en función de determinadas condiciones establecidas por el usuario.

Requisitos para la solicitud:

  • Módulo ESP8266 (ESP-01)
  • Placa de circuito impreso
  • Placa de pruebas
  • Cables
  • Cuenta Ubidots
  • Arduino nano

1. Esquema:

Materiales:

3x resistencias 1k ohm 1/4w

2x resistencias 470 ohm 1/2w

1x conector hembra doble en línea (U3)

1x MOC3010 (Opto-triac)

1x Triac BTA24

1x 100nf 400v Condensador

1x Fuente de alimentación Hi-Link de 3,3 V

1x bloque de terminales 2p

1x bloque de terminales 3p

PCB: Enlace para descargar el archivo Gerber

PCB fabricado con PCBGOGO (Industria de fabricación de PCB)

2. Ubidots Creación de dispositivos y variables.

Ve a la sección Dispositivos de tu cuenta de Ubidots y crea un nuevo dispositivo llamado"wifiswitch".

Dentro de tu dispositivo"wifiswitch", crea una variable llamada"light".

3. Ubidots Dashboard y creación de widgets.

Una vez creados nuestro dispositivo y nuestra variable, podemos crear un dashboard y un widget para controlar la luz desde una web o un móvil dashboard. Para crear un nuevo dashboard, pulse el botón"Datos > Dashboard". A continuación, pulse el icono más y complete la configuración de dashboard como desee.

Ahora, crea un widget de control para establecer el estado de la bombilla asociada a la variable "luz". Para crear el widget de control, selecciona el icono más situado en la parte superior derecha de la página. A continuación, pulse "Interruptor" como tipo de widget, seleccione la variable que desea controlar y complete la configuración del widget como desee.

Entonces estará listo para programar y probar su proyecto.

4. Programación con el IDE Arduino.

1. Si aún no lo has hecho, descarga el IDE de Arduino.

1a. Abra el IDE Arduino y seleccione Archivos -> Preferencias

1b. Añada la siguiente URL en el campo URLs adicionales del Administrador de Juntas . Puede añadir varias URL separándolas con comas.

http://arduino.esp8266.com/stable/paquete_esp8266com_index.json

2. Abra e instale la placa ESP8266 en el Boards Manager: Herramientas -> Placa -> Administrador de Placas

2a. Puedes encontrar fácilmente la placa escribiendo "ESP8266" en la barra de búsqueda.

3. Ahora, selecciona la placa Generic ESP8266 en el menú Herramientas -> Placa

4. Defina o vuelva a comprobar el Puerto de su PC con el que se está comunicando el dispositivo. Vaya a Herramientas -> Puerto: -> Seleccione el puerto

4b. Asegúrate de que la velocidad de subida de tu IDE es 115200 yendo a Herramientas -> Velocidad de subida -> 115200

5. Descarga la librería UbidotsESPMQTT si aún no lo has hecho. Ahora, haga clic en Sketch -> Include Library -> Add .ZIP Library y elija la biblioteca Ubidots ESP8266 MQTT.

Si se carga correctamente, obtendrá la respuesta: "Biblioteca añadida a sus bibliotecas".

8. Cierra y abre de nuevo el IDE de Arduino.

Programación del ESP8266:

Una vez que tu ESP8266 está configurado, podemos empezar a publicar y suscribir datos desde/hacia Ubidots para controlar el Wifi Switch.
1. Copia y pega el siguiente código en el IDE de Arduino. No se olvide de personalizar el SSID Wi-Fi y la contraseña y su Ubidots Token.



/****************************************

 * Libraries

 ****************************************/

#include "UbidotsESPMQTT.h"


/****************************************

 * Define constants
 
 ****************************************/

#define TOKEN "............................." // Your Ubidots TOKEN

#define WIFINAME "........." //Your SSID

#define WIFIPASS "........." // Your Wifi Pass

#define DEVICE_LABEL "wifiswitch"   // Name of the device

#define VARIABLE_LABEL1  "light"  // Name of the Ubidots variable

const int ERROR_VALUE = 65535;  // Error value 

const uint8_t NUMBER_OF_VARIABLES = 2; // Cantidad de variables a las que el programa se va a suscribir
char * variable_labels[NUMBER_OF_VARIABLES] = {"light"}; // Variables names


#define luz  0
#define boton  2

int seguro=0;

int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin
int reading;
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50; 

float estadoluz; // Variable to be used in the code

float value; // Variable to store input data
uint8_t variable; // To use with the switch case

Ubidots ubiClient(TOKEN);

WiFiClient client;

/****************************************

 * Auxiliar functions

 ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
  char* variable_label = (char *) malloc(sizeof(char) * 30);
  get_variable_label_topic(topic, variable_label);
  value = btof(payload, length);
  set_state(variable_label);
  execute_cases();
  free(variable_label);
  /////////////////Light////////////////////

  digitalWrite(luz, estadoluz);
 
  /////////////////Light////////////////////
  
}

// Parse topic to extract the variable label which changed value
void get_variable_label_topic(char * topic, char * variable_label) {
  Serial.print("topic:");
  Serial.println(topic);
  sprintf(variable_label, "");
  for (int i = 0; i < NUMBER_OF_VARIABLES; i++) {
    char * result_lv = strstr(topic, variable_labels[i]);
    if (result_lv != NULL) {
      uint8_t len = strlen(result_lv);      
      char result[100];
      uint8_t i = 0;
      for (i = 0; i < len - 3; i++) { 
        result[i] = result_lv[i];
      }
      result[i] = '\0';
      Serial.print("Label is: ");
      Serial.println(result);
      sprintf(variable_label, "%s", result);
      break;
    }
  }
}

// cast from an array of chars to float value.
float btof(byte * payload, unsigned int length) {
  char * demo = (char *) malloc(sizeof(char) * 10);
  for (int i = 0; i < length; i++) {
    demo[i] = payload[i];
  }
  float value = atof(demo);
  free(demo);
  return value;
}

// State machine to use switch case
void set_state(char* variable_label) {
  variable = 0;
  for (uint8_t i = 0; i < NUMBER_OF_VARIABLES; i++) {
    if (strcmp(variable_label, variable_labels[i]) == 0) {
      break;
    }
    variable++;
  }
  if (variable >= NUMBER_OF_VARIABLES) variable = ERROR_VALUE; // Not valid
  
}

// Function with switch case to determine which variable changed and assigned the value accordingly to the code variable
void execute_cases() {  
  switch (variable) {
    case 0:
      estadoluz = value;
      Serial.print("Luz: ");
      Serial.println(estadoluz);
      Serial.println();
      break;
    case ERROR_VALUE:
      Serial.println("error");
      Serial.println();
      break;
    default:
      Serial.println("default");
      Serial.println();
  }

}
/****************************************

 * Funcion principal

 ****************************************/

void setup() {

  // put your setup code here, to run once:
  pinMode(luz, OUTPUT);  
  pinMode(boton, INPUT); 
  ubiClient.ubidotsSetBroker("industrial.api.ubidots.com"); // Sets the broker properly for the business account
  ubiClient.setDebug(true); // Pass a true or false bool value to activate debug messages
  Serial.begin(115200);
  ubiClient.wifiConnection(WIFINAME, WIFIPASS);
  ubiClient.begin(callback);
  if(!ubiClient.connected()){
    ubiClient.reconnect();
  }

  char* deviceStatus = getUbidotsDevice(DEVICE_LABEL);

  if (strcmp(deviceStatus, "404") == 0) {
    ubiClient.add("light", 0); //Insert your variable Labels and the value to be sent
    ubiClient.ubidotsPublish(DEVICE_LABEL);
    ubiClient.loop();
  }

  ubiClient.ubidotsSubscribe(DEVICE_LABEL,VARIABLE_LABEL1); //Insert the Device and Variable's Labels
  Serial.println(variable_labels[1]);

}

void loop() {
  // put your main code here, to run repeatedly:
  if(!ubiClient.connected()){
    ubiClient.reconnect();
    ubiClient.ubidotsSubscribe(DEVICE_LABEL,VARIABLE_LABEL1); //Insert the Device and Variable's Labels
  }
  ubiClient.loop();    
  
  readit();

  debounce();

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
          
}

void readit(){
  // read the state of the switch into a local variable:
  reading = digitalRead(boton);
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
}

void debounce(){
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
    readit2();  
  }
}

void readit2(){
    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      toggle();      
    }
}

void toggle(){
  // only toggle the LED if the new button state is LOW
  if (buttonState == LOW) {
    ledState = !ledState;
    // set the LED:
    digitalWrite(luz, ledState);
    ubiClient.add("light", ledState); //Insert your variable Labels and the value to be sent
    ubiClient.ubidotsPublish(DEVICE_LABEL);
  }  
}

char* getUbidotsDevice(char* deviceLabel) {
  char* data = (char *) malloc(sizeof(char) * 700);
  char* response = (char *) malloc(sizeof(char) * 400);
  sprintf(data, "GET /api/v1.6/devices/%s/", deviceLabel);
  sprintf(data, "%s HTTP/1.1\r\n", data);
  sprintf(data, "%sHost: industrial.api.ubidots.com\r\nUser-Agent:wifiswitch/1.0\r\n", data);
  sprintf(data, "%sX-Auth-Token: %s\r\nConnection: close\r\n\r\n", data, TOKEN);
  free(data);
 
  if (client.connect("industrial.api.ubidots.com", 80)) {
    client.println(data);
  } 
  else {
    free(data);
    free(response);
    return "e";
  }
  int timeout = 0;
  while(!client.available() && timeout < 5000) {
    timeout++;
    if (timeout >= 4999){
      free(data);
      free(response);
      return "e";
    }
    delay(1);
    }

  int i = 0;
  while (client.available()) {
    response[i++] = (char)client.read();
    if (i >= 399){
      break;
    }
  }
  char * pch;
  char * statusCode;
  int j = 0;
  pch = strtok (response, " ");
  while (pch != NULL) {
    if (j == 1 ) {
      statusCode = pch;
    }

    pch = strtok (NULL, " ");
    j++;
  }
  free(response);
  return statusCode;

}

2. Carga del código en el ESP8266:

Para subir el código al ESP8266 necesitamos una interfaz serie para comunicar (Programar) el módulo con el PC, podemos usar conversores de USB a TTL, pero en este caso, vamos a usar la serie del Arduino que hacen muy buen trabajo.

Para cargar el código en el ESP8266 tienes que seguir las conexiones de abajo.

Arduino Nano ESP8266
TXD TXD
RXD RXD
3.3V VCC
GND GND
3.3V CH_PD
GND GPIO0

NOTA: Por favor, tenga cuidado con el VCC del ESP8266, sólo funciona con una alimentación de 3,3V.

Ahora, verifica que tu código es correcto haciendo clic en el botón de comprobación en el IDE Arduino encima del editor.

Una vez verificado el código, recibirá una respuesta similar a la siguiente, indicando que está correctamente configurado.

A continuación, tienes que cargar el código en tu NodeMCU. Para ello, seleccione el icono de flecha a la derecha junto al icono de verificación.

Una vez cargado el código, recibirá el siguiente mensaje en el IDE de Arduino:

5. Configura los comandos de voz mediante el Asistente de Google:

Para controlar tu "WiFi Switch"con Google Home, primero debemos configurar una plataforma intermediaria llamada IFTTT, esto nos permitirá emparejar nuestro Switch con el Asistente de Google. Para configurarlo correctamente, sigue los pasos que se muestran a continuación.

Si no tiene una cuenta, regístrese.

Haga clic en "Mis Applets".

A continuación, haga clic en "Nueva Applet".

Haga clic en "+ esto" para configurar el desencadenante de su condición.


Busca el servicio "Asistente de Google" y haz clic en él.

Haz clic en "Di una frase sencilla".

Rellene los campos de activación con las frases que desea utilizar para controlar la luz, la respuesta y el idioma y, a continuación, haga clic en "Crear activación".

A continuación, haz clic en "+eso" para configurar la acción.

Busque el servicio de acción "Webhooks".

Haga clic en "Realizar una solicitud web".

Completa los campos de acción:

Campo Argumento
URL http://things.ubidots.com/ api/v1.6/devices/wifiswitch?token=(Aquí van tus Ubidots Token)
Método POST
Tipo de contenido application/json
Cuerpo To turn on {“light”:1}, to turn off {“light”:0}

Por último, haga clic en Finalizar.

NOTA: Repita todo para configurar el applet "Apagar la luz", con la declaración correcta del Cuerpo.

6. Sesión de pruebas:

Siguiendo el esquema de la imagen, conecte correctamente el módulo a su aparato de corriente alterna.

Inicio Módulo
Línea L
Neutro N
Línea Ligera B

Añada un botón momentáneo de su preferencia en el bloque de terminales llamado SW.

Identifique los cables de Línea, Neutro y Luz:

Realiza las conexiones y coloca el pulsador, aprieta los tornillos y prueba.

En caso de que seas un aprendiz visual echa un vistazo al siguiente video tutorial. Puedes encontrar todos los pasos que hice para construir este proyecto cuidadosamente explicados:

Resumen:

En esta guía, acabamos de aprender cómo construir un interruptor WiFi que puede ser controlado a través de Internet por su voz, aplicación de teléfono móvil, o su PC, que le permiten controlar una bombilla de un dormitorio o cualquier otro lugar. Este dispositivo funciona basado en el módulo WiFi ESP8266, que es un pequeño módulo que permite que el proyecto esté en línea fácilmente. Y este dispositivo se puede aplicar en el control de muchos dispositivos diferentes, como ventiladores, motores, cortinas, luces, tiras de led, y mucho más.

Empiece hoy mismo a desarrollar sus soluciones IoT con Ubidots.