Skip to content

Instantly share code, notes, and snippets.

@trevmex
Last active July 10, 2018 01:26
Show Gist options
  • Save trevmex/c930aec09ac3d83ed634bef628066527 to your computer and use it in GitHub Desktop.
Save trevmex/c930aec09ac3d83ed634bef628066527 to your computer and use it in GitHub Desktop.
Arduino code to toggle your lights on and off using a Magiquest wand. Schematics and instructions are available at http://fritzing.org/projects/magiquest-caseta-arduino-light-toggle
/*
Copyright 2017 Trevor Menagh
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <IRremote.h> // Imported from https://github.com/kitlaan/Arduino-IRremote (LGPL)
#include <SparkFunESP8266WiFi.h> // Imported from https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library (MIT)
/**
* IR Receiver Setup
*
* The number in the paraentheses is the pin number for the IR receiver. Change it to whatever pin you are using.
*/
IRrecv irrecv(11);
/**
* Led Pins
*/
int offLedPin = 3;
int onLedPin = 2;
/**
* WiFi Settings
*/
const char *wifiNetworkName = "YOUR_WIFI_NETWORK_NAME";
const char *wifiPassword = "YOUR_WIFI_PASSWORD";
ESP8266Client client;
/**
* Light Commands
*/
String lightsOnCommand = "YOUR_IFTTT_MAKER_LIGHTS_ON_COMMAND";
String lightsOffCommand = "YOUR_IFTTT_MAKER_LIGHTS_OFF_COMMAND";
String key = "YOUR_IFTTT_MAKER_KEY";
boolean toggle = true;
/**
* Loops forever, ending the program.
*/
void errorLoop()
{
Serial.println(F("Looping forever."));
for (;;)
;
}
/**
* Turns on or off an Led at a given pin.
*
* pin: the control pin for the Led to change
* on: if true, turn on Led, turn off otherwise
*/
void toggleLed(int pin, boolean on)
{
digitalWrite(pin, on ? HIGH : LOW);
}
/**
* Activates an Led and turns it on or off.
*
* pin: the control pin for the Led to change
* on: if true, turn on Led, turn off otherwise
*/
void setupLed(int pin, boolean on)
{
pinMode(pin, OUTPUT);
toggleLed(pin, on);
}
/**
* Returns true if the WiFi shield is initialized, false otherwise.
*/
boolean initialized()
{
return esp8266.begin();
}
/**
* Initializes the WiFi shield.
*/
void initializeWiFi()
{
if (!initialized())
{
Serial.println(F("Error talking to ESP8266."));
errorLoop();
}
}
/**
* Returns true if the WiFi shield is in station mode (ready to act as a router), false otherwise.
*/
boolean inStationMode()
{
return esp8266.getMode() == ESP8266_MODE_STA || esp8266.setMode(ESP8266_MODE_STA) >= 0;
}
/**
* Prepares the WiFi shield for use.
*/
void prepareWiFi()
{
if (!inStationMode())
{
Serial.println(F("Error setting mode."));
errorLoop();
}
}
/**
* Returns true if the WiFi shield is connected to your WiFi network, false otherwise.
*/
boolean connectedToWiFi()
{
return esp8266.status() > 0 || esp8266.connect(wifiNetworkName, wifiPassword) >= 0;
}
/**
* Connects to your WiFi network.
*/
void connectToWiFi()
{
if (!connectedToWiFi())
{
Serial.println(F("Error connecting."));
errorLoop();
}
}
/**
* Prints out TCP response codes from the ESP8266 WiFi Bridge.
*/
void printTcpResponse(int tcpResponse)
{
Serial.print("TCP Response: ");
switch (tcpResponse)
{
case 1:
Serial.println(F("success"));
break;
case 2:
Serial.println(F("already connected"));
break;
case -1:
Serial.println(F("timeout"));
break;
case -3:
Serial.println(F("fail"));
break;
default:
Serial.print(F("unknown code = "));
Serial.println(tcpResponse, DEC);
}
}
/**
* Returns true if the WiFi client is connected to the light control host, false otherwise.
*/
boolean connectedToLights()
{
Serial.println(F("Connecting to http://maker.ifttt.com on port 80 for 60 minutes."));
int tcpResponse = client.connect("maker.ifttt.com", 80, 3600000);
printTcpResponse(tcpResponse);
return tcpResponse > 0;
}
/**
* Send the command to the light control host to turn on or off the lights, depending on the current state.
*/
void sendCommandToLights()
{
String command = "GET /trigger/" + (toggle ? lightsOnCommand : lightsOffCommand) + "/with/key/" + key + " HTTP/1.1\n"
"Host: maker.ifttt.com\n"
"Connection: close\n\n";
Serial.println(command);
client.print(command);
}
/**
* Returns true if the light control host has issued a response, false otherwise.
*
* Side effect: The response it printed to the Serial Monitor
*/
boolean responseReceived()
{
boolean isResponseReceived = false;
while (client.available())
{
isResponseReceived = true;
Serial.write(client.read());
}
return isResponseReceived;
}
/**
* Toggle the on and off Leds.
*/
void toggleLeds()
{
toggleLed(onLedPin, toggle);
toggleLed(offLedPin, !toggle);
}
/**
* Flip the toggle either on or off (the opposite of what it is now).
*
* Side effect: the currect stet (before the flip) is printed to the Serial Monitor
*/
void flipToggle()
{
Serial.print(F("Toggled to "));
Serial.println(toggle ? "on." : "off.");
toggleLeds();
toggle = !toggle;
}
/**
* Toggle the lights either on or off (the opposite of what it is now).
*/
void toggleLights()
{
if (connectedToLights())
{
sendCommandToLights();
if (responseReceived())
{
flipToggle();
}
}
else
{
Serial.println(F("Failed to connect to server."));
}
}
/**
* Print decoded Magiquest wand information to the Serial Monitor.
*/
void printMagiquestInfo(decode_results results)
{
Serial.println(F("Magiquest received."));
Serial.print(F("bits: "));
Serial.println(results.bits, HEX);
Serial.print(F("value: "));
Serial.println(results.value, HEX);
Serial.print(F("magnitude: "));
Serial.println(results.magnitude, HEX);
}
/**
* Main setup function.
*
* Sets up debug messaging, IR Receiver, on/off Leds and WiFi shield.
*/
void setup()
{
Serial.begin(9600); // Turns on the Serial Monitor.
irrecv.enableIRIn(); // Turns on IR Receiver.
setupLed(onLedPin, false);
setupLed(offLedPin, true);
initializeWiFi(); // Turns on the ESP8266 WiFi Shield
prepareWiFi(); // Sets the ESP8266 WiFi Shield to Station Mode
connectToWiFi(); // Connects the ESP8266 WiFi Shield to your WiFi network
Serial.println(F("Ready."));
}
/**
* Main loop.
*
* Waits for an IR signal to come in, checks to see if it is a Magiquest wand, and if it is, then toggles the lights.
*/
void loop()
{
decode_results results;
if (irrecv.decode(&results)) // Returns true if an IR signal was received, false otherwise. Populates results. Stops IR receiver.
{
if (results.decode_type == MAGIQUEST)
{
printMagiquestInfo(results);
toggleLights();
}
else
{
Serial.println(F("Unknown IR signal."));
}
irrecv.resume(); // Resets the IR Received to allow new signals to be received.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment