πŸ”Œ Controlling an ESP32 Smart Lamp with Amazon Alexa

A complete guide to voice-controlled IoT using ESP32, Adafruit IO, IFTTT and Alexa

1. Project Overview

In this project, we control a lamp connected to an ESP32 development board simply by speaking a voice command to an Amazon Echo Dot (or the Alexa smartphone app). Instead of writing any new firmware, we reuse the exact same ESP32 sketch from a previous IoT project (DHT22 sensor + Relay + Adafruit IO) β€” the "magic" happens entirely in the cloud, through a free automation service called IFTTT (If This Then That).

Key takeaway: No changes are required to the ESP32 code. The board already subscribes to a feed on Adafruit IO called relay. All we need to do is get Alexa to update that feed's value remotely, and the ESP32 will react automatically.

2. System Architecture

When you speak a command to Alexa, the request travels through several cloud services before it finally reaches your ESP32 board. Here is the complete signal path:

πŸ—£οΈ You say:
"Alexa, trigger lamp on"
β†’
Amazon Echo /
Alexa Cloud
β†’
IFTTT
(Applet Trigger)
β†’
Adafruit IO
(MQTT Feed: relay)
β†’
ESP32
(Subscriber)
β†’
πŸ’‘ Relay + Lamp

This matches the description of the process: a signal will initiate from the voice command, go first to the Amazon server, from Amazon server to IFTTT, from IFTTT to Adafruit IO, back to the ESP32, and finally to the lamp. Each service performs one specific job in this chain:

ServiceRole in the Chain
Amazon AlexaListens for the spoken phrase and converts it into a cloud event
IFTTTActs as the "glue" β€” detects the Alexa phrase and triggers an action on Adafruit IO
Adafruit IOHosts the MQTT feed/dashboard; stores the new value (ON/OFF)
ESP32Subscribed to the feed via MQTT; reacts instantly when the value changes
Relay + LampPhysically switches the lamp's power based on the ESP32's GPIO output

3. What You Will Need

Hardware Pin Reference (from the sketch)

ComponentESP32 Pin
DHT22 SensorGPIO 27
Relay ModuleGPIO 12
Onboard LEDLED_BUILTIN

4. Step-by-Step Setup Guide

4.1 Create an IFTTT Account

1

Go to ifttt.com and sign up for free using an email, Google, Apple, or Facebook account.

4.2 Create Your First Applet (Lamp ON)

1

Click Create to start a new Applet. IFTTT Applets follow the logic: "If This, Then That."

2

For the "If This" part, search for and select the Amazon Alexa service.

3

Choose the trigger type: "Say a specific phrase."

4

Connect your Amazon account when prompted (you will need to enter an OTP for two-step verification), then click Allow to authorize.

5

Set the trigger phrase to:

lamp on
6

For the "Then That" part, search for and select the Adafruit IO service, then connect it using your Adafruit IO account credentials.

7

Choose the action "Send data to Adafruit IO", select the feed named relay, and set the value to send as:

ON
8

Click Create Action, then Finish to save the Applet.

Note: Even though the Adafruit IO service also lists a "temperature" field option, it is not used here β€” only the relay feed is relevant for lamp control.

4.3 Create the Second Applet (Lamp OFF)

Repeat the same process to build a second Applet for turning the lamp off:

1

If This: Amazon Alexa β†’ "Say a specific phrase" with the phrase:

lamp off
2

Then That: Adafruit IO β†’ Send data to the relay feed with the value:

OFF
You now have two working Applets, each free to create β€” the free IFTTT plan typically allows a handful of Applets, which is more than enough for basic home‑automation experiments like this.

5. The ESP32 Sketch (Unchanged)

The beauty of this experiment is that the exact same code from the earlier DHT22 + Relay + Adafruit IO project is reused. The ESP32 already publishes temperature and humidity data to Adafruit IO, and β€” most importantly β€” it already subscribes to the relay and led feeds. Whenever IFTTT updates the relay feed's value (via Alexa), the ESP32 picks it up over MQTT and switches the physical relay accordingly.

5.1 Key Configuration Section

Before uploading, update the following fields with your own credentials:

#define WLAN_SSID       "Robotics Lab"      // Your WiFi network name
#define WLAN_PASS       "Robotics@321"      // Your WiFi password

#define AIO_USERNAME    "your_adafruit_username"
#define AIO_KEY         "your_adafruit_io_key"

5.2 Full Arduino Sketch

/***************************************************
Complete IoT Project with DHT22, Relay and ESP32 Huzzah Board
THE SAME CODE TO BE USED TO CONTROL LAMP FROM ALEXA

DHT Sensor connected to PIn 27
Relay Connected to Pin 12
 ****************************************************/

#include <WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "Robotics Lab"  // replace it with your Wifi Name
#define WLAN_PASS       "Robotics@321"  // Replace it with your wifi password

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "amitrana3348"  // Change this to your username
#define AIO_KEY         "3e359482c74e59509c3f50ab76e3a80958f55033"  // Change this to your key

#include "DHT.h"
#define DHTPIN 27 // dht connection
#define DHTTYPE DHT22   // DHT 22  connected to pin 27
DHT dht(DHTPIN, DHTTYPE);

int rel = 12;


/************ Global State (you don't need to change this!) ******************/

WiFiClient client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temperature");
Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/humidity");
Adafruit_MQTT_Subscribe relay = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/relay");
Adafruit_MQTT_Subscribe led = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/led");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() 
{
  Serial.begin(9600);
  delay(10);
  pinMode(rel,OUTPUT); digitalWrite(rel,LOW);
  pinMode(LED_BUILTIN,OUTPUT); digitalWrite(LED_BUILTIN,LOW);
  Serial.println(F("Adafruit MQTT demo"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&relay);
  mqtt.subscribe(&led);
  dht.begin();
}


void loop() 
{
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) 
  {
    if (subscription == &led) 
    {
      Serial.print(F("Got: "));
      Serial.println((char *)led.lastread);
      if(strcmp((char *)led.lastread, "ON") == 0) 
      {
        digitalWrite(LED_BUILTIN,HIGH);
        Serial.println("LED Turned ON");
      }
      if(strcmp((char *)led.lastread, "OFF") == 0)
      {
        digitalWrite(LED_BUILTIN,LOW);
        Serial.println("LED Turned OFF");
      }
    }
    
    if (subscription == &relay) 
    {
      Serial.print(F("Got: "));
      Serial.println((char *)relay.lastread);
      if(strcmp((char *)relay.lastread, "ON") == 0) 
      {
        digitalWrite(rel,HIGH);
        Serial.println("Relay Turned ON");
      }
      if(strcmp((char *)relay.lastread, "OFF") == 0)
      {
        digitalWrite(rel,LOW);
        Serial.println("Relay Turned OFF");
      }
    }
  }

  // Now we can publish stuff!
  float h = dht.readHumidity(); 
  float t = dht.readTemperature();
 
  Serial.print(F("\nSending Temperature value "));
  Serial.print(t);
  Serial.print("...");
  if (! temperature.publish(t)) 
  {
    Serial.println(F("Failed"));
  } 
  else 
  {
    Serial.println(F("OK!"));
  }
  delay(1500);
  Serial.print(F("\nSending Humidity value "));
  Serial.print(h);
  Serial.print("...");
  if (! humidity.publish(h)) 
  {
    Serial.println(F("Failed"));
  } 
  else 
  {
    Serial.println(F("OK!"));
  }
  Serial.println("*******************************************************************************************");
  
  delay(1500);

  // ping the server to keep the mqtt connection alive
  // NOT required if you are publishing once every KEEPALIVE seconds
  /*
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }
  */
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() 
{
  unsigned char ret;

  // Stop if already connected.
  if (mqtt.connected()) 
  {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) 
  { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) 
       {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

5.3 How the Code Logic Works

6. Testing the Voice Commands

With both Applets created and the ESP32 running the sketch, keep the Adafruit IO dashboard open on screen so you can visually confirm the feed value changing in real time. Then simply speak the following commands to your Echo device or Alexa app:

Alexa, trigger lamp on
Alexa, trigger lamp off

Each time you say the phrase, IFTTT detects it, sends the corresponding value (ON or OFF) to the Adafruit IO relay feed, and the ESP32 reacts within a second or two β€” switching the relay and turning the connected lamp on or off.

Tip: You are not limited to the word "trigger." IFTTT lets you customize the phrase structure, so commands like "Alexa, turn on the lamp" can also be configured if you prefer more natural language.

7. Troubleshooting & Tips

ProblemPossible CauseSolution
Alexa does not respond to the phrase Network delay or Applet not yet synced Wait a few seconds and try again; IFTTT free plan may have a short polling delay
Lamp does not turn off/on ESP32 lost MQTT connection Check Serial Monitor for "MQTT Connected!" message; verify Wi-Fi credentials
Applet fails to trigger Amazon account not linked properly Reconnect the Alexa service in IFTTT and re-authorize permissions
Free IFTTT plan limits reached Only a few Applets allowed on free tier Delete unused Applets or consider a paid plan for larger projects
Good to know: No prior experience with IFTTT or Alexa development is required β€” the entire integration is done through simple point-and-click configuration, with zero additional code needed on the ESP32 side.

8. Conclusion

This project demonstrates how easily an existing MQTT-based ESP32 IoT setup can be extended with voice control, simply by adding a cloud automation layer (IFTTT) between Alexa and Adafruit IO. Because the ESP32 already listens for feed updates, the hardware and firmware require zero modification β€” only cloud-side configuration changes.

For makers and hobbyists, the free tiers of Adafruit IO and IFTTT are more than sufficient. For professional or larger-scale IoT deployments, paid subscriptions to these services unlock higher usage limits and more advanced automation capabilities.