Created
December 1, 2012 01:13
-
-
Save gunthercox/4179931 to your computer and use it in GitHub Desktop.
Arduino code for a sonic screwdriver.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sonic Screw Driver | |
// CONSTANTS AND VARIABLES | |
const int button2 = 2; | |
const int button3 = 3; | |
const int speaker = 4; | |
const int inputVoltagePin = 6; | |
const int IREMITTER = 7; | |
const int IRRECEIVER = 8; | |
const int LED = 9; | |
const int LASER = 12; | |
//const int mic = A0; | |
// LED STUFF | |
int value; | |
long time = 0; | |
int periode = 2000; | |
int displace = 500; | |
// SENSOR READINGS | |
int settingCount = 0; | |
//int ambientVol = 0; | |
// EMF DETECTOR | |
#define NUMREADINGS 15 // raise this number to increase data smoothing | |
int senseLimit = 15; // raise this number to decrease sensitivity (up to 1023 max) | |
int probePin = 0; | |
int val = 0; // reading from probePin | |
// VOLT METER | |
int voltage = 0; | |
int valueVolts = 0; | |
int valueHundrethsOfMilliVolts = 0; | |
// variables for smoothing | |
int readings[NUMREADINGS]; // the readings from the analog input | |
int index = 0; // the index of the current reading | |
int total = 0; // the running total | |
int average = 0; // final average of the probe reading | |
//CHANGE THIS TO affect the speed of the updates for numbers. Lower the number the faster it updates. | |
int updateTime = 40; | |
// CURRENT BUTTON STATES | |
int incUp = 0; | |
int incDn = 0; | |
// TONES ========================================== | |
// Defining the relationship between note, period, & frequency | |
// period is in microsecond so P = 1/f * (1E6) | |
#define c3 7634 | |
#define d3 6803 | |
#define e3 6061 | |
#define f3 5714 | |
#define g3 5102 | |
#define a3 4545 | |
#define b3 4049 | |
#define c4 3816 // 261 Hz | |
#define d4 3401 // 294 Hz | |
#define e4 3030 // 329 Hz | |
#define f4 2865 // 349 Hz | |
#define g4 2551 // 392 Hz | |
#define a4 2272 // 440 Hz | |
#define a4s 2146 | |
#define b4 2028 // 493 Hz | |
#define c5 1912 // 523 Hz | |
#define d5 1706 | |
#define d5s 1608 | |
#define e5 1517 | |
#define f5 1433 | |
#define g5 1276 | |
#define a5 1136 | |
#define a5s 1073 | |
#define b5 1012 | |
#define c6 955 | |
// Define a special note, 'R', to represent a rest | |
#define R 0 | |
// melody[] is an array of notes, accompanied by beats[], | |
// which sets each note's relative length (higher #, longer note) | |
// star wars theme | |
int melody[] = { | |
f4, f4, f4, a4s, f5, d5s, d5, c5, a5s, f5, d5s, d5, c5, a5s, f5, d5s, d5, d5s, c5}; | |
int beats[] = { | |
21, 21, 21, 128, 128, 21, 21, 21, 128, 64, 21, 21, 21, 128, 64, 21, 21, 21, 128 }; | |
// note debug | |
//int melody[] = { c4, d4, e4, f4, g4, a4, b4, c5 }; | |
//int beats[] = { 63, 64, 64, 64, 64, 64, 64, 64 }; | |
//super mario theme | |
//int melody[] = {e5, e5, R, e5, R, c5, e5, R, g5, R, R, R, g4, R, R, R, c5, R, R, g4, R, R, e4}; | |
//int beats[] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 , 16, 16, 16, 16, 16, 16, 8, 16, 8, 16, 16}; | |
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping. | |
// Set overall tempo | |
long tempo = 10000; | |
// Set length of pause between notes | |
int pause = 1000; | |
// Loop variable to increase Rest length | |
int rest_count = 50; | |
// Initialize core variables | |
int toneM = 0; | |
int beat = 0; | |
long duration = 0; | |
void setup() { | |
// SET COMPONENTS AS INPUT OR OUTPUT | |
pinMode(button2, INPUT); | |
pinMode(button3, INPUT); | |
//pinMode(mic, INPUT); | |
pinMode(IREMITTER, OUTPUT); | |
pinMode(LASER, OUTPUT); | |
pinMode(LED, OUTPUT); | |
pinMode(speaker, OUTPUT); | |
// BEGIN SERIAL COMUNICATION | |
Serial.begin(9600); | |
for (int i = 0; i < NUMREADINGS; i++) | |
readings[i] = 0; // initialize all the readings to 0 | |
} | |
void loop() { | |
readButtons(); | |
switch (settingCount) { | |
case 1: | |
// FLASHLIGHT | |
digitalOff(); | |
digitalWrite(LED, HIGH); | |
break; | |
case 2: | |
// LASER | |
digitalOff(); | |
digitalWrite(LASER, HIGH); | |
break; | |
case 3: | |
// IR LIGHT | |
digitalOff(); | |
digitalWrite(IREMITTER, HIGH); | |
break; | |
case 4: | |
// PULSE LED | |
digitalWrite(IREMITTER, LOW); | |
time = millis(); | |
value = 128+127*cos(2*PI/periode*time); | |
analogWrite(LED, value); | |
break; | |
case 5: | |
// EMF METER http://www.instructables.com/id/Arduino-EMF-Detector/ | |
digitalOff(); | |
val = analogRead(probePin); // take a reading from the probe | |
if(val >= 1){ // if the reading isn't zero, proceed | |
val = constrain(val, 1, senseLimit); // turn any reading higher than the senseLimit value into the senseLimit value | |
val = map(val, 1, senseLimit, 1, 1023); // remap the constrained value within a 1 to 1023 range | |
total -= readings[index]; // subtract the last reading | |
readings[index] = val; // read from the sensor | |
total += readings[index]; // add the reading to the total | |
index = (index + 1); // advance to the next index | |
if (index >= NUMREADINGS) // if we're at the end of the array... | |
index = 0; // ...wrap around to the beginning | |
average = (total / NUMREADINGS); // calculate the average | |
analogWrite(LED, average); | |
Serial.println(average); // use output to aid in calibrating | |
delay(updateTime); | |
} | |
break; | |
case 6: | |
// EMF METER WITH SOUND | |
digitalOff(); | |
val = analogRead(probePin); // take a reading from the probe | |
if(val >= 1){ // if the reading isn't zero, proceed | |
val = constrain(val, 1, senseLimit); // turn any reading higher than the senseLimit value into the senseLimit value | |
val = map(val, 1, senseLimit, 1, 1023); // remap the constrained value within a 1 to 1023 range | |
total -= readings[index]; // subtract the last reading | |
readings[index] = val; // read from the sensor | |
total += readings[index]; // add the reading to the total | |
index = (index + 1); // advance to the next index | |
if (index >= NUMREADINGS) // if we're at the end of the array... | |
index = 0; // ...wrap around to the beginning | |
average = (total / NUMREADINGS); // calculate the average | |
analogWrite(LED, average); | |
tone(speaker, average, 500); | |
Serial.println(average); // use output to aid in calibrating | |
delay(updateTime); | |
} | |
break; | |
case 7: | |
// BROWN NOTE | |
digitalOff(); | |
tone(speaker, 10000, 500); | |
break; | |
case 8: | |
// DOG WHISTLE | |
digitalOff(); | |
tone(speaker, 23000, 500); | |
break; | |
case 9: | |
// VOLTAGE DETECTOR | |
digitalOff(); | |
val = analogRead(probePin); // take a reading from the probe | |
if (val >= 1) { // if the reading isn't zero, proceed | |
val = constrain(val, 1, senseLimit); // turn any reading higher than the senseLimit value into the senseLimit value | |
val = map(val, 1, senseLimit, 1, 1023); // remap the constrained value within a 1 to 1023 range | |
total -= readings[index]; // subtract the last reading | |
readings[index] = val; // read from the sensor | |
total += readings[index]; // add the reading to the total | |
index = (index + 1); // advance to the next index | |
if (index >= NUMREADINGS) // if we're at the end of the array... | |
index = 0; // ...wrap around to the beginning | |
average = (total / NUMREADINGS); // calculate the average | |
if (average > 40) { | |
analogWrite(LED, average); | |
Serial.println(average); | |
} | |
delay(updateTime); | |
} | |
break; | |
case 10: | |
// VOLT METER | |
// http://arduino.cc/playground/Main/AOneLedVoltmeter | |
// read voltage value | |
/*voltage=analogRead(inputVoltagePin); | |
valueVolts=voltage/102; | |
valueHundrethsOfMilliVolts=((voltage % 102)*10)/102; | |
// send formated value to serial com port | |
Serial.print(valueVolts); | |
Serial.print('.'); | |
Serial.print(valueHundrethsOfMilliVolts); | |
Serial.println('V'); | |
// flash volts | |
for(int i=0;i<valueVolts;i++){ | |
digitalWrite(LED, HIGH); | |
delay(500); | |
digitalWrite(LED, LOW); | |
delay(500); | |
} | |
delay(1000); | |
// flash hundreths of millivolts | |
for(int i=0;i<valueHundrethsOfMilliVolts;i++){ | |
digitalWrite(LED, HIGH); | |
delay(100); | |
digitalWrite(LED, LOW); | |
delay(500); | |
} | |
// pause between readings | |
delay(5000);*/ | |
break; | |
case 11: | |
// OHM METER | |
/* | |
int analogPin = 0; // potentiometer middle terminal connected to analog pin 3 | |
// outside leads to ground and +5V | |
int raw = 0; // variable to store the raw input value | |
int Vin = 5; // variable to store the input voltage | |
float Vout = 0; // variable to store the output voltage | |
float R1 = 10; // variable to store the R1 value | |
float R2 = 0; // variable to store the R2 value | |
float buffer = 0; // buffer variable for calculation | |
raw = analogRead(analogPin); // Reads the Input PIN | |
Vout = (5.0 / 1023.0) * raw; // Calculates the Voltage on th Input PIN | |
buffer = (Vin / Vout) - 1; | |
R2 = R1 / buffer; | |
Serial.print("Voltage: "); // | |
Serial.println(Vout); // Outputs the information | |
Serial.print("R2: "); // | |
Serial.println(R2); // | |
delay(1000); | |
}*/ | |
break; | |
case 12: | |
// IR REMOTE | |
break; | |
case 13: | |
// METAL DETECTOR | |
break; | |
case 14: | |
// TONE GENERATOR | |
// http://www.phys-x.org/rbots/index.php?option=com_content&view=article&id=66:lesson-5-play-melody-with-piezo&catid=41:kits&Itemid=70 | |
digitalOff(); | |
// Set up a counter to pull from melody[] and beats[] | |
for (int i = 0; i < MAX_COUNT; i++) { | |
readButtons(); | |
toneM = melody[i]; | |
beat = beats[i]; | |
duration = beat * tempo; // Set up timing | |
playTone(); | |
// A pause between notes... | |
delayMicroseconds(pause); | |
} | |
break; | |
default: | |
digitalOff(); | |
// http://www.arduino.cc/playground/Main/UsbMemory | |
// http://www.instructables.com/id/A-simple-DIY-spectrophotometer/ | |
} | |
} | |
void readButtons() { | |
// READ BUTTON INPUTS | |
incUp = digitalRead(button2); | |
incDn = digitalRead(button3); | |
// INCREMENT UP | |
if (incUp == HIGH) { | |
settingCount++; | |
delay(200); | |
} | |
// INCREMENT DOWN | |
if (incDn == HIGH) { | |
// If the current state is HIGH then the button went from off to on | |
settingCount--; | |
delay(200); | |
} | |
// RESET COUNTER | |
if (incUp == HIGH && incDn == HIGH) { | |
settingCount = 0; | |
} | |
} | |
void digitalOff() { | |
// TURN EVERYTHING OFF | |
analogWrite(LED, LOW); | |
digitalWrite(IREMITTER, LOW); | |
digitalWrite(LASER, LOW); | |
digitalWrite(speaker, LOW); | |
/*for (int thisPin = 2; thisPin < 7; thisPin++) { | |
digitalWrite(thisPin, LOW); | |
}*/ | |
} | |
void playTone() { | |
// Pulse the speaker to play a tone for a particular duration | |
long elapsed_time = 0; | |
if (toneM > 0) { // 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(speaker, HIGH); | |
delayMicroseconds(toneM / 2); | |
// DOWN | |
digitalWrite(speaker, LOW); | |
delayMicroseconds(toneM / 2); | |
// Keep track of how long we pulsed | |
elapsed_time += (toneM); | |
} | |
} | |
else { // Rest beat; loop times delay | |
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count | |
delayMicroseconds(duration); | |
} | |
} | |
} | |
/* | |
void indicator() { | |
// BLINK THE LED ACCORDING TO THE SETTING | |
for (int i=0; i < settingCount; i++) { | |
digitalWrite(LED, HIGH); | |
delay(300); | |
digitalWrite(LED, LOW); | |
delay(300); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment