Link to video: https://youtu.be/cn9VR3cG1EI

Narrative Description

An alarm clock that gets louder when you try to turn it off. It displays the current time and an alarm countdown on the LCD display, which can be triggered by pressing a push button. When the alarm countdown reaches zero, the alarm (a piezo buzzer) goes off. However, when you press the push button again to turn it off, the alarm gets louder (up to four times). When you are finally awake, you can turn off the alarm clock by twisting two knobs (potentiometers) next to the LCD display.

 

Progress Images

We decided early on to use piezo speakers instead of a more sophisticated speaker. Instead of changing the loudness of each individual speaker (and get a noticeable drop in sound quality), we decided to use four speakers to vary loudness.

 

 

 

 

We added an LCD display to make the product more intuitive. We noticed that most alarm clocks have front facing displays, so we opted to do the same to set up the expectation of a regular alarm clock.

 

 

We put all the parts together, and aggregated our code for the different subsystems into one, to get everything to work together.

 

 

 

 

 

Schematic

 

Code

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
</pre>
#include <Wire.h>
#include "rgb_lcd.h"
 
rgb_lcd lcd;
 
//rgb values
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
 
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
#define c 3830 // 261 Hz
#define d 3400 // 294 Hz
#define e 3038 // 329 Hz
#define f 2864 // 349 Hz
#define g 2550 // 392 Hz
#define a 2272 // 440 Hz
#define b 2028 // 493 Hz
#define C 1912 // 523 Hz
// Define a special note, 'R', to represent a rest
#define R 0
 
// SETUP ============================================
int speaker_1 = 3;
int speaker_2 = 5;
int speaker_3 = 6;
int speaker_4 = 9;
int button_pin = 8; //increases number of alarms and sets the alarm
 
int hour = 11;
int minute = 10;
int second = 0;
int alarm_counter = 9;
bool alarm_set = false;
 
int alarms_on = 0; // the number of alarms that are on
int button_press = 0; // button read
int threshold = 1000;
int pot_1 = 0; // pot read
int pot_2 = 0; // pot read
bool button_prev_pressed = false;
 
void setup() {
pinMode(speaker_1, OUTPUT);
pinMode(speaker_2, OUTPUT);
pinMode(speaker_3, OUTPUT);
pinMode(speaker_4, OUTPUT);
pinMode(button_pin, INPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
 
lcd.begin(16,2);
lcd.setRGB(colorR, colorG, colorB);
}
 
// MELODY and TIMING =======================================
// melody[] is an array of notes, accompanied by beats[],
// which sets each note's relative length (higher #, longer note)
int melody[] = { C, b, g, C, b, e, R, C, c, g, a, C };
int beats[] = { 16, 16, 16, 8, 8, 16, 32, 16, 16, 16, 8, 8 };
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 = 100; //<-BLETCHEROUS HACK; See NOTES
 
// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration = 0;
 
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
long elapsed_time = 0;
if (tone_ > 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) {
 
if (alarms_on == 4){
digitalWrite(speaker_1,HIGH);
digitalWrite(speaker_2,HIGH);
digitalWrite(speaker_3,HIGH);
digitalWrite(speaker_4,HIGH);
delayMicroseconds(tone_ / 2);
 
// DOWN
digitalWrite(speaker_1, LOW);
digitalWrite(speaker_2, LOW);
digitalWrite(speaker_3, LOW);
digitalWrite(speaker_4, LOW);
delayMicroseconds(tone_ / 2);
 
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
 
else if (alarms_on == 3){
digitalWrite(speaker_1,HIGH);
digitalWrite(speaker_2,HIGH);
digitalWrite(speaker_3,HIGH);
delayMicroseconds(tone_ / 2);
 
// DOWN
digitalWrite(speaker_1, LOW);
digitalWrite(speaker_2, LOW);
digitalWrite(speaker_3, LOW);
delayMicroseconds(tone_ / 2);
 
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
 
else if (alarms_on == 2){
digitalWrite(speaker_1,HIGH);
digitalWrite(speaker_2,HIGH);
delayMicroseconds(tone_ / 2);
 
// DOWN
digitalWrite(speaker_1, LOW);
digitalWrite(speaker_2, LOW);
delayMicroseconds(tone_ / 2);
 
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
 
else if (alarms_on == 1){
digitalWrite(speaker_1,HIGH);
delayMicroseconds(tone_ / 2);
 
// DOWN
digitalWrite(speaker_1, LOW);
delayMicroseconds(tone_ / 2);
 
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
 
else{
break;
 
}
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
 
void loop() {
 
//print current time
lcd.setCursor(0,0);
lcd.print(hour);
lcd.setCursor(2,0);
lcd.print(':');
lcd.setCursor(3,0);
lcd.print(minute);
lcd.setCursor(5,0);
lcd.print(':');
lcd.setCursor(6,0);
lcd.print(second);
 
//increment time
second = second + 1;
 
if (second == 60){
second = 0;
minute = minute + 1;
 
if (minute == 60){
minute = 0;
hour = hour + 1;
 
if (hour == 24){
hour = 0;
}
}
}
 
lcd.setCursor(0,1);
if (alarm_counter>=0){
lcd.print(alarm_counter);
}
 
button_press = digitalRead(button_pin);
 
if ((button_press) and (button_prev_pressed)){
button_press = false;
}
 
if ((button_press) and (!alarm_set) and (alarms_on == 0)){
alarm_set = true;
}
 
else if ((alarm_set) and (alarm_counter == 0)){
alarm_set = false;
alarms_on = 1;
alarm_counter = 9;
}
else if ((alarms_on > 0) and (alarms_on < 4) and (button_press)){
alarms_on = alarms_on + 1;
}
 
if (alarm_set){
alarm_counter = alarm_counter - 1;
}
 
pot_1 = analogRead(A0);
pot_2 = analogRead(A1);
 
if ((pot_1 > threshold) and (pot_2 > threshold)){
alarms_on = 0;
}
 
for (int i=0; i<MAX_COUNT; i++) {
tone_ = melody[i];
beat = beats[i];
 
duration = beat * tempo; // Set up timing
 
playTone();
// A pause between notes...
delayMicroseconds(pause);
 
}
}
<pre>

Discussion

The idea behind using four speakers to gradually make the alarm louder by pressing the ”snooze” button multiple times is an attempt to surprise someone by increasing the number of engaged speakers over time as triggered by (snooze) button press.  The waking up person might initially be confused as to why the snooze button made the alarm signal louder.  Upon multiple more snooze button presses, the user begins to realize they are only making the alarm louder by trying to silence it.  As the person becomes more focused they are forced to look for other solutions for turning off the alarm.  By playing around with the two potentiometers next to the LCD display, the user becomes engaged with the device as they troubleshoot ways for quieting the alarm sound.  The natural motion of a radial dial alludes to the idea of volume control and dual dials require two hands to be engaged, encouraging the user to focus on the activity at hand.