<
>
back to all cubes

Mixer Cube

3 faces have sliders for R, G and B. A LED inside displays the mixed color

We thought of this cube as a 3D version of the software widget for selecting color using 3 sliders - Red, Green and Blue. We located each slider on one face of the cube, leaving the fourth one empty. An RGB Led inside the cube changes color accordingly.

We created a simple pattern on the top of the cube so that the light would break and the color would show as strongly as possible. Finally, it was nice to use red, green and blue cables to connect each slider to the Arduino board.

Arduino code - download here

/*
  CUBES originally created by the interaction Lab, Holon Institute of Technology for the Design Museum Holon.
  http://interaction.shenkar.ac.il
  This work is licensed under a Creative Commons Attribution 3.0 Unported License

  RGBCube by Idit Minka
  Based on code by Tom Igoe
*/



#define totalFadeTime   1000.0

// defining names for possible states of cube
#define WakeUp             0
#define GoToSleep          1
#define WorkingMode        2
#define Sleep              3
#define FadeIn             4

const int analogInPinR = A2;  // Analog input pin that the slider is attached to
const int analogInPinG = A1;  // Analog input pin that the slider is attached to
const int analogInPinB = A0;  // Analog input pin that the slider is attached to

const int analogOutPinR = 5; // Analog output pin that the LED is attached to
const int analogOutPinG = 6; // Analog output pin that the LED is attached to
const int analogOutPinB = 9; // Analog output pin that the LED is attached to

int sensorValueR = 0;        // value read from the pot
int sensorValueG = 0;        // value read from the pot
int sensorValueB = 0;        // value read from the pot

int outputValueR = 0;        // value output to the PWM (analog out)
int outputValueG = 0;        // value output to the PWM (analog out)
int outputValueB = 0;        // value output to the PWM (analog out)

int lastSensorValueR = 0;
int lastSensorValueG = 0;
int lastSensorValueB = 0;

int state = Sleep;

long lastModification = 0;  // last millis() any input changed (for timing sleeping after 10 seconds of no change)
long FadeTime = 0;          // fade start time

static unsigned char exp_map[256] = { // this help create a linear change in brightness to the human eye (which is more sensitive to changes in low light)
  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
  5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9,
  9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13,
  14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 20,
  20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29,
  29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 40, 41, 42,
  42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60,
  62, 63, 64, 66, 67, 69, 70, 72, 74, 75, 77, 79, 80, 82, 84, 86, 88,
  90, 91, 94, 96, 98, 100, 102, 104, 107, 109, 111, 114, 116, 119,
  122, 124, 127, 130, 133, 136, 139, 142, 145, 148, 151, 155, 158,
  161, 165, 169, 172, 176, 180, 184, 188, 192, 196, 201, 205, 210,
  214, 219, 224, 229, 234, 239, 244, 250, 255
};





void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {

  sensorValueR = analogRead(analogInPinR);
  sensorValueG = analogRead(analogInPinG);
  sensorValueB = analogRead(analogInPinB);

  // we implement a state machine. each state has "actions" it does and conditions for moving to other states ("if"s)
  switch (state) {


    case Sleep:
      // if any slider is touched, wake up the LED
      if (lastSensorValueR != sensorValueR || lastSensorValueG != sensorValueG || lastSensorValueB != sensorValueB)
      {
        lastModification = millis();
        state = WakeUp;
        FadeTime = millis();
      }
      break;

    case WakeUp:
      fadeIn();
      break;

    case WorkingMode:
      normalRun();
      // if untouched for more than 10 seconds, go to sleep
      if (millis() - lastModification > 10000) {
        state = GoToSleep;
        FadeTime = millis();
      }
      // if any slider is touched, update the sleeping timer
      if (lastSensorValueR != sensorValueR || lastSensorValueG != sensorValueG || lastSensorValueB != sensorValueB)
      {
        lastModification = millis();
      }
      break;


    case GoToSleep:
      fadeOut();
      if (lastSensorValueR != sensorValueR || lastSensorValueG != sensorValueG || lastSensorValueB != sensorValueB)
      {
        lastModification = millis();
        state = WorkingMode;
      }
      break;


  }


  // update the previous analog in values, for finding user activity and going to sleep:

  lastSensorValueR = sensorValueR;
  lastSensorValueG = sensorValueG;
  lastSensorValueB = sensorValueB;

}



void normalRun() {

  // map it to the range of the analog out:
  outputValueR = map(sensorValueR, 1023, 0, 0, 255);
  outputValueG = map(sensorValueG, 1023, 0, 0, 255);
  outputValueB = map(sensorValueB, 1023, 0, 0, 230);
  
  // adjust value to match human eye sensitivity
  outputValueR = exp_map[outputValueR];
  outputValueG = exp_map[outputValueG];
  outputValueB = exp_map[outputValueB];

  // change the analog out value:
  analogWrite(analogOutPinR, outputValueR);
  analogWrite(analogOutPinG, outputValueG);
  analogWrite(analogOutPinB, outputValueB);
}


void fadeIn() {
  // here we create a factor to multiply each color's value for fading in.
  // this number will start at 0 and grdually grow until it reaches 1 after one second (1000 milliseconds, which is totalFadeTime)
  float factor = (float)(millis() - FadeTime) / totalFadeTime;

  // if fading in is complete - change the state to "working mode"
  if (millis() - FadeTime >= totalFadeTime) {
    state = WorkingMode;
  }

  outputValueR = (int)((float)map(sensorValueR, 1023, 0, 0, 255) * factor);
  outputValueG = (int)((float)map(sensorValueG, 1023, 0, 0, 255) * factor);
  outputValueB = (int)((float)map(sensorValueB, 1023, 0, 0, 230) * factor);

  outputValueR = exp_map[outputValueR];
  outputValueG = exp_map[outputValueG];
  outputValueB = exp_map[outputValueB];

  // change the analog out value:
  analogWrite(analogOutPinR, outputValueR);
  analogWrite(analogOutPinG, outputValueG);
  analogWrite(analogOutPinB, outputValueB);


}

void fadeOut() {
  // here we create a factor to multiply each color's value for fading out.
  // this number will start at 1 and grdually reduce until it reaches 0 after one second (1000 milliseconds, which is totalFadeTime)
  float factor = (float)(totalFadeTime - (millis() - FadeTime)) / totalFadeTime;

  if (millis() - FadeTime >= totalFadeTime) {
    state = Sleep;
  }

  outputValueR = (int)((float)map(sensorValueR, 1023, 0, 0, 255) * factor);
  outputValueG = (int)((float)map(sensorValueG, 1023, 0, 0, 255) * factor);
  outputValueB = (int)((float)map(sensorValueB, 1023, 0, 0, 230) * factor);

  outputValueR = exp_map[outputValueR];
  outputValueG = exp_map[outputValueG];
  outputValueB = exp_map[outputValueB];

  // change the analog out value:
  analogWrite(analogOutPinR, outputValueR);
  analogWrite(analogOutPinG, outputValueG);
  analogWrite(analogOutPinB, outputValueB);

}

Parts:

(1x) Arduino Mini Pro 5V

(1x) RGB LED

(3x) Linear Potentiometer

(1x) 7.2V Li-Po Battery

(1x) 5.5/2.1mm Jack Socket