Richard Albritton
Published © CC BY-SA

Remote Control with the Huzzah + Adafruit.io

Use Adafruit IO to let buttons on one Adafruit Huzzah to control LEDs on another Huzzah, anywhere on Earth!

IntermediateFull instructions provided3 hours3,113

Things used in this project

Hardware components

Adafruit HUZZAH ESP8266 Breakout
Adafruit HUZZAH ESP8266 Breakout
×2
Breadboard (generic)
Breadboard (generic)
×2
RGB Diffused Common Anode
RGB Diffused Common Anode
×1
Resistor 475 ohm
Resistor 475 ohm
×9
Male/Male Jumper Wires
×15
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×4
SparkFun FTDI Basic Breakout - 5V
SparkFun FTDI Basic Breakout - 5V
×1
Li-Ion Battery 1000mAh
Li-Ion Battery 1000mAh
×2

Software apps and online services

Arduino IDE
Arduino IDE
Adafruit Adafuit.IO

Story

Read more

Schematics

Buttons Wiring

LED Wiring

Code

Buttons Code

Arduino
The Arduino sketch for this project is fairly straight forward. Copy the following code into a new Arduino sketch. We will need to modify this sketch to include settings for the WiFi connection as well as Adafruit IO credentials.
      /***************************************************
  Must use ESP8266 Arduino from:
    https://github.com/esp8266/Arduino

  Works great with Adafruit's Huzzah ESP board:
  ----> https://www.adafruit.com/product/2471
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Richard Albritton, based on original code by Tony DiCola 
  for Adafruit Industries. Adafruit IO example additions by Todd Treece.
  MIT license, all text above must be included in any redistribution
 ****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/****************************** Pins ******************************************/

#define Buttons       A0  // analog 0

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

#define WLAN_SSID       "...your SSID..."
#define WLAN_PASS       "...your password..."

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

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "...your AIO username..."
#define AIO_KEY         "...your AIO key..."

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

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Store the MQTT server, client ID, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ AIO_USERNAME;
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_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);/****************************** Feeds ***************************************/

// Setup a feed called 'remote-buttons' for publishing changes.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
const char RemoteButtons_FEED[] PROGMEM = AIO_USERNAME "/feeds/remote-buttons";
Adafruit_MQTT_Publish RemoteButtons = Adafruit_MQTT_Publish(&mqtt, RemoteButtons_FEED);

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

// remote-buttons state
int ButtonRead = 0;
int current = 0;
int last = -1;

void setup() {

  Serial.begin(115200);

  Serial.println(F("Adafruit IO Example"));

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

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

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

  // connect to adafruit io
  connect();

}

void loop() {

  // ping adafruit io a few times to make sure we remain connected
  if(! mqtt.ping(3)) {
    // reconnect to adafruit io
    if(! mqtt.connected())
      connect();
    }
    Serial.print("\n");
    Serial.print(analogRead(Buttons));
    ButtonRead = analogRead(Buttons);
    delay(1);
    // grab the current state of the remote-buttons
    if (ButtonRead > 500 && ButtonRead < 600) {
      current = 1;
    }
    if (ButtonRead > 600 && ButtonRead < 750) {
      current = 2;
    }
    if (ButtonRead > 750 && ButtonRead < 900) {
      current = 3;
    }
    if (ButtonRead > 900) {
      current = 0;
    }

  // return if the value hasn't changed
  if(current == last)
    return;

  int32_t value = current;

  // Now we can publish stuff!
  Serial.print(F("\nSending RemoteButtons value: "));
  Serial.print(value);
  Serial.print("... ");

  if (! RemoteButtons.publish(value))
    Serial.println(F("Failed."));
  else
    Serial.println(F("Success!"));

  // save the RemoteButtons state
  last = current;

}

// connect to adafruit io via MQTT
void connect() {

  Serial.print(F("Connecting to Adafruit IO... "));

  int8_t ret;

  while ((ret = mqtt.connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt.disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("Adafruit IO Connected!"));

}
    

LED Code

Arduino
The Arduino sketch for this project is fairly straight forward. Copy the following code into a new Arduino sketch. We will need to modify this sketch to include settings for the WiFi connection as well as Adafruit IO credentials.
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/****************************** Pins ******************************************/

#define Blue            5  // LED Color
#define Green            4  // LED Color
#define Red            2  // LED Color

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

#define WLAN_SSID       "...your SSID..."
#define WLAN_PASS       "...your password..."

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

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "...your AIO username..."
#define AIO_KEY         "...your AIO key..."

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

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Store the MQTT server, client ID, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ AIO_USERNAME;
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_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);

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

// Setup a feed called 'lamp' for subscribing to changes.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
const char AssistiveCallButtons_FEED[] PROGMEM = AIO_USERNAME "/feeds/assistive-call-buttons";
Adafruit_MQTT_Subscribe AssistiveCallButtons = Adafruit_MQTT_Subscribe(&mqtt, AssistiveCallButtons_FEED);

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

int current = 0;

void setup() {

  // set power switch tail pin as an output
  pinMode(Blue, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(Red, OUTPUT);

  digitalWrite(Red, HIGH);
  digitalWrite(Blue, HIGH);
  digitalWrite(Green, HIGH);

  Serial.begin(115200);

  Serial.println(F("Adafruit IO Example"));

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

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

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

  // listen for events on the lamp feed
  mqtt.subscribe(&AssistiveCallButtons);

  // connect to adafruit io
  connect();
}

void loop() {

  Adafruit_MQTT_Subscribe *subscription;

  // ping adafruit io a few times to make sure we remain connected
  if(! mqtt.ping(3)) {
    // reconnect to adafruit io
    if(! mqtt.connected())
      // listen for events on the lamp feed
     // mqtt.subscribe(&AssistiveCallButtons);
      
      // connect to adafruit io
      connect();
  }

  // this is our 'wait for incoming subscription packets' busy subloop
  while (subscription = mqtt.readSubscription(1000)) {

    // we only care about the lamp events
    if (subscription == &AssistiveCallButtons) {

      // convert mqtt ascii payload to int
      char *value = (char *)AssistiveCallButtons.lastread;
      Serial.print(F("Received: "));
      Serial.println(value);
      current = atoi(value);
    }
      //Serial.println(current);
  // write the current state to the power switch tail
  // do something different depending on the
  // range value:
  switch (current) {
    case 0:    // your hand is on the sensor
      digitalWrite(Red, HIGH);
      digitalWrite(Blue, HIGH);
      digitalWrite(Green, HIGH);
      break;
    case 1:    // your hand is close to the sensor
      digitalWrite(Red, LOW);
      digitalWrite(Blue, HIGH);
      digitalWrite(Green, HIGH);
      break;
    case 2:    // your hand is a few inches from the sensor
      digitalWrite(Red, HIGH);
      digitalWrite(Blue, HIGH);
      digitalWrite(Green, LOW);
      break;
    case 3:    // your hand is nowhere near the sensor
      digitalWrite(Red, HIGH);
      digitalWrite(Blue, LOW);
      digitalWrite(Green, HIGH);
      break;
  }
  delay(1);        // delay in between reads for stability

  }

}

// connect to adafruit io via MQTT
void connect() {

  Serial.print(F("Connecting to Adafruit IO... "));

  int8_t ret;

  while ((ret = mqtt.connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt.disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("Adafruit IO Connected!"));

}

Credits

Richard Albritton

Richard Albritton

4 projects • 31 followers
I am a graphic artist and tech developer working at the SoDo Makerspace in Seattle Washington.

Comments