IoT Lamp With ESP32, Adafruit MQTT and Relay Module

by JônatasT in Circuits > Arduino

5518 Views, 0 Favorites, 0 Comments

IoT Lamp With ESP32, Adafruit MQTT and Relay Module

IMG_20210328_182053.jpg

Hello guys!

Today I'm going to show you how to activating and monitoring a lamp using ESP32, a Relay module, through a MQTT server from Adafruit.

List of Materials

  • ESP32 dev kit (in this project the Doit ESP32 devkit V1 was used)
  • Breadboard
  • 1 Push button
  • 1 kΩ resistor
  • Wires
  • Relay module (only 1 channel required)
  • Breadboard power supply

Note: In this project I used Doit ESP32 Devkit V1, but you can use another development kit that has ESP32. But you will need to change the GPIOs used in the source code.

Adafruit Settings

1 criar grupo.png
2 - criar feed.png
2a - feed info.png
2a- criando feed.png
2b - feed info.png
3 - my key.png
3a - my key.png

Note: If you do not already have an Adafruit account, you must first register. In this project I used the free account.

https://io.adafruit.com/

  1. After creating the account, you must create a group and a feed.
    • Go to Feeds> View all> New Group.
  2. After creating the group, click on New Feed in the created group and create a feed.
  3. After creatad the feed, open the feed and click on Feed Info to get the full address of the MQTT topic (MQTT by Key) that will be used in the source code below.
  4. In the main menu, select My Key. In the open dialog, you will see the IO_KEY that you will need to insert in the source code later on (Arduino).

Assembling the Circuit

esp32.jpg
IMG_20210329_213540.jpg
  1. Insert ESP32 in the breadboard.
  2. Connect ESP32 3V3 pin to the (+) rail of breadboard.
  3. Connect ESP32 GND to the (-) rail of breadboard.
  4. Join (only) the (-) rail of breadboard.

Note 1: The breadboard's rails (+) and (-) are splited. So, they are divided into 2 unconnected halves. In this project we will only join the (-) (GND) rail, leaving the (+) (3V3) rail splited because we will use 5V in the other segment to supply the relay module.

Note 2: The GND must be equalized with the GND of the breadboard power source, so we join the (-) rail of the breadboard.

Note 3: Make sure that your breadboard is like the one in the example, that is, that it has this segmentation on the (+) and (-) rails. Otherwise, the breadboard power supply cannot be mounted on the same breadboard.

Push Button Connection

push button.jpg

We will connect the resistor and the button in the pull-down configuration

  1. Connect the ESP32 IO D23 directly to the push button terminal (terminal strip 40 of the breadboard in the first image).
  2. Connect the second push button terminal to a 1kΩ resistor (terminal strip 42).
  3. Connect the other terminal of the resistor to the rail (-) (GND) of the breadboard.

Breadboard Power Supply

IMG_20210328_184354.jpg

Insert the breadboard power supply, as shown in image.

Note 1: In this project we use only 1 channel from this source, and we configure it to supply 5V. This configuration is made through the jumper on the board (closing between 5V and OFF).

Note 2 (AGAIN): BE VERY CAREFUL TO NOT TO JOIN THE RAIL (+), BECAUSE IT MAY DAMAGE THE ESP32.

​Relay Connections

IMG_20210328_184452.jpg
IMG_20210328_193858.jpg
  1. Use a wire to connect the VCC pin of the relay module directly to the 5V supplied by the breadboard source (Right half of the rail + of the breadboard).
    • The yellow wire of the figure 2.
  2. Use a wire to connect the GND pin of the relay module to the rail (-) (GND) of the breadboard.
    • The blue wire of the figure 2.
  3. Use a wire to connect pin IN2 (or IN1, whatever) to IO D22 of ESP32.
    • The green wire of the figure 2.

​Lamp

relé.png

Heads up! In this project we work with the AC network. There is a risk of electric shock. Be careful to not get hurt (if you are a child, ask an adult for help)!

We have reached the dangerous part of the project. We will connect the lamp cables to the relay.

First of all - make sure that everything is disconnected from the electrical power.

  1. Follow the diagram shown in the figure.
  2. The neutral (represented by blue line on diagram) is connected directly to one of the terminals of the lamp socket.
  3. The phase (represented by red line on diagram) is connected to the common terminal of the relay.
  4. The return (represented by black line on diagram) is connected from NO terminal of the relay to the other socket of the lamp.

Note 1:Be careful to not touch the bottom of the relay module when it is energized, because you will receive an electric shock!

Note 2: You MUST plugue the lamp cable to the power only AFTER all the circuit connections are ready and the code has been recorded on the ESP32.

Note 3: This relay supports voltages from ~125V to ~250V, and a maximum current of 10A.

Note 4: In this project, this lamp was connected on 127V AC network. But in 220V, the connection is the same (L-L or L-N).

Arduino

Captura de tela 2021-03-28 205032.png

We finally got to the most exciting part of the project.

  1. Install the ESP32 library on the arduino (tutorial on this link).
  2. Install the PubSubClient library (as shown in the figure).
  3. Create an .ino file and enter the code below:
#include <PubSubClient.h>
#include <WiFi.h>
#include <Arduino.h>

void mqtt_send_lamp_status();
void toggle_lamp_sts();
void button_action();
void startTimer();
void stopTimer();

const char* ssid = "your wifi name";
const char* password = "your wifi password";
const char* mqttServer = "io.adafruit.com";
const int mqttPort = 1883;
const char* mqttUser = "your adafruit username";
const char* mqttPassword = "adafruit io key";
const char* mqttTopic = "user_name/feeds/iot-project.lampada-esp32";

#define LED 2
#define RELE 22
#define BUTTON 23
#define RELE_ON LOW
#define RELE_OFF HIGH
#define LED_ON HIGH
#define LED_OFF LOW

WiFiClient espClient;
PubSubClient client(espClient);

//--------- WIFI -------------------------------------------

void wifi_connect() {
  Serial.print("Starting connecting WiFi.");
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//------------------ MQTT ----------------------------------
void mqtt_setup() {
  client.setServer(mqttServer, mqttPort);
    client.setCallback(callback);
    Serial.println("Connecting to MQTT…");
    while (!client.connected()) {        
        String clientId = "ESP32Client-";
        clientId += String(random(0xffff), HEX);
        if (client.connect(clientId.c_str(), mqttUser, mqttPassword )) {
            Serial.println("connected");
        } else {
            Serial.print("failed with state  ");
            Serial.println(client.state());
            delay(2000);
        }
    }

    mqtt_send_lamp_status();
    client.subscribe(mqttTopic);
}

void mqtt_send_lamp_status() {   
  int val = digitalRead(RELE);
  Serial.printf("Sending LAMP status: ");
  if(val == RELE_OFF) {
    Serial.println("OFF");
    digitalWrite(LED, LED_OFF);
    client.publish(mqttTopic, "OFF");
  } else {
    Serial.println("ON");
    digitalWrite(LED, LED_ON);
    client.publish(mqttTopic, "ON");
  } 
}

void callback(char* topic, byte* payload, unsigned int length) {

    Serial.print("Message arrived in topic: ");
    Serial.println(topic);

    String byteRead = "";
    Serial.print("Message: ");
    for (int i = 0; i < length; i++) {
        byteRead += (char)payload[i];
    }    
    Serial.println(byteRead);

    if (byteRead == "OFF"){
        Serial.println("LAMP OFF");
        digitalWrite(RELE, RELE_OFF);
        digitalWrite(LED, LED_OFF);
    }

    if (byteRead == "ON"){
        Serial.println("LAMP ON");
        digitalWrite(RELE, RELE_ON);
        digitalWrite(LED, LED_ON);
    }

    Serial.println();
    Serial.println(" — — — — — — — — — — — -");

}

//----------- IOs -------------------------------------------
void setup_ios() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, RELE_OFF);
}

//---------------- INTERRUPTS ----------------------------
struct Button {
    const uint8_t PIN;
    uint32_t numberKeyPresses;
    bool pressed;
};

Button button = {BUTTON, 0, false};

void IRAM_ATTR isr() {
    static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 200){
   button.pressed = true;
 }
 last_interrupt_time = interrupt_time;
}

void config_interrupts() {
  attachInterrupt(button.PIN, isr, FALLING);
}

//----------- GENERAL -------------------------------------
void toggle_lamp_sts() {
  int val = digitalRead(RELE);
  digitalWrite(RELE, !val);
  digitalWrite(LED, val);
}

void button_action() {
  if (button.pressed) {
    toggle_lamp_sts();      
    mqtt_send_lamp_status();
    button.pressed = false;
  }
}

//--------- ARDUINO --------------------------------------
void setup() {  
  Serial.begin(115200);
  setup_ios();  
  wifi_connect();
  mqtt_setup();  
  //startTimer();
  config_interrupts();
}

void loop() {
    client.loop();
    button_action();
}

Note 1: This source code was based on the examples provided by the Arduino IDE for ESP32.

Mobile APP

app.png
dashboard.png

In this last step, I leave as a bonus a mobile application developed by a colleague to communicate with the MQTT server that I implemented in Adafruit (github link here).

The code is open, and will need to be edited to insert Adafruit's MQTT data (topic, key), in order to work correctly.

If you don't want to use the application, Adafruit provides a nice feature called Dashboard. In this functionality it is possible to create a panel and subscribe and publish on several topics.

Conclusion

In this article we saw how to control a lamp remotely using ESP32, a MQTT server (Adafruit) and a relay module.

The implemented project can be used to create several prototypes based on the same logic of activating / deactivating the relay, for example, activating the buttonhole of an electronic gate, or activating a fan (but it is necessary to consider the limits of the relay).

Another feature that can be implemented, is the communication via Bluetooth with the ESP32, but I will leave that for the future.

That's all, folks!

Thanks for all!