-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathArduinoMetalDetector.ino
More file actions
123 lines (104 loc) · 3.24 KB
/
ArduinoMetalDetector.ino
File metadata and controls
123 lines (104 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Copyright (c) 2016 Evan Kale
* Media: @EvanKale91
* Email: EvanKale91@gmail.com
* Website: www.ISeeDeadPixel.com
* www.evankale.blogspot.ca
* www.youtube.com/EvanKale91
*
* This file is part of ArduinoMetalDetector.
*
* ArduinoMetalDetector is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Number of cycles from external counter needed to generate a signal event
#define CYCLES_PER_SIGNAL 5000
// Base tone frequency (speaker)
#define BASE_TONE_FREQUENCY 280
// Frequency delta threshold for fancy spinner to trigger
#define SPINNER_THRESHOLD 700
// Pin definitions
#define SENSITIVITY_POT_APIN 1
#define SPEAKER_PIN 2
#define SPINNER_PIN 9
#define TRIGGER_BTN_PIN 11
#define RESET_BTN_PIN 12
unsigned long lastSignalTime = 0;
unsigned long signalTimeDelta = 0;
boolean firstSignal = true;
unsigned long storedTimeDelta = 0;
// This signal is called whenever OCR1A reaches 0
// (Note: OCR1A is decremented on every external clock cycle)
SIGNAL(TIMER1_COMPA_vect)
{
unsigned long currentTime = micros();
signalTimeDelta = currentTime - lastSignalTime;
lastSignalTime = currentTime;
if (firstSignal)
{
firstSignal = false;
}
else if (storedTimeDelta == 0)
{
storedTimeDelta = signalTimeDelta;
}
// Reset OCR1A
OCR1A += CYCLES_PER_SIGNAL;
}
void setup()
{
// Set WGM(Waveform Generation Mode) to 0 (Normal)
TCCR1A = 0b00000000;
// Set CSS(Clock Speed Selection) to 0b111 (External clock source on T0 pin
// (ie, pin 5 on UNO). Clock on rising edge.)
TCCR1B = 0b00000111;
// Enable timer compare interrupt A (ie, SIGNAL(TIMER1_COMPA_VECT))
TIMSK1 |= (1 << OCIE1A);
// Set OCR1A (timer A counter) to 1 to trigger interrupt on next cycle
OCR1A = 1;
pinMode(SPEAKER_PIN, OUTPUT);
pinMode(SPINNER_PIN, OUTPUT);
pinMode(TRIGGER_BTN_PIN, INPUT_PULLUP);
pinMode(RESET_BTN_PIN, INPUT_PULLUP);
}
void loop()
{
if (digitalRead(TRIGGER_BTN_PIN) == LOW)
{
float sensitivity = mapFloat(analogRead(SENSITIVITY_POT_APIN), 0, 1023, 0.5, 10.0);
int storedTimeDeltaDifference = (storedTimeDelta - signalTimeDelta) * sensitivity;
tone(SPEAKER_PIN, BASE_TONE_FREQUENCY + storedTimeDeltaDifference);
if (storedTimeDeltaDifference > SPINNER_THRESHOLD)
{
digitalWrite(SPINNER_PIN, HIGH);
}
else
{
digitalWrite(SPINNER_PIN, LOW);
}
}
else
{
noTone(SPEAKER_PIN);
digitalWrite(SPINNER_PIN, LOW);
}
if (digitalRead(RESET_BTN_PIN) == LOW)
{
storedTimeDelta = 0;
}
}
float mapFloat(int input, int inMin, int inMax, float outMin, float outMax)
{
float scale = (float)(input - inMin) / (inMax - inMin);
return ((outMax - outMin) * scale) + outMin;
}