Skip to content

Instantly share code, notes, and snippets.

@gunthercox
Created December 1, 2012 01:13
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gunthercox/4179931 to your computer and use it in GitHub Desktop.
Save gunthercox/4179931 to your computer and use it in GitHub Desktop.
Arduino code for a sonic screwdriver.
// 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