Created
April 5, 2015 20:43
-
-
Save jamesabruce/8bc9faf3c06e30c3f6fc to your computer and use it in GitHub Desktop.
Example of using an Arduino with Ethernet shield to control Philips Hue, with PIR motion sensor on i/o pin 2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Talking to Hue from an Arduino | |
By James Bruce (MakeUseOf.com) | |
Adapted from code by Gilson Oguime. https://github.com/oguime/Hue_W5100_HT6P20B/blob/master/Hue_W5100_HT6P20B.ino | |
*/ | |
#include <SPI.h> | |
#include <Ethernet.h> | |
// Hue constants | |
const char hueHubIP[] = "192.168.1.216"; // Hue hub IP | |
const char hueUsername[] = "newdeveloper"; // Hue username | |
const int hueHubPort = 80; | |
// PIR | |
int pir = 2; | |
boolean activated = false; | |
// Hue variables | |
boolean hueOn; // on/off | |
int hueBri; // brightness value | |
long hueHue; // hue value | |
String hueCmd; // Hue command | |
unsigned long buffer=0; //buffer for received data storage | |
unsigned long addr; | |
// Ethernet | |
byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // W5100 MAC address | |
IPAddress ip(192,168,1,2); // Arduino IP | |
EthernetClient client; | |
/* | |
Setup | |
*/ | |
void setup() | |
{ | |
Serial.begin(9600); | |
Ethernet.begin(mac,ip); | |
pinMode(pir,INPUT); | |
delay(2000); | |
Serial.println("Ready."); | |
} | |
void loop() | |
{ | |
if(digitalRead(pir) == 1){ | |
Serial.println("activated"); | |
// A series of four sample commands, which colour fades two lights between red and pink. Read up on the Hue API | |
// documentation for more details on the exact commands to be used, but note that quote marks must be escaped. | |
String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(1,command); | |
command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(2,command); | |
command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(1,command); | |
command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(2,command); | |
// so we can track state | |
activated = true; | |
} | |
else{ | |
activated = false; | |
Serial.println("deactivated"); | |
//was activated, so send a single off command | |
String command = "{\"on\": false}"; | |
setHue(1,command); | |
setHue(2,command); | |
} | |
} | |
/* setHue() is our main command function, which needs to be passed a light number and a | |
* properly formatted command string in JSON format (basically a Javascript style array of variables | |
* and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start. | |
*/ | |
boolean setHue(int lightNum,String command) | |
{ | |
if (client.connect(hueHubIP, hueHubPort)) | |
{ | |
while (client.connected()) | |
{ | |
client.print("PUT /api/"); | |
client.print(hueUsername); | |
client.print("/lights/"); | |
client.print(lightNum); // hueLight zero based, add 1 | |
client.println("/state HTTP/1.1"); | |
client.println("keep-alive"); | |
client.print("Host: "); | |
client.println(hueHubIP); | |
client.print("Content-Length: "); | |
client.println(command.length()); | |
client.println("Content-Type: text/plain;charset=UTF-8"); | |
client.println(); // blank line before body | |
client.println(command); // Hue command | |
} | |
client.stop(); | |
return true; // command executed | |
} | |
else | |
return false; // command failed | |
} | |
/* A helper function in case your logic depends on the current state of the light. | |
* This sets a number of global variables which you can check to find out if a light is currently on or not | |
* and the hue etc. Not needed just to send out commands | |
*/ | |
boolean getHue(int lightNum) | |
{ | |
if (client.connect(hueHubIP, hueHubPort)) | |
{ | |
client.print("GET /api/"); | |
client.print(hueUsername); | |
client.print("/lights/"); | |
client.print(lightNum); | |
client.println(" HTTP/1.1"); | |
client.print("Host: "); | |
client.println(hueHubIP); | |
client.println("Content-type: application/json"); | |
client.println("keep-alive"); | |
client.println(); | |
while (client.connected()) | |
{ | |
if (client.available()) | |
{ | |
client.findUntil("\"on\":", "\0"); | |
hueOn = (client.readStringUntil(',') == "true"); // if light is on, set variable to true | |
client.findUntil("\"bri\":", "\0"); | |
hueBri = client.readStringUntil(',').toInt(); // set variable to brightness value | |
client.findUntil("\"hue\":", "\0"); | |
hueHue = client.readStringUntil(',').toInt(); // set variable to hue value | |
break; // not capturing other light attributes yet | |
} | |
} | |
client.stop(); | |
return true; // captured on,bri,hue | |
} | |
else | |
return false; // error reading on,bri,hue | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The reason your code takes so long to run and update the change of input is because of the while loop on line 90. You don't need that while loop. You should also only be calling setHue when the switch input changes from off to on, or on to off. Your current code continuously calls upon setHue even if the state is the same.
I suggest changing line 51 to:
if((digitalRead(pir) == 1) && (activated == false) ){
and line 68 to:
if((digitalRead(pir) == 0) && (activated == true) ){