/*
 lightTheremin.ino
 Alexander Hiam
 8/2012
 
 Parts:
   -Adafruit photocell: https://www.adafruit.com/products/161
     (any photocell will work, but values tuned for Adafruit's)
   -2x 10k ohm resistor
   -1x 330 ohm resistor
   -1x LED
   -1x momentary tactile switch 
     (like one of these: http://www.adafruit.com/products/367 )
   -1x piezo buzzer: http://www.adafruit.com/products/160
     (many other speakers or buzzers will work)
  Optional:
   -1x 10k ohm potentiometer
   -1x 0.1uF ceramic capacitor
   
 Circuit:
 
  Inputs:
 
   [5V]--------------------------- 
         |                       |
      (10k R)                     \ - (Switch)
         |                       |
         |-------[A0]            |--------[4]
         |                       |
     (Photocell)              (10k R)
         |                       |
       [GND]                   [GND]
       
  LED:
  
   [5]---(LED)---
                |
             (330 R)
                |
              [GND]
 
  Output:            |   Or with optional filter:
                     |    
   [3]-------        |    [3]-------
            |        |             |
         (Buzzer)    |         (10k pot) <----------------
            |        |             |          |          |
          [GND]      |           [GND]   (0.1uF cap)  (Buzzer)
                     |                        |          |
                     |                      [GND]      [GND]
                     |

 This code is in the public domain.
*/

// Define pin constants:
#define FREQ_LDR  A0
#define FREQ_LED  5
#define ON_SWITCH 4
#define SPEAKER   3

// A global variable to store the current output state:
int current_state;

void setup() {
  // Set the two output pins to outputs:
  pinMode(SPEAKER, OUTPUT);
  pinMode(FREQ_LED, OUTPUT);
}

void loop() {
  // Initialize the local variables:
  int adc_value;
  float frequency, half_period_ms;

  if (digitalRead(ON_SWITCH)) {
    // The switch is depressed; generate output:
    
    // Get the ADC value from the photocell:
    frequency = analogRead(FREQ_LDR);
    // Invert (so darker = lower frequency), and increase the scale a bit:
    frequency = map(frequency, 0, 1024, 2000, 1)/2;
    
    // Adjust a bit to ensure we can get the lower frequencies:
    frequency = frequency - 50;

    // Make sure we don't get values outside our range (especially not below 1 Hz):
    frequency = constrain(frequency, 1, 2000);

    // The period in ms is 1000/frequency, so every half period we need to switch 
    // the output; calculate this value: 
    half_period_ms = 1000/(2*frequency);

    if (current_state == HIGH) {
      // This output is currently high, set it low:
      digitalWrite(SPEAKER, LOW);
      digitalWrite(FREQ_LED, LOW);
      current_state = LOW;
    }
    else {
      // This output is currently low, set it high:
      digitalWrite(SPEAKER, HIGH);
      digitalWrite(FREQ_LED, HIGH);
      current_state = HIGH; 
    }

    // Wait one half period:
    delay(half_period_ms);
  }
  
  else {
    // The switch is not pressed, turn off output:
    digitalWrite(SPEAKER, LOW);
    digitalWrite(FREQ_LED, LOW);
    
    // Delaying a little here will keep the power consumption down a little
    // while the button's not pressed:
    delay(100);
  }
}

syntax highlighted by Code2HTML, v. 0.93pm6