Introduction: Music Tune That Sounds in the Dark

In this simple project we'll create a music tuner that plays only in the dark, using Arduino Uno, a LDR, a Piezo speaker, some resistances and LEDs for better looking matters.

Step 1:

First the materias, we need:

- Arduino Uno
- Fotowiderstand (LDR)
- LEDs of different colors, 3 in this case
- Piezo speaker
- a pair of resistors (330 Ohms / 10 Kohms)
- breadboard
- cables for the conections
- the usb cable for the Arduino Uno
- and of course the arduino IDE

now for the first part we launch the IDE and take some useful code found in this website, used for the notes necesary to make the tunes (http://arduino.cc/en/Tutorial/PlayMelody) this is really useful cause it allow us to prepare the code and save us the time finding how to generate each note with the speaker.

after this we can generate a code that look like this for the notes and the duration of them:

int melody[] = {  RE, MI, RE, SI, Rest, RE, MI, RE, SI, Rest, LA,LA,FA,Rest,SOL,SOL,RE,Rest };
int beats[]  = { 8, 8, 8,  16, 64,  8,  8, 8, 16, 64,8,8,16,32,8,8,16,128 };
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.
// Set overall tempo
long tempo = 80000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 100;

tempo is used to change the speed, this will be added further in the code.

Step 2:

Now that we have the base code of the project lets work on the wiring of the device.

first let's wire the LDR. for this we require a 10kohms resistance and a couple of cables, we'll use the A0 analog port for reading the data from the LDR, the 5v pin to power it up and gnd as usual, wire it as shown in the images

Step 3:

next, let's wire the rest of the components to the arduino and the breadboard.
first we'll use the digital Output ports 2,3 and 4 for the LEDs, attaching the short legs of the LEDs to the horizontal rail on top for the GND connection, then we hook up the speaker on por 9 with a small resistance of 330Ohm. also the negative leg of the speaker will go to GND,

the picture shows

Step 4:

after all the attaching of the electronics, let's get into software stuff, open the Arduino IDE and type the missing code for the project to work.

void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { if(tone_ == 3400 || tone_ == 3038){
   digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);  
    }
else if (tone_ == 2028 || tone_ ==2272){  
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);  }
else if (tone_ == 2864 || tone_ ==2550){digitalWrite(2, LOW);                
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);  } // if this isn't a Rest beat, while the tone has
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {

      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(tone_ / 2);

      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    }
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration); 
    }                               
  }                               
}

here we can see the usage of the LED's as decoration illumination for the project, everytime a note is played, one of them is going to be lighted, since the tune is short it's ok to use only 3 LED's. remember to add:
void setup() {
  pinMode(speakerOut, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

in order for the code to indentify what would be the output sources for this project.

finally let's wrap it up with :

void loop() {
  // Set up a counter to pull from melody[] and beats[]
  // read the value from the ldr:
  sensorValue = analogRead(sensorPin);    
  if(sensorValue<500){
   //
// 
    for (int i=0; i<MAX_COUNT; i++) {
    tone_ = melody[i];
    beat = beats[i];

    duration = beat * tempo; // Set up timing

    playTone();
         
    // A pause between notes...
    delayMicroseconds(pause);
}

this part will read the data from the LDR and identify if there's enough light in the enviorement, if not then the tune starts and the LED's light acording to it.

Step 5:

as a final step, let's try it out. connect the USB on the Arduino and upload the code to it, now if there's enough light picked by the LDR nothing will happen. if that's the case, put your hand closer to the LDR and the LED will light up and the tune will start playing, in this case, Silent Night for means of consistency with the absence of light ;)

so there u go, a nice and easy way to use Arduino just for fun, here's the full code

// TONES  ==========================================
// Start by defining the relationship between
//       note, period, &  frequency.
#define  DO     3830    // 261 Hz
#define  RE     3400    // 294 Hz
#define  MI     3038    // 329 Hz
#define  FA     2864    // 349 Hz
#define  SOL     2550    // 392 Hz
#define  LA     2272    // 440 Hz
#define  SI     2028    // 493 Hz
#define  DOM     1912    // 523 Hz
// Define a special note, 'R', to represent a rest
#define  Rest     0

// SETUP ============================================
// Set up speaker on a PWM pin (digital 9, 10 or 11)
int speakerOut = 9;
// Do we want debugging on serial out? 1 for yes, 0 for no
int DEBUG = 1;
int sensorPin = A0;            // select the input pin for the ldr
unsigned int sensorValue = 0;  // variable to store the value coming from the ldr

void setup() {
  pinMode(speakerOut, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (DEBUG) {
    Serial.begin(9600); // Set serial out if we want debugging
  }
}

// MELODY and TIMING  =======================================
//  melody[] is an array of notes, accompanied by beats[],
//  which sets each note's relative length (higher #, longer note)
int melody[] = {  RE, MI, RE, SI, Rest, RE, MI, RE, SI, Rest, LA,LA,FA,Rest,SOL,SOL,RE,Rest };
int beats[]  = { 8, 8, 8,  16, 64,  8,  8, 8, 16, 64,8,8,16,32,8,8,16,128 };
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.

// Set overall tempo
long tempo = 80000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES

// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration  = 0;

// PLAY TONE  ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { if(tone_ == 3400 || tone_ == 3038){
   digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);  
    }
else if (tone_ == 2028 || tone_ ==2272){  
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);  }
else if (tone_ == 2864 || tone_ ==2550){digitalWrite(2, LOW);                
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);  } // if this isn't a Rest beat, while the tone has
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {

      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(tone_ / 2);

      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    }
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration); 
    }                               
  }                               
}

// LET THE WILD RUMPUS BEGIN =============================
void loop() {
  // Set up a counter to pull from melody[] and beats[]
  // read the value from the ldr:
  sensorValue = analogRead(sensorPin);    
  if(sensorValue<500){
   //
// 
    for (int i=0; i<MAX_COUNT; i++) {
    tone_ = melody[i];
    beat = beats[i];

    duration = beat * tempo; // Set up timing

    playTone();
         
    // A pause between notes...
    delayMicroseconds(pause);

    if (DEBUG) { // If debugging, report loop, tone, beat, and duration
      Serial.print(i);
      Serial.print(":");
      Serial.print(beat);
      Serial.print(" ");   
      Serial.print(tone_);
      Serial.print(" ");
      Serial.println(duration);
    }
  }} // set the LED on
  else {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW); } // set the LED on

}

the debugging part can be helpful for educational purposes, since u can see the values being picked and what tones are being played by the device