Introduction: LumiCube: a Lighting Assistant for Workspace

Have you ever felt uncomfortable or difficult to concentrate when working/studying in a workspace? Did you know the lighting (light intensity and light color) in our workspace can affect the quality of work, the speed of working, our mood, our overall productivity, and human health?

To ensure our comfort and productivity, the lighting should be set properly according to the exact work activity/task. But, how can we determine if the lighting is good or not for the task?

LumiCube is a lighting assistant for our workspace, it can help us know the current lighting in the workspace easily:

  • light intensity and color temperature.
  • what kind of work activity is suitable under the lighting.
  • how to set good lighting for the current task.

Design Solution:

Basically, LumiCube has two modes: work mode and relax mode.
Work mode:

  • measure and display real-time Light intensity and color temperature.
  • inform what type of work activity is suitable under the lighting.
  • imply how to set good lighting for different tasks.

Relax mode:

  • provide weather info: temperature and weather description.
  • give outdoor clothing/equipment tips

The relax mode is actually created for my personal issue. Because I always didn't prepare myself well before going outside, especially when I was busy with work. Moreover, It is kind of troublesome to take out my mobile phone and open the weather app. Thanks to Julien Vanier's idea and design - A whimsical weather clock, I decided to implement it for myself.

The overall work process went through 7 steps: knowledge exploration, prototyping, hardware implementation, software development, appearance design, testing, and assembly.

Step 1: Knowledge Exploration

Search for some reliable guidance about the recommended light intensity and color temperature for different degrees of visual information processing work and find a suitable light sensor for measuring light intensity and color temperature.

According to the guidance Recommended Light Levels (Illuminace) for Outdoor and Indoor Venues provided by NOAO, four light intensities were set for different work tasks:

  1. Easy work: 250 lux
  2. Normal office work, PC work: 500 lux
  3. Normal Drawing work, Mechanical work: 1000 lux
  4. Detailed Drawing work, Detailed Mechanical work: 1500 lux

In terms of the guidance provided by Westinghouse Electric Corporation, three light color temperature ranges were defined for different working moods:

  1. Cozy: 2000-3000 Kelvin
  2. Bright: 3100-4500 Kelvin
  3. Invigorating: 4600-6500 Kelvin

Suitable Light sensor for measuring light intensity and color temperature:
Adafruit RGB Color Sensor with IR filter and White LED - TCS34725

Step 2: Prototyping - Sketch

Design the overall product by sketching.

Control Board: there will be a power switch and a mode switch on the top face. The light sensor will be placed on the top face as well for being exposed to the lighting properly and measuring light intensity and color temperature with less error.

Work Mode: there are two kinds of lighting information (light intensity and color temperature) presented on the front face via a LED NeoPixel ring. when the mode switch on the top face is switched to "work", the light sensor starts measuring the light intensity and color temperature of the current lighting environment. The LED NeoPixel will light up regarding the real-time light intensity and color temperature. Four work task icons, meaning reading, normal office work, normal drawing work, and detailed work, are placed near the upper half of the ring for different light intensity. Three work mood icons, meaning cozy, bright, and invigorating, are placed near the lower half for different color temperature range.

Relax Mode: when the mode switch on the top face is switched to "relax", the screen will display the current weather temperature. Additionally, the LED NeoPixel ring will present the weather icon and corresponding outdoor clothing/equipment tips.

Step 3: Hardware Implementation

The main electronics:

  • NeoPixel Ring - 24 x 5050 RGB LED with Integrated Drivers * 1
  • NeoPixel Ring - 16 x 5050 RGB LED with Integrated Drivers * 1
  • Serial OLED Screen,0.96" * 1
  • RGB Color Sensor with IR filter and White LED - TCS34725 * 1
  • 4 x AA Battery Holder * 1
  • AA battery pack * 4
  • SPDT Switch * 2
  • Photon with Headers * 1

Step 4: Software Development

Development Tool: Particle Web IDE

Included Libraries:

  • Arduino (0.0.10)
  • Adafruit_TCS34725 (1.0.0)
  • Adafruit_SSD1306 (0.0.2)
  • SparkJson (0.0.2)
  • NeoPixel (0.0.14)

Programming

Create Webhook to request weather info from OpenWeatherMap API in the Integrations tab of the Particle Console. Apply appid and Weather API on OpenWeatherMap.org Get the current weather API call with zip code and appid, for example, https://samples.openweathermap.org/data/2.5/weather?zip=94040,us&appid=b6907d289e10d714a6e88b30761fae22. This API response will be in JSON format.

Particle Console->Integration tab->New Integration->Webhook: Define the webhook weatherinfo, the URL should be the current weather API call. Since LumiCube only needs the weather description and temperature, mustache templates can be used to process the JSON data in the webhook response. So, in the Advanced Settings of the webhook, set the response template as "{{#weather}}{{0.main}}~{{/weather}}{{#main}}{{temp}}~{{/main}}". And then save the webhook.

In the code, define the variables for the webhook and weather data:

unsigned long request_interval=1000*60*15;// request weather info from openweathermap every 15min
unsigned long lastReq=0;
bool ifUpdate = false; //for weather info update
String wx_main="";
String wx_temp="";
//for storing last-updated weather info
String main="loading";
float temp=0.0;

Subscribe to the response event in setup() using:

Particle.subscribe("hook-response/weatherInfo", myHandler, MY_DEVICES);

Define myHandler function to handle the webhook response as:

void myHandler(const char *event, const char *data) {<br>    String str = String(data);
    char strBuffer[256] = "";
    str.toCharArray(strBuffer, 256);
    wx_main = strtok(strBuffer, "\"~");
    wx_temp = strtok(NULL, "~");
    ifUpdate = true;
    return;
}

Trigger the webhook to request the weather info using:

Particle.publish("weatherInfo", PRIVATE);

Initialize two LED NeoPixel Rings, OLED screen, RGB Light sensor, Mode switch in the code according to the circuit:

// IMPORTANT: Set pixel COUNT, PIN and TYPE for the 24 neopixel ring<br>#define PIXEL_COUNT 24 
#define PIXEL_PIN D6 
#define PIXEL_TYPE WS2812B
// IMPORTANT: Set pixel COUNT, PIN and TYPE for the 16 neopixel ring
#define PIXEL_COUNT_S 16 
#define PIXEL_PIN_S D2 
#define PIXEL_TYPE_S WS2812B
// use hardware SPI for OLED Screen
#define OLED_DC     D3
#define OLED_CS     D4
#define OLED_RESET  D5
//initialize two neopixel rings
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
Adafruit_NeoPixel strip_s = Adafruit_NeoPixel(PIXEL_COUNT_S, PIXEL_PIN_S, PIXEL_TYPE_S);
//initialize OLED screen
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
char buf[64];
//initialize rgb light sensor
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
double r, g, b, l, c; 
bool init = false;
// mode switch
int switchPin = A0;

Main features in each loop of the code:

Check the state of the mode switch.

If the state of the mode switch is LOW which is set as the work mode of LumiCube:

Read values from the RGB light sensor using:

void getRawData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c); 

Calculate light intensity and color temperature using:

uint16_t calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b);
uint16_t calculateLux(uint16_t r, uint16_t g, uint16_t b);

According to the light intensity and color temperature, light up NeoPixels on the 24 NeoPixel using:

strip.setPixelColor(i, r, g, b); 

If the state of the mode switch is HIGH which is set as the relax mode of LumiCube:

Trigger the webhook to request and update the weather information every 15 minutes

Display weather temperature on the OLED Screen:

//display temperature on OLED Screen   <br>display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0,0);
        
snprintf(buf, sizeof(buf), "Temp");
display.println(buf);
        
snprintf(buf, sizeof(buf), "%0.1f C", temp);
display.println(buf);

According to the weather description and temperature, light up NeoPixels on the 16 NeoPixel using:

strip_s.setPixelColor(i, r, g, b);

The full code is in the lumicube.ino file.

Step 5: Appearance Design

Use Adobe Illustrator to design the appearance of LumiCube: 4.5 X 4.5 X 4.5 inch.

Laser Cut the design using ⅛ inch Birchwood.

Step 6: Testing

Let Photon connect to the cloud and flash the code into it through Particle Web IDE.

Debug and make sure the lighting information and the weather information displayed properly.

Step 7: Assembly

Assemble the electronics with the wood cube.

Step 8: Final Prototype

First Time Author

Participated in the
First Time Author