D.I.Y internet controlled living room ambient light

I needed some light in my living room and decided to make it myself.

The lights are some cheap LED strips from eBay with a red, green and blue led on a little cluster.

Parts used for this project:

  • Arduino nano
  • Ethernet shield
  • ULN2003
  • LED strip
  • (20 plastic clips)
  • (3D printer)

It is made so the colors will fade between the selected, instead of just switching.

To set a color, call http://192.168.1.50/_255-255-255_ this will then stay for 60 seconds, and fade back to the sticky setting.
If you want to make a color stick, call http://192.168.1.50/_255-255-255_STICK and it will then fade to this. If someone else then changes the color without the STICK in the end, it will change to that color, and fade back to the setting you made with the STICK in the end.

This way people can still play with the light, without I have to worry about it being turned on all day.

 

 


(video parts start around 0:45)

#define fadeTime 1000   //How many milliseconds fading should take
#define tempSetSecs 60  //How many seconds we want the temp setting to stay

#define pinR 3
#define pinG 5
#define pinB 6

#define EthernetResetPin 2

//Used for ethernet
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 
  192, 168, 1, 50 };
byte gw[] = { 
  192, 168, 1, 1 };
byte subnet[] = { 
  255, 255, 255, 0 };
Server server(80);


//Color values
unsigned int stickR = 0;
unsigned int stickG = 0;
unsigned int stickB = 0;

unsigned int tempR = 0;
unsigned int tempG = 0;
unsigned int tempB = 0;
boolean tempActive = false;

//Boolean to define if the pwm should be changed
boolean updatePWM = true;

//When the temp color was set
unsigned long tempSet = 0;

//Smoothing of colors
#define numReadings 100

unsigned int S_index = 0;

unsigned int R_readings[numReadings];
unsigned int R_total = 0;
unsigned int R_average = 0;

unsigned int G_readings[numReadings];
unsigned int G_total = 0;
unsigned int G_average = 0;

unsigned int B_readings[numReadings];
unsigned int B_total = 0;
unsigned int B_average = 0;

unsigned long lastSmooth = 0;
int smoothSteps = 1;
#define smoothDelay (fadeTime-500)/numReadings

//#define debug 1

void setup()
{  
  for (int thisReading = 0; thisReading < numReadings; thisReading++) { R_readings[thisReading] = 0; G_readings[thisReading] = 0; B_readings[thisReading] = 0; } pinMode(pinR, OUTPUT); pinMode(pinG, OUTPUT); pinMode(pinB, OUTPUT); pinMode(EthernetResetPin, OUTPUT); digitalWrite(EthernetResetPin, LOW); digitalWrite(EthernetResetPin, HIGH); Ethernet.begin(mac, ip, gw, subnet); server.begin(); #ifdef debug Serial.begin(9600); #endif } void loop() { if ((millis() - tempSet) >= (tempSetSecs*1000UL) && tempActive)
 {
   smoothSteps = numReadings;
   tempActive = false;
 }  
  
  if ((millis()-lastSmooth) >= smoothDelay && smoothSteps > 0)
  {
    R_total -= R_readings[S_index];
    G_total -= G_readings[S_index];
    B_total -= B_readings[S_index];

    if (tempSet == 0 || (millis() - tempSet) >= (tempSetSecs*1000UL))
    {
      R_readings[S_index] = stickR;
      G_readings[S_index] = stickG;
      B_readings[S_index] = stickB;
    }
    else
    {
      R_readings[S_index] = tempR;
      G_readings[S_index] = tempG;
      B_readings[S_index] = tempB;
    }

    R_total += R_readings[S_index];
    G_total += G_readings[S_index];
    B_total += B_readings[S_index];

    S_index++;
    if (S_index >= numReadings) S_index = 0;

    R_average = R_total / numReadings;
    G_average = G_total / numReadings;
    B_average = B_total / numReadings;

    analogWrite(pinR, R_average);
    analogWrite(pinG, G_average);
    analogWrite(pinB, B_average);

#ifdef debug
    Serial.print("R ");
    Serial.print(R_average, DEC);
    Serial.print(" G ");
    Serial.print(G_average, DEC);
    Serial.print(" B ");
    Serial.println(B_average, DEC);
#endif

    lastSmooth = millis();
    smoothSteps--;
  }

  Client client = server.available();
  if (client)
  {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    String inString = String(35); //Used to hold the string from the ethernet shield

    while (client.connected()) //We got a client online
    {
      if (client.available())
      {
        char c = client.read();        
        inString += c;

        if (c == '\n' && currentLineIsBlank)
        {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          break;
        }

        if (c == '\n')
        {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r')
        {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }

    if (inString.indexOf("favicon.ico") > 0) //Do nothing about the favicon.ico request
    {
      client.stop();
      inString = "";
      return;
    }

    // give the web browser time to receive the data
    delay(1);

    int startCommand = inString.indexOf('_');
    int stopCommand = inString.indexOf('_', startCommand + 1);
    int startR = startCommand;
    int startG = inString.indexOf('-', startR + 1);
    int startB = inString.indexOf('-', startG + 1);

    if (startCommand > 0 && stopCommand > 0) // If we got a valid command...
    {
      client.print("R > ");
      client.println(inString.substring(startR+1, startG));
      client.print("
G > ");
      client.println(inString.substring(startG+1, startB));
      client.print("
B > ");
      client.println(inString.substring(startB+1, stopCommand));

      if (inString.indexOf("STICK") > 0) //Check if this is a value that will stick
      {
        client.print("

Sticky");

        stickR = string2Num(inString.substring(startR+1, startG));
        stickG = string2Num(inString.substring(startG+1, startB));
        stickB = string2Num(inString.substring(startB+1, stopCommand));
        tempSet = 0;
      }
      else
      {   
        tempR = string2Num(inString.substring(startR+1, startG));
        tempG = string2Num(inString.substring(startG+1, startB));
        tempB = string2Num(inString.substring(startB+1, stopCommand));
        tempSet = millis();
        tempActive = true;
      }
      
      //Set smoothSteps to the numbers of readings we use for fading
      smoothSteps = numReadings;
    }

    // close the connection:
    client.stop();

    inString = "";
  }
}

int string2Num(String input)
{
  char tempNum[10]; //Char to hold the message before converting it to an integer
  input.toCharArray(tempNum, 10);
  return atoi(tempNum); // Convert char array to an integer
}

Leave a Reply