Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Jan FischerPatrick Crutchfield
Published © GPL3+

Room Lights

My dorm's bedroom didn't come with lights, so I taped 15m of individually addressable RGB LEDs to my ceiling and control them through IoT.

BeginnerFull instructions provided2 hours13,680
Room Lights

Things used in this project

Hardware components

Photon
Particle Photon
×1
NeoPixel strip
NeoPixel strip
Can be any generic strip, I found mine on Amazon for around $25 I used 3 of the 5 meter ones to span entirely around my bedroom
×3
Jumper wires (generic)
Jumper wires (generic)
×1

Story

Read more

Schematics

Circuit Design

While you can include a voltage stepper, I have not had the time to do so yet and thus am just powering the device off of my computer's USB port via 10 foot USB cable.

Code

Second Particle Simple Controlling Software

C/C++
This is a simple debugging script used to control the main controller with a simple button push.
void setup(){
  pinMode(D1, INPUT);
}

void loop() {
  while(digitalRead(D1)==LOW){}
  Particle.publish("LightControllerInputFromSecondParticle", "Lights Med");
  delay(500);
  while(digitalRead(D1)==HIGH){}
  while(digitalRead(D1)==LOW){}
  Particle.publish("LightControllerInputFromSecondParticle", "Lights Off");
  delay(500);
  while(digitalRead(D1)==HIGH){}
}

Main Code V1

C/C++
This is the main code used to run the particle running the lights.
/*-------------------------------------------------------------------------
  Spark Core, Particle Photon, P1, Electron and RedBear Duo library to control
  WS2811/WS2812/WS2813 based RGB LED devices such as Adafruit NeoPixel strips.
  Supports:
  - 800 KHz WS2812, WS2812B, WS2813 and 400kHz bitstream and WS2811
  - 800 KHz bitstream SK6812RGBW (NeoPixel RGBW pixel strips)
    (use 'SK6812RGBW' as PIXEL_TYPE)
  Also supports:
  - Radio Shack Tri-Color Strip with TM1803 controller 400kHz bitstream.
  - TM1829 pixels
  PLEASE NOTE that the NeoPixels require 5V level inputs
  and the Spark Core, Particle Photon, P1, Electron and RedBear Duo only
  have 3.3V level outputs. Level shifting is necessary, but will require
  a fast device such as one of the following:
  [SN74HCT125N]
  http://www.digikey.com/product-detail/en/SN74HCT125N/296-8386-5-ND/376860
  [SN74HCT245N]
  http://www.digikey.com/product-detail/en/SN74HCT245N/296-1612-5-ND/277258
  Written by Phil Burgess / Paint Your Dragon for Adafruit Industries.
  Modified to work with Particle devices by Technobly.
  Contributions by PJRC and other members of the open source community.
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!
  --------------------------------------------------------------------*/

/* ======================= includes ================================= */


#include "Particle.h"
#include <neopixel.h>


/* ======================= prototypes =============================== */

void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t c, uint8_t wait);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);
uint32_t Wheel(byte WheelPos);


String LedMode = "off";
bool LedChange = false;
bool ShowChange = false;

int WaitTime = 50;


/* ======================= extra-examples.cpp ======================== */

SYSTEM_MODE(AUTOMATIC);

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 300
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812B

// Parameter 1 = number of pixels in strip
//               note: for some stripes like those with the TM1829, you
//                     need to count the number of segments, i.e. the
//                     number of controllers in your stripe, not the number
//                     of individual LEDs!
// Parameter 2 = pin number (most are valid)
//               note: if not specified, D2 is selected for you.
// Parameter 3 = pixel type [ WS2812, WS2812B, WS2812B2, WS2813, WS2811,
//                            TM1803, TM1829, SK6812RGBW, WS2812B_FAST,
//                            WS2812B2_FAST ]
//               note: if not specified, WS2812B is selected for you which
//                     is the same as WS2812 or WS2813 in operation.
//               note: RGB order is automatically applied to WS2811,
//                     WS2812/WS2812B/WS2812B2/WS2813/TM1803 is GRB order.
//               note: For legacy 50us reset pulse timing on WS2812/WS2812B
//                     or WS2812B2, select WS2812B_FAST or WS2812B2_FAST
//                     respectively.  Otherwise 300us timing will be used.
//
// 800 KHz bitstream 800 KHz bitstream (most NeoPixel products
//               WS2812/WS2813 (6-pin part)/WS2812B (4-pin part)/SK6812RGBW (RGB+W) )
//
// 400 KHz bitstream (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//                   (Radio Shack Tri-Color LED Strip - TM1803 driver
//                    NOTE: RS Tri-Color LED's are grouped in sets of 3)

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  Particle.function("light",setLight);
  Particle.subscribe("LightControllerInputFromSecondParticle", myHandler);
  //Particle.function("setWaitTime", setWaitTime);
  
}

void loop() {
    
    
    
    if(LedChange){
    
        LedChange = false;
        
        if(LedMode == "Off"){
            colorAll(strip.Color(0, 0, 0), 5);
        }
        else if(LedMode == "W_Low"){
            colorAll(strip.Color(60, 2, 50), 5);
        }
        else if(LedMode == "W_Med"){
            colorAll(strip.Color(120, 6, 100), 5);
        }
        else if(LedMode == "W_High"){
            colorAll(strip.Color(180, 15, 150), 5);
        }
        else if(LedMode == "R_Low"){
            colorAll(strip.Color(30, 0, 0), 5);
        }
        else if(LedMode == "R_Med"){
            colorAll(strip.Color(90, 0, 0), 5);
        }
        else if(LedMode == "R_High"){
            colorAll(strip.Color(180, 0, 0), 5);
        }
        else if(LedMode == "Y_Low"){
            colorAll(strip.Color(60, 0, 50), 5);
        }
        else if(LedMode == "Y_Med"){
            colorAll(strip.Color(120, 0, 100), 5);
        }
        else if(LedMode == "Y_High"){
            colorAll(strip.Color(180, 0, 150), 5);
        }
        else if(LedMode == "Rainbow"){
            uint16_t i, j = 0;
            while(!LedChange){
                if(j == 256){
                    j=0;
                }
                for(i=0; i<strip.numPixels(); i++) {
                    strip.setPixelColor(i, Wheel((i+j) & 255));
                }
                j++;
                strip.show();
                delay(WaitTime);
                
            }
        }
        
    }
    
    

  
  
  
  
  /*
  
  // Some example procedures showing how to display to the pixels:
  // Do not run more than 15 seconds of these, or the b/g tasks
  // will be blocked.
  //--------------------------------------------------------------

  //strip.setPixelColor(0, strip.Color(255, 0, 255));
  //strip.show();

  //colorWipe(strip.Color(255, 0, 0), 50); // Red

  //colorWipe(strip.Color(0, 255, 0), 50); // Green

  //colorWipe(strip.Color(0, 0, 255), 50); // Blue

  rainbow(20);

  //rainbowCycle(20);

  //colorAll(strip.Color(0, 255, 255), 50); // Cyan
*/

}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
  uint16_t i;

  for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(wait);
}

// Fill the dots one after the other with a color, wait (ms) after each one
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout, then wait (ms)
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) { // 1 cycle of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  
  
}


int setLight(String command){
    
    LedChange = true;
    
      if(command == "Lights Off"){
          LedMode = "Off";
      }
      else if(command == "Lights Low"){
          LedMode = "W_Low";
      }
      else if(command == "Lights Med"){
          LedMode = "W_Med";
      }
      else if(command == "Lights High"){
          LedMode = "W_High";
      }
      else if(command == "Red Low"){
          LedMode = "R_Low";
      }
      else if(command == "Red Med"){
          LedMode = "R_Med";
      }
      else if(command == "Red High"){
          LedMode = "R_High";
      }
      else if(command == "Yellow Low"){
          LedMode = "Y_Low";
      }
      else if(command == "Yellow"){
          LedMode = "Y_Med";
      }
      else if(command == "Yellow High"){
          LedMode = "Y_High";
      }
      else if(command == "Rainbow"){
          LedMode = "Rainbow";
      }

      
}

void myHandler(const char *event, const char *data){
    String data2 = (String)data;
    setLight(data2);
}
/*
int setWaitTime(String command){
    try{
        WaitTime = command.toInt();
    }catch(){
        
    }
}

*/

Credits

Jan Fischer
1 project • 2 followers
Patrick Crutchfield
1 project • 2 followers

Comments