Eternal Flame

Today we’re making a digital candle that never goes out, 7 LEDs. We’ll detect a blow, to make the LEDs flicker and have an RGB LED change colours. When this main LED turns back to its original colour, it means your Christmas wish has been granted.
Disclaimer: wish granting not guaranteed

candle_hero

You’ll need:

  • 6 5mm yellow and red LEDs
  • 1 10mm RGB LED
  • Arduino UNO
  • Jump wires + breadboard

This hack was a lot trickier than I had planned. The original idea, was to use a piezo sensor as an input (as opposed to the usual sound output), change the lights accordingly and have a stand-alone “candle”. Unfortunately, analog inputs aren’t my favourite thing (getting better as those is on my New Year’s resolutions list, though). I was trying to mix up the Knock Sensor with this blow sensor hack, but it didn’t turn out very well. I think it’s mostly because I’ve got the wrong types of resistors (values are too low).

Anyway, I was still decided to deliver a hack today, so it’s back to good old Serial communication with Processing! Using the Minim audio library and the built-in microphone of my computer, I have been able to adapt this example to detect a blow and pass the data to Arduino, accordingly. It doesn’t look like you’re blowing on the candle anymore, but it’s better than nothing. So, let’s have a look:

1) Microphone input and different blow strengths
To start with, I adjusted the Processing sketch mentioned above to detect and visualise blows in a simple way : just a line, drawn in a different colour depending on the strength of it. Here’s the result:

import ddf.minim.*;
 
Minim minim;
AudioInput in;
 
void setup()
{
  background(0);
  size(500, 200, P3D);
 
  minim = new Minim(this);
 
  // get a line in from Minim, default bit depth is 16
  in = minim.getLineIn(Minim.MONO, 2);
}
 
void draw()
{
  strokeWeight(5);
  // draw the waveforms
  for(int i = 0; i = 0.99){
      drawLine(159, 61, 158, i);
       println("max blow"); 
    } else if(in.left.get(i) > 0.8 && in.left.get(i)  0.6 && in.left.get(i)  0.5 && in.left.get(i)  0.2 &&in.left.get(i) <= 0.5) {
      drawLine(255, 255, 255, i);
       println("weak blow"); 
     }
  }
}


void drawLine(int R, int G, int B, int i) {
  background(0);
  stroke(R, G, B);
  line(i+50, 100 + in.left.get(i)*50, (i+450), 100 + in.left.get(i+1)*50);
}
 
void stop()
{
  // always close Minim audio classes when you are done with them
  in.close();
  minim.stop();
 
  super.stop();
}

If you run the sketch as is and blow into your microphone, you should see some results.
Now, we want to pass this data to Arduino, to make LEDs flicker and change colour for the RGB one. Let’s build the circuit first.

2) Candlelight flickers
candle_one

Put the RGB LED in the center. Then wire the 6 yellow LEDs in a semi circle around it. I’ve wired the small LEDs in 2 groups of three, (odd ones together and even ones together), to have a nice flickering effect later. We’ll save the RGB LED for later and focus on the flickering for the yellow LEDs. The Processing sketch needs to be slightly amended to parse the different blow values over Serial. I’ve defined them as: max, big, strong, medium, weak.

The Arduino code for the demo above is as follows:

//RGB LED pins
int RPin = 11;
int GPin = 10;
int BPin = 9;

//2x3 yellow LEDs
int YPin = 6;
int Y2Pin = 5;

String command = "";

void setup() {
  Serial.begin(9600);
  pinMode(RPin, OUTPUT);
  pinMode(GPin, OUTPUT);
  pinMode(BPin, OUTPUT);
  pinMode(YPin, OUTPUT);
  pinMode(Y2Pin, OUTPUT);
  
//turn yellow LEDs on by default
  digitalWrite(YPin, HIGH);
  digitalWrite(Y2Pin, HIGH);
  
  resetRGB();
}

void loop() {
    while(Serial.available() > 0) {
      char inChar = Serial.read();
      
      if(inChar == '\n'){
        //read commands from Processing
          if (command == "max"){
            flickerYellow(20);
          }
          if (command == "big"){
            flickerYellow(50);
          }
          if (command == "strong"){
            flickerYellow(80);
          }
          if (command == "medium"){
            flickerYellow(100);
          }
          if (command == "weak"){
            flickerYellow(500);
          }
          
          else {
             digitalWrite(YPin, HIGH);
             digitalWrite(Y2Pin, HIGH); 
          }

  
          command = "";
      }
    
      else if(inChar !='\r'){
        command += inChar;
      }
      
  } 
}

void flickerYellow(int delayTime) {
 if(delayTime == 500) {
//we make the 6 leds blink together if the flicker is weak
     digitalWrite(YPin, LOW);
     digitalWrite(Y2Pin, LOW);
     delay(30);
     digitalWrite(YPin, HIGH);
     digitalWrite(Y2Pin, HIGH);
     delay(30); 
  
 } else {
//we make an alternate flickering if not
     digitalWrite(YPin, HIGH);
     digitalWrite(Y2Pin, LOW);
     delay(delayTime);
     digitalWrite(YPin, LOW);
     digitalWrite(Y2Pin, HIGH);
     delay(delayTime); 
 } 
  
}


//we switch the RGB off for now
void resetRGB() {
  analogWrite(RPin, 255);
  analogWrite(GPin, 255);
  analogWrite(BPin, 255);
}

Upload this to your Arduino and run your new Processing sketch, you should have the same results as above.

3) Make a wish
In the Arduino sketch, let’s create a setRGB function with 3 paramaters: int R, int G, int B.

void setRGB() {
  analogWrite(RPin, 255);
  analogWrite(GPin, 255);
  analogWrite(BPin, 255);
}

This will help us set the colour of the RGB LED.
Now, we just need to define random values and call setRGB when a blow is detected.
We need to amend the loop function as follows:

void loop() {
    while(Serial.available() > 0) {
      char inChar = Serial.read();
      
      if(inChar == '\n'){
          if (command == "max"){
            flickerYellow(20);
              wish -=random(50);
          }
          if (command == "big"){
            flickerYellow(50);
              wish -=random(40);
          }
          if (command == "strong"){
            flickerYellow(80);
            wish -=random(30);
          }
          if (command == "medium"){
              wish -=random(20);
            flickerYellow(100);
          }
          if (command == "weak"){
            wish-=random(10);
            flickerYellow(500);
          }
          
          if(command!= "") {
            if(wish >= 0) {
              setRGB(random(wish), random(wish), random(wish));
              wish = 250; 
            }
          }
          
          else {
             digitalWrite(YPin, HIGH);
             digitalWrite(Y2Pin, HIGH); 
          }

  
          command = "";
      }
    
      else if(inChar !='\r'){
        command += inChar;
      }
      
  } 
}


wish is an int initially set at 250.
And it seems like we’re done. We’ve got a magic LED candle!

If you’ve got time, it would be nice to mount it on a cardboard cylinder and decorate it like a real Christmas candle.

Back tomorrow!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s