Close

Results 1 to 3 of 3
  1. #1
    DF VIP Member
    beerman's Avatar
    Join Date
    May 2001
    Location
    29 Acacia Road
    Posts
    8,446
    Thanks
    1,080
    Thanked:        1,626
    Karma Level
    956

    Default £5 DIY Philips Hue Motion sensor

    I already have one motion sensor in the house but wanted a cheaper option to add to a few more rooms. Philips want £30 per sensor and I can make this for around £5 and a 3 week wait from China. Sure it hasn't got an ambient light sensor like the philips but that isn't needed for me, I could always add one later anyway for under £2.





    It consists of a Wemos D1 mini and a HC-SR501 PIR sensor.


    Instructions:
    Wire up your PIR as follows:

    Wemos D1 --> PIR signal (middle wire)
    Wemos 5v --> PIR 5v (left wire when connector is facing you)
    Wemos GND --> PIR GND (Right wire)





    Set up the bridge to allow the connection. Follow this guide to set up your unique user ID.
    https://developers.meethue.com/docum...etting-started


    Set up the arduino:
    First you'll need to add the ESP8266 library to your Arduino install.

    Go to Sketch--->Include Library--->Manage Libraries

    Install the ESP8266Wifi by Ivan Grokhotkov library.

    Copy and paste the following. Don't use the code on the guys github as it's slightly wrong (it's missing the HTTP/1.1 string on the end of the PUT command), this one is tested working.


    Code:
    /*
      esp8266Huemotion
      https://github.com/LeskoIam/esp8266Huemotion
      polensek.matevz@gmail.com
    
      Used instead of very expensive Hue motion sensor.
      It's basicly a D1 mini, which breaks out pins from esp8266 WiFi module and adds some
      periphery to enable USB serial communication.
    
      Operation:
      It uses PIR sensor attached to pin D1 (arduino library maps this pin to pin 5) to
      detect motion and turn on specified Hue light bulb if all conditions are met. These
      conditions are:
        - It's night time. This is determined based on if specified light bulb is on or off.
          State of the light bulb is checked and updated every set number of minutes
          ("lights_check_delay").
        - If motion is detected. Specified light bulb is turned on for set amount of time
          ("motion_detected_delay"). Motion is still detected and updated when light is turned on,
          this means light is turned off only after no motion is detected for set delay.
      
      Deep sleep:
      If enabled, you can put module to sleep while "lights_check_delay" is active. It can conserve
      a lot of power and is specialy useful when module is powered with batteries. This is controlled
      with "use_deep_sleep" variable.
      Minor hardware modification is also necessary. Connect D0 pin to RST pin. This connection is 
      used to wake up the module after sleep period is over.
      
      The circuit:
      - Philips Hue lights
      - D1 mini or clone (esp8266).
      - PIR motion sensor (HC-SR501).
    
      Settings:
      Look for code in #### block.
      Mandatory settings:
        - use_deep_sleep
        - ssid
        - password
        - bridge_ip, port
        - user
        - light
      Optional:
        - motion_detected_delay
        - lights_check_delay
        - hue_on
        - hue_off
    
    */
    #include <ESP8266WiFi.h>
    
    //// Global settings and variables
    // ################################################
    // Deep Sleep
    bool use_deep_sleep = 0;  // If deep sleep is enable don't forget to connect D0 to RST pin
    // Wifi Settings
    const char* ssid = "YOURSSID";
    const char* password = "YOURPASSWORD";
    
    // Hue settings
    const char* bridge_ip = "YOURBRIDGEIP";  // Hue bridge IP
    const int port = 80;
    String user = "YOURUSERNAME";
    String light = "YOURLIGHTNUMBER";  // Number of the light you want to control
    
    // Motion timing
    unsigned long motion_detected_time = 0;         // When was motion last detected
    unsigned long motion_detected_delay = 60*1000;  // Keep light on for that many seconds after last motion was detected
    
    // All lights off check timing
    unsigned long lights_check_time = 0;            // When was light state last checked
    unsigned long lights_check_delay = 1*60*1000;   // Check light state every that many minutes
    
    // Commands
    String hue_on = "{\"on\":true, \"bri\":5, \"xy\":[0.1540,0.0806]}";
    String hue_off = "{\"on\":false}";
    // ################################################
    
    // Pin settings
    // PIR sensor is attached to D1 mini D1 pin which maps to pin 5 for arduino library
    int pirPin = 5;
    
    int light_state = 0;              // Internally track state of light
    int first_loop = 1;               // Is this first loop
    int check_lights_first_loop = 1;  // Same as above but for checking light state
    bool night_time;                  // master logic variable
    
    void setup()
    {
      Serial.begin(115200);
      delay(10);
      
      // Connect to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
      
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println();
      Serial.println("WiFi connected");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
      Serial.println();
      Serial.print("MAC: ");
      Serial.println(WiFi.macAddress());
    
      // Set PIR pin as input pin
      pinMode(pirPin, INPUT);
      if (use_deep_sleep)
      {
        // Connect D0 to RST to wake up
        pinMode(16, WAKEUP_PULLUP);
      }
    
      Serial.println("Waiting 2 seconds for stable sensor readings...");
      delay(1000);
      Serial.println("Setup done. Main loop starting in a second...");
      delay(1000);
      Serial.println();
    }
    
    void loop() 
    {
      //// Check state of the light and set nigh_time accordingly
      if ((((lights_check_time + lights_check_delay) < millis()) || check_lights_first_loop == 1) && (light_state != 1))
      {
        Serial.print("Checking state of light ");
        Serial.println(light);
        check_lights_first_loop = 0;
        if (is_light_on() == 1) { night_time = 0; }
        else { night_time = 1; }
        lights_check_time = millis();
        if (use_deep_sleep)
        {
          if (!night_time)
          {
            // Go to deep sleep. Don't forget to convert milliseconds to microseconds
            Serial.printf("\nDEEP SLEEP for %i microseconds\n\n", lights_check_delay*1000);
            ESP.deepSleep(lights_check_delay * 1000);
          }
        }
      }
    
      
    
      // Some debug prints
      Serial.println("-----");
      Serial.print("night_time: ");
      Serial.println(night_time);
      Serial.print("motion_detected_time: ");
      Serial.println(motion_detected_time);
      Serial.print("light_state: ");
      Serial.println(light_state);
    
      //// Main motion-light logic
      // Enter only if it is nigh time and ligh is not on because of us
      if ((night_time == 1) || (light_state == 1))
      {
        // Read PIR sensor
        int motion = digitalRead(pirPin);
        Serial.print("motion: ");
        Serial.println(motion);
    
        // If motion is detected
        if (motion == HIGH)
        {
          // And light is off because of us.
          // This also prevents multiple turn ons (sensor output stays on for around 2 seconds)
          if (light_state == 0)
          {
            // Turn light on only if previous on time delay has passed or if this is first loop
            // first_loop check was added to handle situation when motion-light has
            // not yet been running for more than motion delay time
            if (((motion_detected_time + motion_detected_delay) < millis()) || first_loop == 1)
            {
              Serial.println("Turning light on");
              light_control(hue_on);
              light_state = 1;
              first_loop = 0;
            }
          }
          // Detect every motion and update detection time
          motion_detected_time = millis();
        }
        else
        {
          // Only turn off light if they were turned on by us
          if (light_state == 1)
          {
            // Turn light off only if on time delay has passed
            if ((motion_detected_time + motion_detected_delay) < millis())
            {
              Serial.print("No motion for ");
              Serial.print(motion_detected_delay/1000);
              Serial.println(" seconds. Turning light off");
              light_control(hue_off);
              light_state = 0;
            }
          }
        }
      }
      delay(333);
    }
    
    
    /*  light_control.
     *  Send PUT command to hue light (bridge). Function takes json formated command.
     *  Returns:
     *  1 if operation successful
     *  0 if operation not successful
     *  -1 if error occurred 
     */
    bool light_control(String command)
    {
      int retval = 0;     // return value
      WiFiClient client;  // WiFiClient class to create TCP connections
      
      if (!client.connect(bridge_ip, port))
      {
        Serial.println("ERR>> light_control - Connection failed");
        return -1;
      }
      
      // This will send PUT request to the server
      client.println("PUT /api/" + user + "/lights/" + light + "/state  HTTP/1.1");
      client.println("Host: " + String(bridge_ip) + ":" + String(port));
      client.println("User-Agent: ESP8266/1.0");
      client.println("Connection: keep-alive");
      client.println("Content-type: text/xml; charset=\"utf-8\"");
      client.print("Content-Length: ");
      client.println(command.length()); // PUT COMMAND HERE
      client.println();
      client.println(command); // PUT COMMAND HERE
    
      // Wait 10 seconds for server to respond
      unsigned long timeout = millis();
      while (client.available() == 0)
      {
        if (millis() - timeout > 10000)
        {
          Serial.println("ERR>> light_control - Client timeout");
          client.stop();
          return -1;
        }
      }
      
      // Read all the lines of the reply from server
      while(client.available())
      {
        String line = client.readStringUntil('\r');
        // Print line to serial if it's request status or json formated string
        if (((line.indexOf("{") != -1) && (line.indexOf("}") != -1)) || (line.indexOf("HTTP") != -1)){ Serial.print(line); }
        // If success string is found in reply we have successfully sexecuted command
        if (line.indexOf("\"success\":") != -1){ retval = 1; }
      }
      Serial.println();
      client.stop();
      return retval;
    }
    
    /*  are_all_lights_on
     *  Returns:
     *  1 if operation successful
     *  0 if operation not successful
     *  -1 if error occurred 
     */
    bool are_all_lights_on()
    {
      int retval = 0;     // return value
      WiFiClient client;  // WiFiClient class to create TCP connections
      
      if (!client.connect(bridge_ip, port))
      {
        Serial.println("ERR>> are_all_lights_on - Connection failed");
        return -1;
      }
      
      // This will send GET request to the server
      client.println("GET /api/" + user + "/lights HTTP/1.1");
      client.println("Host: " + String(bridge_ip) + ":" + String(port));
      client.println("Connection: close");
    
      // Wait maximum of 10 seconds for server to respond
      unsigned long timeout = millis();
      while (client.available() == 0)
      {
        if (millis() - timeout > 10000)
        {
          Serial.println("ERR>> are_all_lights_on - Client timeout");
          client.stop();
          return -1;
        }
      }
      
      // Read all the lines of the reply from server
      while(client.available())
      {
        String line = client.readStringUntil('\r');
        // Print line to serial if it's request status or json formated string
        if (((line.indexOf("{") != -1) && (line.indexOf("}") != -1)) || (line.indexOf("HTTP") != -1)){ Serial.print(line); }
        // If any light is off - all lights are not on
        if (line.indexOf("\"on\":false") == -1){ retval = 1; }
      }
      Serial.println();
      client.stop();
      return retval;
    }
    
    /* is_light_on.
     *  Returns:
     *  1 if operation successful
     *  0 if operation not successful
     *  -1 if error occurred 
     */
    bool is_light_on()
    {
      int retval = 0;
      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      
      if (!client.connect(bridge_ip, port))
      {
        Serial.println("ERR>> is_light_on - Connection failed");
        return -1;
      }
      
      // This will send GET request to the server
      client.println("GET /api/" + user + "/lights/" + light);
      client.println("Host: " + String(bridge_ip) + ":" + String(port));
      client.println("Connection: close");
      
      // Wait maximum of 10 seconds for server to respond
      unsigned long timeout = millis();
      while (client.available() == 0)
      {
        if (millis() - timeout > 10000)
        {
          Serial.println("ERR>> is_light_on - Client timeout");
          client.stop();
          return -1;
        }
      }
      
      // Read all the lines of the reply from server and print them to Serial
      while(client.available())
      {
        String line = client.readStringUntil('\r');
        // Print line to serial if it's request status or json formated string
        if (((line.indexOf("{") != -1) && (line.indexOf("}") != -1)) || (line.indexOf("HTTP") != -1)){ Serial.print(line); }
        // Check if light is on
        if (line.indexOf("\"on\":true") != -1){ retval = 1; }
      }
      Serial.println();
      client.stop();
      return retval;
    }
    Change the global variables for your SSID, password, bridge IP address, user ID and light number you want to control. You can also change how long you want it to stay on for. The Wemos will also go into deep sleep until new motion if the "use_deep_sleep" is set to 1. If you do this you will need to connect the D0 and RST pins of the Wemos.

    Upload the code to your Wemos and that's it apart from printing your case.
    https://www.thingiverse.com/thing:2955991

    4 Thanks given to beerman

    Ashley (14th June 2018),  evilsatan (14th June 2018),  MHP (15th June 2018),  Over Carl (14th June 2018)  


  2. #2
    DF Super Moderator piggzy's Avatar
    Join Date
    Jul 2014
    Location
    UK
    Posts
    3,540
    Thanks
    3,063
    Thanked:        1,553
    Karma Level
    371

    Default Re: £5 DIY Philips Hue Motion sensor

    So this would work in conjunction with a google home etc

  3. #3
    DF VIP Member
    beerman's Avatar
    Join Date
    May 2001
    Location
    29 Acacia Road
    Posts
    8,446
    Thanks
    1,080
    Thanked:        1,626
    Karma Level
    956

    Default Re: £5 DIY Philips Hue Motion sensor

    Quote Originally Posted by piggzy View Post
    So this would work in conjunction with a google home etc
    To do what though, it doesn't really affect anything on the google home? All it does at the moment is detect motion and send a command to my Philips Hue bridge which turns on the light/light group. It then starts a timer to count to 60 seconds, if no more motion is in that period it turns the light/light group off.

    But in actual answer to your question, yes you can use it in conjunction with the google home.

Similar Threads

  1. £5 DIY Philips Hue Motion sensor
    By beerman in forum Home Audio/Video, Electronic Toys & Gadgets
    Replies: 2
    Last Post: 14th June 2018, 08:32 PM
  2. Need An MAF Sensor!
    By super mike in forum Cars & Motorbikes
    Replies: 8
    Last Post: 9th December 2009, 06:41 PM
  3. Replies: 2
    Last Post: 14th May 2008, 06:56 PM
  4. Motion Sensor
    By QfanatiQ in forum Nintendo Consoles
    Replies: 0
    Last Post: 4th July 2007, 11:38 AM

Social Networking Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •