Will Freeman
Published © GPL3+

Philips Hue Tap Control

Turn any surface into a tap/knock sensor to control your Philips Hue lights.

IntermediateWork in progress2 hours1,425
Philips Hue Tap Control

Things used in this project

Hardware components

Photon
Particle Photon
×1
Piezo Sensor
ControlEverything.com Piezo Sensor
×1

Software apps and online services

Particle Web IDE

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Schematics

Piezo Hookup Diagram

Piezo sensor connected to Arduino with a 1MΩ resistor in parallel

Code

HueTapControl

C/C++
#include <HttpClient.h>

// Configuration

// 1. Replace this with your API username from Step 1
const String API_USERNAME = "OOeV6cZg0zhTu4wLriaTSYMU1VfnttWYzwlZtiPx";

// 2. Replace this with your bridge's IP address from Step 1
IPAddress hueIP(10,0,0,167);

// 3. Replace with the path to the lights you want to control. Use webpage from Step 1 to verify it works.
const String LIGHT_PATH = "/groups/2/action";

// 4. Replace this with the body of your request for turning the lights on.
const String REQUEST_BODY_ON = "{\"on\":true,\"bri\":254}";

// 5. Replace this with the body of your request for turning the lights off.
const String REQUEST_BODY_OFF = "{\"on\":false,\"bri\":254}";

#define PIEZO_PIN A0                // Analog input for piezo sensor
#define INTENSITY_THRESHOLD 117     // Threshold (0-1023) at which an intensity value is considered a tap
#define TAP_DECAY_TIME 100          // How long (milliseconds) to wait for sensor to settle (stop vibrating) after a tap
#define MIN_TIME_BETWEEN_TAPS 50    // Minimim time between taps in milliseconds
#define MAX_TIME_BETWEEN_TAPS 750   // Maximum time between taps in milliseconds
#define TRIGGER_NUM_TAPS 3          // Number of taps in a sequence that will trigger a light event

// Keep track of light state in this program
bool lightsOn = true;

// HttpClient object used to make HTTP requests to the Hue bridge
HttpClient http;

// Default header for HTTP requests
http_header_t headers[] = {
    { "Accept" , "*/*"},
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

// Request and response objects
http_request_t request;
http_response_t response;

void setup() {
    
    request.ip = hueIP;
    request.port = 80;
    
    // Onboard LED as indicator light for sensed tap
    pinMode(D7, OUTPUT);
}

void loop() {

  static int tapsInSequence = 0;
  static unsigned long lastTappedTime = millis();

  unsigned long currentTime = millis();

  if (isBeingTapped()) {
      
    digitalWrite(D7, HIGH);

    if (tapsInSequence == 0)
      tapsInSequence++;
    else {
      if (currentTime - lastTappedTime > MAX_TIME_BETWEEN_TAPS) {
        tapsInSequence = 1;
      } else {
        // within range
        tapsInSequence++;
      }
    }
    
    if (tapsInSequence == TRIGGER_NUM_TAPS) {
      toggleLights();
      tapsInSequence = 0;
    }

    lastTappedTime = currentTime;
    
    while (isBeingTapped()) delay(TAP_DECAY_TIME);

    delay(MIN_TIME_BETWEEN_TAPS);
    
    digitalWrite(D7, LOW);
  }

  
}

void setLights(bool on) {
    
    if (on) {
        request.path = "/api/" + API_USERNAME + LIGHT_PATH;
        request.body = REQUEST_BODY_ON;
    } else {
        request.path = "/api/" + API_USERNAME + LIGHT_PATH;
        request.body = REQUEST_BODY_OFF;
    }
    
    http.put(request, response, headers);
}

void printInfo() {
    Serial.print("Application>\tResponse status: ");
    Serial.println(response.status);

    Serial.print("Application>\tHTTP Response Body: ");
    Serial.println(response.body);
}

bool isBeingTapped() {
  return (analogRead(PIEZO_PIN) >= INTENSITY_THRESHOLD);
}

void toggleLights() {
  lightsOn = !lightsOn;

  setLights(lightsOn);
}

Credits

Will Freeman

Will Freeman

2 projects • 5 followers
Student at the University of Alabama in Huntsville (UAH). Ambassador of Hackster Live meetup at CoWorking Night.

Comments