Motion Sensing Lights

About the project

If you're trying to save energy, one way is to turn the lights off in rooms when you're not using them. But what about the hallway if you're always going up and down the stairs? You want something that lights automatically.

Project info

Difficulty: Easy

Platforms: Espruino

Estimated time: 1 hour

License: Apache License 2.0 (Apache-2.0)

Items used in this project

Hardware components

2621  ARM Espruino Pico 2621 ARM Espruino Pico x 1
WS2811 Lights WS2811 Lights x 1
A Pyroelectric motion sensor - or something else you can use to detect movement A Pyroelectric motion sensor - or something else you can use to detect movement http://www.espruino.com/Pyroelectric x 1

Story

If you're trying to save energy, one way is to turn the lights off in rooms when you're not using them. But what about the hallway if you're always going up and down the stairs? You want something that lights automatically.

Sure, you can buy those - but what if you want it to light up in an awesome way as well?


Wiring Up

Connect the Pyroelectric sensor as follows:

Connect the WS2811 lights as follows:

Software

Just copy and paste this into the right-hand window, then click the Send to Espruino button.


  1. // Set up the SPI port (for communications with the lights)
  2. SPI2.setup({baud:3200000, mosi:B15});
  3. // stores the timeout used to turn lights off
  4. var timeout;
  5. // stores the RGB data we want to send to our lights
  6. var rgb = new Uint8ClampedArray(25*3); // 25 x RGB lights
  7.  
  8. // Turn lights on
  9. function lightsOn() {
  10. digitalWrite(LED3,1); // turn blue LED on as indicator
  11. // Turn all lights on
  12. for (var i in rgb)
  13. rgb[i] = 255;
  14. // send data to the lights
  15. SPI2.send4bit(rgb, 0b0001, 0b0011);
  16. }
  17.  
  18. // turn lights off
  19. function lightsOff() {
  20. digitalWrite(LED3,0); // turn blue LED off as indicator
  21. // Turn all lights off
  22. for (var i in rgb)
  23. rgb[i] = 0;
  24. // send data to the lights
  25. SPI2.send4bit(rgb, 0b0001, 0b0011);
  26. }
  27.  
  28. // When the signal from the PIR changes...
  29. setWatch(function(e) {
  30. // If we had a timeout, it's because lights are already On.
  31. // clear it...
  32. if (timeout!==undefined)
  33. clearTimeout(timeout);
  34. else // otherwise turn the lights on
  35. lightsOn();
  36. // Now set a timeout to turn the lights off after 15 seconds
  37. timeout = setTimeout(function() {
  38. timeout = undefined;
  39. lightsOff();
  40. }, 15000);
  41. }, A1, { repeat:true, edge: "rising" });

Note, if you want to see what the signal you're getting from the PIR looks like, just add this command and it will use the red LED as an indicator:

  1. setInterval("digitalWrite(LED1,digitalRead(A1));",50);

The comments in the code describe pretty clearly what it's doing, but it's a bit boring really. It suddenly turns the lights on, and then suddenly turns them off after 15 seconds. Wouldn't it be better if they lit up smoothly?

Copy and paste the following into the right-hand window:

  1. // Set up the SPI port (for communications with the lights)
  2. SPI2.setup({baud:3200000, mosi:B15});
  3. // stores the timeout used to turn lights off
  4. var timeout;
  5. // stores the RGB data we want to send to our lights
  6. var rgb = new Uint8ClampedArray(25*3); // 25 x RGB lights
  7.  
  8. // Turn lights on
  9. function lightsOn() {
  10. digitalWrite(LED3,1); // turn blue LED on as indicator
  11. // animate to turn lights on
  12. var pos = 0;
  13. var interval = setInterval(function() {
  14. pos += 0.025;
  15. if (pos>=1) clearInterval(interval);
  16. // Work out colours - fade in from one end
  17. for (var i=0;i=1) clearInterval(interval);
  18. // Work out colours - fade all out the same amount
  19. var amtr = (1-pos)*255; // red
  20. var amtg = (1-pos*1.5)*255; // green
  21. var amtb = (1-pos*2)*255; // blue
  22. for (var i=0;i

Now the lights will smoothly turn on, and smoothly turn off.

Because the code above is written in an event-based way (listening for movement using setWatch, rather than 'polling' using setInterval), you can add the setDeepSleep(true); command. This will send the Espruino board into a very low power sleep mode - which means that the whole project can run on batteries for a long time. Having said that, the LED strip draws around 20mA even when all LEDs are off - so if you want seriously low power you'll have to use a relay or FET on the 5v line of the LED string to ensure that when the LEDs are off, they are not drawing any power at all.
Another good addition to this would be a Light Dependent Resistor, so that you could detect when the area was light enough that the lights do not need to light up.

Credits

Photo of Espruino

Espruino

Espruino, Espruino Pico and Puck.js are low-power Microcontrollers that run JavaScript. Espruino is a JavaScript Interpreter for Microcontrollers that is designed to make development quick and easy. The Espruino interpreter is firmware that runs on a variety of different microcontrollers, but we also make Espruino Boards that come with the interpreter pre-installed and are the easiest devices to get started with. However Espruino itself isn't just the interpreter firmware or hardware - there's also the Web IDE, command-line tools, documentation, tutorials, and modules that form a complete solution for embedded software development.

   

Leave your feedback...