Finals: Let there be light!

The proposed lamp will change color temperature across the day in a pattern which follows the natural path of the sun. It will be warmer in the mornings and evenings and cool white during the day. The brightness of the surroundings will change the brightness of the lamp.

Paper.Light.28 4.png

Currently, the circuit to light up the lamp and change its color temperature is working as seen in the video below:

Wandering on the 5th floor

The 5th floor is a pretty onerous floor with overbearing walls and claustrophobic passages. Trying to find an interesting lighting moment was pretty bleak but I found that some of the open spaces had interesting spot lights. Now, spot lights are not something that would strike me as an addition inside a house but I liked how they create a sense of drama and highlight in an otherwise boring space. the light shimmering off the curtain was also an interesting effect to observe. The interplay of light and cloth was pretty awesome to observe and while we do not think of matching textures to color, it adds an interesting effect to play around with. With small bright LEDs appearing on the horizon and getting affordable, are they going to be used more in home lighting?

Average light: 200 LUX

The walls of the corridor need more diffused light and a warmer color.

IMG_20190501_062520.jpg

Huehuehue

For this week’s assignment, we had to make a web dashboard for controlling a Philips Hue bulb. I was pretty stretched for time this week so I decided to keep things simple and learn the basics. Going through the tutorial was pretty self-explanatory and the code on github was pretty logical. However, I tripped up with the call-backs and it was quite confusing for me to understand. Thankfully, I read through Timothy and Atharva’s blog and their call-backs made sense to me. I created a basic UI where the Hue can be controlled by changing it’s Hue, Saturation and Brightness values through sliders and also gave the users the option to turn it on and off. I was also changing the background of the webpage to match the color of the Hue bulb.

Screenshot 2019-02-12 04.26.39.png


I was looking at changing the color of the text to a complementary color based on the currently selected value but did not find any easy way to convert HSB values to its complementary colors. Also, I had thought of an ambient mode where the digits of HH:MM:SS are converted into a RGB hex value which is then transmitted to the hue. Again, I tripped up because I could not find a reliable way to do this. Passing RGB to HSL did not match the colors. So my top questions for this week would be:

1) How do you calculate the complementary HSB value of a color through code?

2) How do you convert a rgb color to a HSB color?

Currently listening: A whiter shade of pale - Procol Harum

/* 
References used: 
https://www.thatworkedyesterday.com/blog/2019/2/12/connected-devices-web-interface-for-hue

https://github.com/tigoe/hue-control/blob/master/client-example/public/single-lamp.js

*/

//IP address of Philips Hue
let IPHub = '128.122.151.172';
let userName = 'Your user name goes here'; // My user name as per the hue developer API
let url;

//Font
let gotham;

//Variables for display of controls and labels
let checkBox;
let hueSlide;
let hueText;
let satSlide;
let satText;
let brightSlide;
let brightText;

//Variables for controlling the philips bulb and its color
let lightNum = 1;
let hueVal = 32767;
let satVal = 127;
let brightVal = 127;

//Loading fonts
function preload() {
  gotham = loadFont('assets/Gotham Book.otf');
}

function setup() {

  //Create canvas
  canvas = createCanvas(windowWidth, windowHeight);
  canvas.background(hueVal, satVal, brightVal);

  //Declare Hue URL
  url = "http://" + IPHub + "/api" + userName;

  //Position ON/OFF checkbox
  checkBox = createCheckbox(' IS ON/OFF', false);
  checkBox.position(canvas.width / 2 - 90, 200);
  checkBox.class('lightSwitch');
  checkBox.mouseClicked(toggleLight);

  //Position Sliders for color control
  hueSlide = createSlider(0, 65535, 32767, 100);
  hueSlide.position(canvas.width / 2 - 225, 400);
  hueSlide.style('rotate', 90);

  satSlide = createSlider(0, 254, 127, 1);
  satSlide.position(canvas.width / 2 - 100, 400);
  satSlide.style('rotate', 90);

  brightSlide = createSlider(1, 255, 127, 1);
  brightSlide.position(canvas.width / 2 + 25, 400);
  brightSlide.style('rotate', 90);

  //Position button for 'Ambient Mode'
  button = createButton('Ambient mode');
  button.position(canvas.width / 2 - 85, 600);
  button.mousePressed(changeBG);

}

function draw() {

  colorMode(HSB);

  if (hueSlide.value() != hueVal || satSlide.value() != satVal || brightSlide.value() != brightVal) {

    //Change color
    changeLightColour();

    //Capture slider value
    hueVal = hueSlide.value();
    satVal = satSlide.value();
    brightVal = brightSlide.value();

    //Change background
    colorMode(HSB, 65535, 254, 255);
    background(65535 - hueVal, 254 - satVal, 255 - brightVal);

    //Display text
    textFont(gotham);
    textSize(width / 15);
    textAlign(CENTER, CENTER);
    text('Huehuehue', width / 2, 100);

    hueText = textSize(width / 60);
    hueText.text('Hue', canvas.width / 2 - 160, 500);

    satText = textSize(width / 60);
    satText.text('Sat', canvas.width / 2 - 35, 500);

    brightText = textSize(width / 60);
    brightText.text('Brightness', canvas.width / 2 + 100, 500);

  }
}

function toggleLight() {

  let path = url + '/lights'
  httpDo(path, 'GET', toggleGetResponse);

}

function toggleGetResponse(getData) {

  let lights = JSON.parse(getData);
  lightState = lights["1"].state.on

  let body = {
    'on': !lightState
  };
  let path = url + '/lights/' + lightNum + '/state/'
  httpDo(path, 'PUT', body, togglePutData);

}

function togglePutData(putData) {

  var response = JSON.stringify(putData);
  if (response.includes("success")) {
    lightState = !lightState
  }
}

function changeLightColour() {
  var path = url + '/lights/' + lightNum + '/state';
  var body = {
    'bri': 255 - brightSlide.value(),
    'sat': 254 - satSlide.value(),
    'hue': 65535 - hueSlide.value()
  };
  var path = url + '/lights/' + lightNum + '/state/'
  httpDo(path, 'PUT', body, changeColourResponse);
}

function changeColourResponse() {
  console.log('Colors changed!');
}

function changeBG() {
  let hr = hour();
  let mn = minute();
  let sc = second();

}

Blink

1st week in ITP is bizarre. The floor turns into a bazaar with students hopping in and out of classes and checking Albert more than Instagram. Caught in a vortex of this hurricane that sweeps through the floor, I somehow ended up in Light & Interactivity (People who dropped the class, I owe you one!). So without much ado, here’s the first assignment.

My task: To fade an LED without using linear PWM. (It’s not the first semester anymore!)


Now, the task seemed pretty deceptively simple. All, you had to do was figure out a curve pattern, figure out the equation of the curve and voila! an expressive LED. That was until I hit an issue that is apparently, an open secret. To explain further, here is the first video:

As you watch the LED fade, trace an imaginary graph of the increase in the light with your fingers. You will come to a realisation which is this:

Paper.Light.4+%281%29.jpg

The curve on the left is what was used to program the LED (linear PWM) but your eyes see what is essentially an exponential growth. This article does a great job explaining the issue and some good discussion can be found here.

So, it was clear that the curve needed to be compensated for in the opposite direction to create a more linear fade. I came across this article which suggested an equation for achieving the same and it felt much better.

This seemed like a good point to try out more curves. First comes the normal sine fade from Tom’s example.

Watching this go on and off, I thought it would be cool to replicate the ‘breathing‘ light on the Mac laptops of old. Turns out, that the pattern is patented (Duh!) and Lady Ada tried to reverse engineer it but did not publish the curve equation. More on that here. If you notice the wave function on the oscilloscope, it looks like a sinusoid function with the top clipped off at the peak. I assumed that I would have to do the math for it but lo and behold! The internet giveth in abundance! Someone had written a great blog on the topic and done the math. Woohoo! Its a great post which fully explains how to derive an equation from a curve using wolfram alpha. read it here. Off I went and wrote an arduino sketch with the results as below:

I am not sure if you can see the difference but a small subtle change in the graph can create perceptible differences. After having scratched the itch of doing the macbook light, I started looking at other repos on Github and came across this repo which has a sine transition as quadratic equation. The author has a great post explaining his approach in balancing the performance and the ease of use while developing the library here.

The result looks like this:

While doing these experiments, I started thinking of the motion curves that are used for defining animations, I wondered if there were of any use. Turns out, there is an old library which has converted all of Robert Penner’s iconic work with easing curves for arduino. It was written for controlling servos, but with a few tweaks, I could get it to work with LEDs:

I did not get much time with the library but on first impression, its extremely easy to use it for any motion with an Arduino control BUT the light fades are not as pretty as the motion curves either because of perceptual differences or the need for modifications to be made to the library. I shall dig into this more later and report back.

Currently listening: Lucy in the sky with diamonds- The Beatles