Close
0%
0%

Internet of Things in 5 minutes

Playing with ESP8266, Adafruit.io, and Amazon Echo

Similar projects worth following
My goal was to create a 3 minute YouTube video showing how to control something from the cloud, and send something to the cloud. Unfortunately, even after massive cuts to my footage, I still could not get it down to 3 minutes, so I had to settle for a five-ish minute video.

Below are the two sketches I demo'ed in the first video:

  1. Turns LED on/off based on "light" feed downloaded from Adafruit.io
  2. Sends Temperature and Humidity to Adafruit.io
// 3 minute IoT - Download from Cloud
// Hari Wiguna, 2015

// Libraries - Thanks AdaFruit!
#include <ESP8266WiFi.h>
#include "Adafruit_IO_Client.h"

// Configure WiFi access point & AdaFruit.io account.
#define WLAN_SSID  "Firefly24"
#define WLAN_PASS  "??????????"
#define ADAFRUIT_IO_KEY    "??????????"

// Create an ESP8266 WiFiClient, AdaFruit.io client, and our lightFeed
WiFiClient client;
Adafruit_IO_Client aio = Adafruit_IO_Client(client, ADAFRUIT_IO_KEY);
Adafruit_IO_Feed lightFeed = aio.getFeed("light");

byte ledPin = 2;

void setup() {
  pinMode(ledPin, OUTPUT);

  Serial.begin(115200);
  delay(10);
  Serial.println(); Serial.println();
  Serial.println(F("3 minute IoT - Download from Cloud"));

  // Connect to WiFi access point.
  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());

  aio.begin();

  Serial.println(F("Ready!"));
}

void loop() {
  //--- READ LIGHT FEED STATE ---
  FeedData feedData = lightFeed.receive();
  if (feedData.isValid()) {
    Serial.print(F("Received value from feed: ")); Serial.println(feedData);
    digitalWrite(ledPin, strcmp(feedData,"ON"));
  }
  else {
    Serial.print(F("Failed to receive the latest feed value!"));
  }

  // Don't be a jerk and abuse AdaFruit.io.  Wait a second in-between data requests.
  delay(1000);
}


Sends Temperature and Humidity to Adafruit.io

// 3 minute IoT - Upload to Cloud
// Hari Wiguna, 2015

// Libraries - Thanks AdaFruit!
#include <ESP8266WiFi.h>
#include "Adafruit_IO_Client.h"

// Configure WiFi access point & AdaFruit.io account.
#define WLAN_SSID  "Firefly24"
#define WLAN_PASS  "??????????"
#define ADAFRUIT_IO_KEY    "??????????"

// Create an ESP8266 WiFiClient class to connect to the AIO server.
WiFiClient client;
Adafruit_IO_Client aio = Adafruit_IO_Client(client, ADAFRUIT_IO_KEY);
Adafruit_IO_Feed temperatureFeed = aio.getFeed("Temperature");
Adafruit_IO_Feed humidityFeed = aio.getFeed("Humidity");

//--------------- SENSOR -----------------------------
#include "DHT.h"

#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
//----------------------------------------------------

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println(); Serial.println();
  Serial.println(F("3 minute IoT - Upload to Cloud"));

  // Connect to WiFi access point.
  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());

  // Initialize the Adafruit IO client class (not strictly necessary with the
  // client class, but good practice).
  aio.begin();

  //--- SENSOR ---
  dht.begin();

  Serial.println(F("Ready!"));
}

void loop() {

  //--- READ AND SEND TEMPERATURE ---
  int f = dht.readTemperature(true);
  Serial.print(F("Temperature = ")); Serial.println(f, DEC);
  if (!temperatureFeed.send(f)) Serial.println(F("*** Error writing value to temperatureFeed!"));

  //--- READ AND SEND HUMIDITY ---
  int h = dht.readHumidity();
  Serial.print(F("Humidity = ")); Serial.println(h, DEC);
  if (!humidityFeed.send(h))Serial.println(F("*** Error writing value to humidityFeed!"));

  //delay(1000); // No need for delay, DHT sensor takes 2 seconds to gather data :-(
}

  • Amazon Echo from 2015 meets X-10 from 1978!

    Hari Wiguna01/07/2016 at 02:08 4 comments

    Sketch and wiring for Arduino can be found here. I connected ESP's GPIO0 to RTS and GPIO2 to DTR of the CM17A. Each goes through TWO inverter gates (in the SN7404 TTL chip) to convert the 3.3V signals to 5V.

    The code below subscribes to MQTT button push from Adafruit.io instead of polling it from the ESP.

    I commented out the ping from loop() because it sometimes would flush the MQTT packet from the server if it pings just at the wrong time. So, I let it timeout and it would reconnect when it discovers that it's no longer connected to the server.

    I also modified Brohogan's excellent code to work on the ESP8266 by not relying on ATMega specific code.

    // Amazon Echo meets X-10
    // Hari Wiguna, 2016
    //
    // Hacked together from:
    // - Adafruit MQTT Library ESP8266 Example
    // - and http://playground.arduino.cc/X10/CM17A
    
    #include <ESP8266WiFi.h>
    #include "Adafruit_MQTT.h"
    #include "Adafruit_MQTT_Client.h"
    #include <X10Firecracker.h> // Use the modified version of this that no longer rely on ATMega specific features. -- Hari
    
    // Configurations
    #define AIO_SERVER      "io.adafruit.com"
    #define AIO_SERVERPORT  1883
    #define AIO_USERNAME    "?????"
    #define WLAN_SSID  "Firefly24"
    #define WLAN_PASS  "?????"
    #define AIO_KEY    "?????"
    
    int ledPin = 2;
    bool isDebug = false; // Don't debug if USB serial is not connected
    
    // Create an ESP8266 WiFiClient class to connect to the MQTT server.
    WiFiClient client;
    
    // Store the MQTT server, username, and password in flash memory.
    // This is required for using the Adafruit MQTT library.
    const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
    const char MQTT_USERNAME[] PROGMEM  = AIO_USERNAME;
    const char MQTT_PASSWORD[] PROGMEM  = AIO_KEY;
    
    // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
    Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
    
    /****************************** Feeds ***************************************/
    // Setup a feed called 'light' for subscribing to changes.
    const char ONOFF_FEED[] PROGMEM = AIO_USERNAME "/feeds/light";
    Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_FEED);
    
    /*************************** Sketch Code ************************************/
    
    void setup() {
      X10.init( 0, 2, 5 ); // 0=RTS, 2=DTR, 5=extra delay for faster ESP8266
    
      if (isDebug) Serial.begin(115200);
      delay(10);
    
      if (isDebug)
      {
        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);
        if (isDebug) Serial.print(".");
      }
      
      if (isDebug)
      {
        Serial.println();
    
        Serial.println("WiFi connected");
        Serial.println("IP address: "); Serial.println(WiFi.localIP());
      }
    
      // Setup MQTT subscription for onoff feed.
      mqtt.subscribe(&onoffbutton);
    }
    
    // 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() {
      int8_t ret;
    
      // Stop if already connected.
      if (mqtt.connected()) {
        return;
      }
    
      if (isDebug) Serial.print("Connecting to MQTT... ");
    
      while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
        if (isDebug) {
          Serial.println(mqtt.connectErrorString(ret));
    
          Serial.println("Retrying MQTT connection in 5 seconds...");
        }
        mqtt.disconnect();
        delay(5000);  // wait 5 seconds
      }
      if (isDebug) Serial.println("MQTT Connected!");
    }
    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
      Adafruit_MQTT_Subscribe *subscription;
      while ((subscription = mqtt.readSubscription(3000))) {
        if (subscription == &onoffbutton) {
          if (isDebug) {
            Serial.print(F("Got: "));
    ...
    Read more »

View project log

Enjoy this project?

Share

Discussions

phase2682 wrote 01/28/2016 at 05:18 point

I have several of my lights controlled by X10, it may be ancient but it works okay.  Just have to infrequently replace a module but not unexpected since it is switching main voltage and current.  I did find that the transceiver module only relays commands for the same house code as it is set on.  I added additional feeds in the code for additional modules so I can control more than one x10 device with my echo.  Also used 7400 for the step up to 5 volts since I have several of them lying around.  Just connect together 2 inputs of the NAND to form an invertor and series connect two for the buffer/level shifter.  Thanks Hari for sharing your idea and code.

  Are you sure? yes | no

Hari Wiguna wrote 01/28/2016 at 05:42 point

Cool! That's awesome! Thanks for sharing. Keep making!

  Are you sure? yes | no

Irfaan Hassan wrote 01/19/2016 at 20:47 point

Good evening Sir,

beautiful project and info..

I have a slight query..

"

digitalWrite(ledPin, strcmp(feedData,"ON"));
  }

"

It was working yesterday..

Now On is off and off is on lol..

Any clue??

Regards,

Irfaan Hassan

  Are you sure? yes | no

Hari Wiguna wrote 01/19/2016 at 20:58 point

Thanks Irfaan.
digitalWrite() of course would set ledPin HIGH (+3.3V) or LOW (0V).

Depending on how you wire up the LED, HIGH could turn on the led or off.

Remember that strcmp return zero (LOW) for a match, non-zero (HIGH) for anything else.

  Are you sure? yes | no

mac9968 wrote 01/07/2016 at 19:06 point

I got an echo as a gift and intend to play around with many projects like this one. Thanks for putting it out there.  I am new to hackaday.io but I am so glad I found the site.  What alternatives would you suggest for the older X10 hardare?

  Are you sure? yes | no

Hari Wiguna wrote 01/07/2016 at 19:20 point

The internet is full of cool projects :-) 

Sorry, I don't have much experience with home automation systems either, so I can't offer any recommendations.  SmartThings, WeMo, Leviton are some brands I've heard of, but again, I do not have any experience using any of them.

  Are you sure? yes | no

jaromir.sukuba wrote 12/31/2015 at 01:04 point

Very comprehensive and informative. Just for fun - I took an old ESP8266 board from my junkbox, connected on protoboard and got LED switching ON/OFF in a few minutes.

  Are you sure? yes | no

Hari Wiguna wrote 12/31/2015 at 02:23 point

Thanks for letting me know Jaromir!  AdaFruit deserves all the credit. I'm just sharing the fun, and sounds like you had some fun too.  Awesome!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates