Viktor S
Published © CC BY-NC

Rotating Lithophane Lamp

Activate a 360° lithophane with a secret key, and pick from a few light modes.

IntermediateShowcase (no instructions)1,166

Story

Read more

Schematics

Litho_Lamp_Schematic

RFP40N10_Datasheet.pdf

ZTX458_Datasheet

Code

Litho_Lamp.ino

Arduino
Code is stable, but can be further optimized.
/**
 * Rotating Lithophane Lamp
 * 12/23/2018
 * by Viktor Silivanov
 * 
 * Stable version.
 * ATmega328 MCU pinout required for pin definitions.
 * 
 * Bug(s): Delays in Mode 3 buffer user input until full cycle completes.
 * 
 */

//******************** Pin Information ********************************************************************************************************************************************************************************************************************
/** 
 * Pin Information:
 * PWM Pins: D3, D5, D6, D9, D10, D11
 * Interrupt Pins: D2, D3
 * Pin D2=0; Pin D3=1 in argument for attachInterrupt operation
 */

// Digital Pins
#define button          2                                // Interrupt pin
#define reed_switch     4
#define motor_switch    8

// PWM Pins
#define GreenLED        5
#define RedLED          6
#define BlueLED         9
#define WhiteLED        10
#define motor           11

// Analog Pins
#define mode1_LED       A0
#define mode2_LED       A1
#define mode3_LED       A2
#define motor_LED       A3

//******************** Global Variables ********************************************************************************************************************************************************************************************************************
uint8_t button_count = 1;                                // Defaults to Mode 1 
#define fade_speed     20                                // Speed in milliseconds  
#define motor_speed    40                                // [0,255]

//******************** Code Begins ******************************************************************************************************************************************************************************************************************

void setup() {
  //**************** PWM Timers ********************
  TCCR1B = TCCR1B & 0b11111000 | 0x01;                // Adjusts PWM freq for pins 9, 10 from 490Hz to 31kHz
  
  //**************** Heart *************************
  pinMode(reed_switch, INPUT_PULLUP);                 // Closing the switch will ground the pin. Pullup will remove floating pin
  
  //**************** Motor *************************
  pinMode(motor, OUTPUT);
  pinMode(motor_LED, OUTPUT);
  pinMode(motor_switch, INPUT_PULLUP);

  //**************** LEDs *************************
  pinMode(GreenLED,  OUTPUT);
  pinMode(RedLED,    OUTPUT);
  pinMode(BlueLED,   OUTPUT);
  pinMode(WhiteLED,  OUTPUT);
  pinMode(mode1_LED, OUTPUT);
  pinMode(mode2_LED, OUTPUT);
  pinMode(mode3_LED, OUTPUT);
  
  //**************** Button *************************
  pinMode(button, INPUT_PULLUP);
  attachInterrupt(0, button_push, FALLING);          // Execute mode_change function on a FALING edge (0 = Pin 2; 1 = Pin 3; These are the only pins that can utilize this interrupt functionality)
}

// Warm White
void Mode_1(){
  //mode LEDs
  analogWrite(mode1_LED, 255);
  analogWrite(mode2_LED, 0);
  analogWrite(mode3_LED, 0);

  //LED strip
  analogWrite(RedLED, 50);
  analogWrite(BlueLED, 0);
  analogWrite(GreenLED, 0);
  analogWrite(WhiteLED, 255);
}

// Cool White
void Mode_2(){
  //mode LEDs
  analogWrite(mode1_LED, 0);
  analogWrite(mode2_LED, 255);
  analogWrite(mode3_LED, 0);

  //LED strip
  analogWrite(RedLED, 0);
  analogWrite(BlueLED, 80);
  analogWrite(GreenLED, 0);
  analogWrite(WhiteLED, 255);
}

// Mood Lights
// Fade between all colors with a hint of white
void Mode_3{
  //mode LEDs
  analogWrite(mode1_LED, 0);
  analogWrite(mode2_LED, 0);
  analogWrite(mode3_LED, 255);

  //LED strip
  analogWrite(WhiteLED, 100);
  int r, g, b;

  // fade from blue to violet
  for (r = 0; r < 256; r++){ 
    analogWrite(RedLED, r);
    delay(fade_speed);
  } 
  // fade from violet to red
  for (b = 255; b > 0; b--){ 
    analogWrite(BlueLED, b);
    delay(fade_speed);
  } 
  // fade from red to yellow
  for (g = 0; g < 256; g++){ 
    analogWrite(GreenLED, g);
    delay(fade_speed);
  } 
  // fade from yellow to green
  for (r = 255; r > 0; r--){ 
    analogWrite(RedLED, r);
    delay(fade_speed);
  } 
  // fade from green to teal
  for (b = 0; b < 256; b++){ 
    analogWrite(BlueLED, b);
    delay(fade_speed);
  } 
  // fade from teal to blue
  for (g = 255; g > 0; g--){ 
    analogWrite(GreenLED, g);
    delay(fade_speed);
  }
}

//******************** Main Loop ******************************************************************************************************************************************************************************************************************
void loop() {
  if(button_count > 3){
    button_count = 0;
  }

  //Magnet placed over reed switch
  while( digitalRead(reed_switch) == LOW ){
    if( digitalRead(motor_switch) == LOW ){
      //Motor OFF
      analogWrite(motor_LED, 0);
      analogWrite(motor, 0);
    }
    else{
      //Motor ON                                        
      analogWrite(motor_LED, 255);
      analogWrite(motor, motor_speed); 
    }

    switch(button_count){
      case 2:
        Mode_2();
        break;
      case 3:
        Mode_3();
        break;
      default:
        Mode_1();
        break;
    }
  }

  analogWrite(motor,     0);
  analogWrite(motor_LED, 0);
  analogWrite(RedLED,    0);
  analogWrite(BlueLED,   0);
  analogWrite(GreenLED,  0);
  analogWrite(WhiteLED,  0);
  analogWrite(mode1_LED, 0);
  analogWrite(mode2_LED, 0);
  analogWrite(mode3_LED, 0);
  analogWrite(motor_LED, 0);  
}

//******************** Interrupt for button ******************************************************************************************************************************************************************************************************************
void button_push(){
  //Includes button debouncing
  static unsigned long last_pressed_time = 0;
  unsigned long pressed_time = millis();

  if(pressed_time - last_pressed_time > 200){
    button_count++;
  }

  last_pressed_time = pressed_time;
}

Credits

Viktor S

Viktor S

7 projects • 11 followers
Electrical Engineer & Electronics Hobbyist

Comments