/*
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