Juan Pablo Risso
Published

Kid Proof Smart LEDStrip

Fun project for my son's bedroom

Full instructions provided2,559
Kid Proof Smart LEDStrip

Things used in this project

Hardware components

Spark Core
Particle Spark Core
×1
NeoPixels LED Strip
×1
Samsung SmartThings Multipurpose Sensor
Samsung SmartThings Multipurpose Sensor
×1
Staples Easy Button
×1

Story

Read more

Code

file_7063.txt

C/C++
// This #include statement was automatically added by the Spark IDE.
#include "neopixel/neopixel.h"

#include "math.h"


#define NEOPIXEL_PIN A1 //data pin for the neopixel LEDs
#define NEOPIXEL_COUNT 30 //# of LEDs
#define NEOPIXEL_TYPE WS2812B //type of LEDs

double lightState = 0; //variable for keeping track of the brightness value for the lamp.
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEOPIXEL_TYPE); //setup neopixel strip
uint32_t color = strip.Color(255, 255, 255); //set color of LEDs to imitate tungsten light via RGB 
int top = D3; // Define encoder pin A (The top pin)
int bottom = D4;// Define encoder pin B (The bottom pin)
int count = 0; // pre-initiate the count of the encoder to zero for debugging
int topVal = LOW; // pre-initiate the state of pin A to low
int topLast = LOW; // make its last value the same
int bottomVal = LOW; // make the bottom value low 
int inputPin = D5; //pin for reading value of pushbutton fucntionality
int led = D7; 
int point = 0; //index for array based dim value
int val = 0; //pushbutton state value
double brightness[] = {0.0, 0.11493046921721886, 0.250704760561023, 0.411103115457414, 0.6005913609774866, 0.8244452478422774, 1.0888973384030416, 1.401310534266823, 1.7703830749408593, 2.206390715088621, 2.721472823120924, 3.3299703667077485, 4.048825195437263, 4.898051737489861, 5.901294243353279, 7.086485091414136, 8.486622484036182, 10.14068918681737, 12.094737890656232, 14.403173415386968, 17.130267454225375, 20.351948032692242, 24.157913504308894, 28.654129941144937, 33.965781451816035, 40.24075556998111, 47.653760753874806, 56.41119063670973, 66.75687045889588, 78.97884567481861, 93.41740174324569, 110.4745383891715, 130.62516212044608, 154.43030862235864, 182.55276316941087, 215.77551395934938, 255.0};

/*
 * setup() - this function runs once when you turn your Arduino one
 * We set the motors pin to be an output (turning the pin high (+5v) or low (ground) (-))
 * rather than an input (checking whether a pin is high or low)
 */
void setup(){
    
    strip.begin();
    pinMode(top, INPUT);  // setup the pins as inputs
    pinMode(bottom, INPUT);
    pinMode(inputPin, INPUT);
    pinMode(led, OUTPUT);    
    
    for(int i = 0; i < strip.numPixels(); i++) {//set pixels to given RGB color
        strip.setPixelColor(i, color);
    }
    
    strip.setBrightness(lightState);//set LEDs to lightState(init. 0)
    strip.show();
    Spark.function("ledstate", turnTo); //Setup Spark turnTo function for remote dimmability
    Serial.begin(9600); //Serial for debugging
}


/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called motorOnThenOff()
 */

void loop(){
    // Nothing here
}

/*
turnTo() is a handler function for the Spark.function "turnTo" turning the lamp to a given state.
The sole parameter "command" is supposed to be a string representation of an integer between 0 and 255 that
represents the state to write to the lamp.

*/
int turnTo(String command){
    String aux1 = getValue(command, ',', 0);
    String aux2 = getValue(command, ',', 1);
    String aux3 = getValue(command, ',', 2);
    String aux4 = getValue(command, ',', 3);
    
    int color1 = atoi(aux1.c_str());
    int color2 = atoi(aux2.c_str());
    int color3 = atoi(aux3.c_str());    
  
    int dim = atoi(aux4.c_str())*2.55; ;//parse the string into an integer
    
    color = strip.Color(color1, color2, color3); //set color of LEDs to imitate tungsten light via RGB 
    
    for(int i = 0; i < strip.numPixels(); i++) {//set LEDs to color
        strip.setPixelColor(i, color);
    }
    
    if (dim < 0 || dim > 255) {//if state out of bounds, return
        return 1;
    }
    
    lightState = dim;//else set local state equal to state
    point = indexRet(lightState);//set the index of the array to the closest brightness to current brightness #see indexRet().
    Serial.println("lightState: " + String(lightState));
    delay(10);
    strip.setBrightness(lightState);//set brightness to lightState    
    Serial.print("Color: (" + String(color1)); //print for debugging
    Serial.print(", " + String(color2)); //print for debugging
    Serial.print(", " + String(color3)); //print for debugging
    Serial.println("), dim value: " + String(dim)); //print for debugging    
    strip.show();
    
    if (dim == 0) {
        digitalWrite(led, LOW);    // Turn OFF the LED        
    } else {
        digitalWrite(led, HIGH);    // Turn ON the LED        
    }
    
    return dim;
}

/*
turnUp() is a function for turning the lamp up, using a point value to index the brightness state from the brightness array.

*/
int turnUp(){
    if (lightState < 247) {//if light less than full
        point++; //increment index
        lightState = brightness[point]; //set local state brightness to new value
    } else if (lightState >= 247){ // if light full
        point = 37; //set index to max value
        lightState = 255; //set local state to max value
    }
    for(int i = 0; i < strip.numPixels(); i++) {//set LEDs to color
        strip.setPixelColor(i, color);
    }
    
    strip.setBrightness(lightState); //set brightness of LEDs to lightState
    strip.show();
    Serial.println(lightState); //print for debugging
    return 1;
}

/*
turnDown() is a function for turning the lamp down, using a point value to index the brightness state from the brightness array.

*/
int turnDown(){
    if (lightState > 0) {//if lamp on
        point--;//decrement index
        lightState = brightness[point];//set local state brightness to new value
    } else if (lightState <= 0) { // if lamp off
        lightState = 0;//set local brightness state to 0
        point = 5; //set index to 5, boundary between visible light and none for dimming function.
    }
    
    for(int i = 0; i < strip.numPixels(); i++) {
        strip.setPixelColor(i, color);
    }
    
    strip.setBrightness(lightState);
    strip.show();
    Serial.println(lightState);
    return 1;
}

/*
indexRet() takes in a given lightState and returns the index of the array that is closest to a given brightness. 
This ensures a smooth transition between physical and cloud dimming; no sporadic jumps between brightness.
*/
int indexRet(double lightState){
    double index = log(1.578*lightState + 1); //conversion function for returning raw value between 0 and 6 (1/6 steps)
    int point = (int) 6*index; //adjustment for returning index between 0 and 36
    return point;
}

String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

file_7064.groovy

Groovy
/**
 *  Spark Core
 *
 *  Author: juano23@gmail.com
 *  Date: 2014-01-23
 */
 
 preferences {
    input("deviceId", "text", title: "Device ID")
    input("token", "text", title: "Access Token")
}
 
 // for the UI
metadata {
    // Automatically generated. Make future change here.
	definition (name: "Spark LED Strip", author: "juano23@gmail.com") {
    	capability "Switch"
        capability "Switch Level"
        
		attribute "level", "string"        
		attribute "color", "string"
		attribute "whitestate", "string"        

		command "fade"
		command "red"
		command "blue"
		command "green"
		command "yellow"
		command "violet"
		command "orange"
		command "flash"
		command "cool"
		command "warm"
		command "white1"        
		command "white2"
		command "white3"
		command "white4"

	}

	// tile 
	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: false) {
			state "on", label:'${name}', action:"switch.off", icon:"st.Lighting.light21", backgroundColor:"#79b821", nextState:"off"
			state "off", label:'${name}', action:"switch.on", icon:"st.Lighting.light21", backgroundColor:"#ffffff", nextState:"on"
		}
		controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
			state "level", label: "Dimmer", action:"switch level.setLevel"
		}
		standardTile("tempup", "device.switch", width: 1, height: 1, canChangeIcon: false, decoration: "flat") {
			state "cool", label:'${name}', action:"cool", icon:"st.thermostat.thermostat-down"
		}
		standardTile("tempdown", "device.switch", width: 1, height: 1, canChangeIcon: false, decoration: "flat") {
			state "warm", label:'${name}', action:"warm", icon:"st.thermostat.thermostat-up"
		}
        standardTile("White", "device.whitestate", height:1, width:1) {
            state "1", label:'White', action:"white1", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#ffffff", nextState: "1"
            state "2", label:'White 1', action:"white2", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#ffffff", nextState: "2"
            state "3", label:'White 2', action:"white3", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#ffffff", nextState: "3"
            state "4", label:'White 3', action:"white4", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#ffffff", nextState: "4"           
        }       
        standardTile("Red", "device.red", height:1, width:1) {
            state "default", label:'Red', action:"red", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#EE2C2C"
        }    
        standardTile("Yellow", "device.yellow", height:1, width:1) {
            state "default", label:'Yellow', action:"yellow", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#FFE303"
        }    
        standardTile("Orange", "device.orange", height:1, width:1) {
            state "default", label:'Orange', action:"orange", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#FFAA00"
        }    
        standardTile("Green", "device.green", height:1, width:1) {
            state "default", label:'Green', action:"green", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#66CD00"
        }    
        standardTile("Blue", "device.blue", height:1, width:1) {
            state "default", label:'Blue', action:"blue", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#0276FD"
        } 
        standardTile("Violet", "device.violet", height:1, width:1) {
            state "default", label:'Purple', action:"violet", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#BF5FFF"
        }     
        standardTile("Fade", "device.fade", height:1, width:1, decoration: "flat") {
            state "default", label:"Fade", action:"fade", unit:"", icon:"st.illuminance.illuminance.light", backgroundColor: "#ffffff"
        }          
		standardTile("Flash", "device.flash", inactiveLabel: false, decoration: "flat") {
			state "default", label:"Flash", action:"flash",  icon:"st.illuminance.illuminance.bright"
		}

		main(["switch"])
		details(["switch","tempdown","tempup", "levelSliderControl","White","Red","Orange","Yellow","Green","Blue","Violet"])
	}
}

def parse(String description) {
	log.error "This device does not support incoming events"
	return null
}

def white1() {
    sendEvent(name: "color", value: "255,255,255,");
	put();
}

def white2() {
    sendEvent(name: "color", value: "255,150,150,");
	put();
}

def white3() {
    sendEvent(name: "color", value: "255,150,100,");
	put();
}

def white4() {
    sendEvent(name: "color", value: "255,150,50,");   
	put();
}

def red() {
    sendEvent(name: "color", value: "255,0,0,")
	put();
}

def blue() {
    sendEvent(name: "color", value: "0,0,255,")
	put();
}

def green() {
    sendEvent(name: "color", value: "0,255,0,")
	put();
}

def yellow() {
    sendEvent(name: "color", value: "255,255,0,")
	put();
}

def orange() {
    sendEvent(name: "color", value: "255,100,0,")
	put();
}

def violet() {
    sendEvent(name: "color", value: "255,0,255,")
	put();
}

def warm() {
	def white = device.currentValue("whitestate") != null ? device.currentValue("whitestate") : "1"
	log.debug "Next white...$white"
    if (white == "1") {white2()};   
    if (white == "2") {white3()};  
	if (white == "3") {white4()};     
    if (white != "4") {sendEvent(name:"whitestate", value: Integer.parseInt(white) + 1)};        
    
}

def cool() {
	def white = device.currentValue("whitestate") != null ? device.currentValue("whitestate") : "1"
    log.debug "Previus white... $white"
    if (white == "4") {white3()};   
    if (white == "3") {white2()}; 
    if (white == "2") {white1()};       
    if (white != "1") {sendEvent(name:"whitestate", value: Integer.parseInt(white) - 1)};    
}

def off() {
    setLevel(0) 
}

def on() {
    setLevel(100)
}

def setLevel(value) {
    def level = value as Integer    
	if (level <= 0){
    	sendEvent(name: "switch", value: "off");    
    } else {
    	sendEvent(name: "switch", value: "on");       
	}    
	sendEvent(name: "level", value: value)   
    put();
	sendEvent(name: "level", value: value)   
    put();    
}

private put() {
    //Spark Core API Call
	httpPost(
		uri: "https://api.spark.io/v1/devices/${deviceId}/ledstate",
        body: [access_token: token, command: device.currentValue("color") + device.currentValue("level")],  
	) {response -> log.debug (response.data)}
    log.debug device.currentValue("color") + device.currentValue("level") + ',' +device.currentValue("whitestate");
} 

Credits

Juan Pablo Risso

Juan Pablo Risso

6 projects • 33 followers
I am a geek, technology Innovator, Software Engineer and Maker. I work at Samsung / SmartThings propelling the Internet of Things.

Comments