Applause Alarm Clock
Using lights, a proximity diffuse, and canned applause, this alarm clock is a stubbornly encouraging way to wake up.

coming in at about 16″ x 6″ x 5.5″, this bad boy has presence and a punch

the top of the box opens for access to the internal electrical components. A gap is left along its hinge, leaving room for wires to power sources and the external motion sensor.

theres something very Ark of the Covenant about servicing this device through its top hatch
Process

I spent a bit of time fitting the piece of acrylic into a wooden “U” shape. In the beginning of this project, I wanted to be able to switch out what the message displayed would be. This fitting process to a long time, and ultimately I had to cut that idea short and commit to figuring out the “APPLAUSE” text the best way I could.

In my first attempt at creating the text, I handdrew the lettering on a piece of fitted tracing paper. However, I wasn’t happy with how the light revealed all of the pen strokes. Knowing that a most onlooker attention would be drawn to the letters, I discarded this draft.

After sleeping on it, I dug around the things I had accumulated during college and was reminded of an old Christmas gift my sister gave me. Pulling letters from a novelty marquee, I couldn’t believe I hadn’t thought of this sooner.
Discussion
I think in my own reflection, I have mixed feelings about how this project turned out. I definitely experienced the warning around budgeting time for nonlinear progress in the project. By the time I thought I would be halfway done, it became evident that I had 80% more to go. Still, I impressed myself that I was able to make a project that was this functional, as I’ve struggled in the past with projects that had less components. Still, my ideal vision for this project would probably require one or two more work sessions to polish the form for a full mount to the ceiling. Additionally, I would want to spend some more time creating acrylic slides.
I do like the rough quality to my current iteration. I had one of my favorite artists, Tom Sachs, in mind as I was working. Sachs’ process is transparent, in that materiality isn’t hidden and pencil marks aren’t erased. A challenge I gave myself was to grab all of the materials I was using from what was left behind by past tenants in my apartment. This limitation yielded interesting final aesthetic, with old layers of paint on my wood collaged back into a new life.
Reading other’s feedback was great. I especially liked the suggestion that “having an internal timer where the applause turns into booing if you don’t get up after a certain amount of time could be funny.” Such a missed initial opportunity! If I revisit this project, I will definitely find a way to map the time to a shift from applause to booing. It’s interesting to see some of my initial reflection surface in others’ suggestions as well. Someone wrote “I loved the end result/aesthetic of the product! Simple yet with a great concept. It would be cool if people could customize sounds + text later on if the idea is built.” I am ecstatic that the simple and honest aesthetic vision came through to others. That was an element I was getting a lot of pushback on from my peers in design. It wasn’t the kind of project intended to fall neatly into functional nor novelty. The suggestion to customize sounds is also a great blindspot to recognize. I remember when presenting live someone suggested incorporating an LED screen to adjust the wakeup time. I think this would be a great place to scroll through sounds to vary morning to morning. I am curious what alternatives there are to uploading custom sounds via SD card.
Schematic
Code
- <span class="com">/*
- * Applause Alarm Clock
- * Connor McGaffin (cmcgaffi)
- *
- * Description: The code below controls an alarm clock in the form of an live-show applause sign.
- * At a designated time, a real time clock module triggers two LED panels to illuminate frosted acrylic with
- * "APPLAUSE" written across it in black. This is accompanied by a looping canned track of studio
- * audience applause, which can be turned off in tandem with the lights by input on a motion sensor intended
- * to be installed outside of one's bedroom.
- *
- * Pin mapping:
- *
- * pin | mode | description
- * ------|--------|------------
- * 7 input pir pin
- * 8 output led panel
- * 9 output led panel
- * 10 output dfplayer tx
- * 11 input dfplayer rx
- * SCL output rtc serial clock
- * SDA input rtc serial data
- *
- * CREDIT: i couldn't have done this without
- * DFRobotDFPlayerMini Library - written by Angelo quiao
- * https://github.com/DFRobot/DFRobotDFPlayerMini
- * DS3231 Library - written by A. Wickert, E. Ayars, J. C. Wippler
- * https://github.com/NorthernWidget/DS3231
- *
- */</span><span class="pln">
- </span><span class="com">#include</span><span class="pln"> </span><span class="str">"Arduino.h"</span><span class="pln">
- </span><span class="com">#include</span><span class="pln"> </span><span class="str">"SoftwareSerial.h"</span><span class="pln">
- </span><span class="com">#include</span><span class="pln"> </span><span class="str">"DFRobotDFPlayerMini.h"</span><span class="pln">
- </span><span class="com">#include</span><span class="pln"> </span><span class="str"><DS3231.h></span><span class="pln">
- </span><span class="com">#include</span><span class="pln"> </span><span class="str"><Wire.h></span><span class="pln">
- DS3231 rtc</span><span class="pun">(</span><span class="pln">SDA</span><span class="pun">,</span><span class="pln"> SCL</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Time</span><span class="pln"> t</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">Hor</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">Min</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">Sec</span><span class="pun">;</span><span class="pln">
- </span><span class="typ">SoftwareSerial</span><span class="pln"> mySoftwareSerial</span><span class="pun">(</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">11</span><span class="pun">);</span><span class="pln"> </span><span class="com">// RX, TX</span><span class="pln">
- </span><span class="typ">DFRobotDFPlayerMini</span><span class="pln"> myDFPlayer</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LEDPIN1 </span><span class="pun">=</span><span class="pln"> </span><span class="lit">9</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LEDPIN2 </span><span class="pun">=</span><span class="pln"> </span><span class="lit">8</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIRPIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">7</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> val </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">()</span><span class="pln">
- </span><span class="pun">{</span><span class="pln">
- mySoftwareSerial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">();</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">LEDPIN1</span><span class="pun">,</span><span class="pln"> OUTPUT</span><span class="pun">);</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">LEDPIN2</span><span class="pun">,</span><span class="pln"> OUTPUT</span><span class="pun">);</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">PIRPIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Wire</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">();</span><span class="pln">
- rtc</span><span class="pun">.</span><span class="kwd">begin</span><span class="pln"> </span><span class="pun">();</span><span class="pln">
- rtc</span><span class="pun">.</span><span class="pln">setTime</span><span class="pun">(</span><span class="lit">00</span><span class="pun">,</span><span class="lit">00</span><span class="pun">,</span><span class="lit">0</span><span class="pun">);</span><span class="pln"> </span><span class="com">//set time</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">myDFPlayer</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="pln">mySoftwareSerial</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// use softwareSerial to communicate with mp3.</span><span class="pln">
- </span><span class="kwd">while</span><span class="pun">(</span><span class="kwd">true</span><span class="pun">);</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- myDFPlayer</span><span class="pun">.</span><span class="pln">volume</span><span class="pun">(</span><span class="lit">20</span><span class="pun">);</span><span class="pln"> </span><span class="com">// volume set out of 30</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">()</span><span class="pln">
- </span><span class="pun">{</span><span class="pln">
- t </span><span class="pun">=</span><span class="pln"> rtc</span><span class="pun">.</span><span class="pln">getTime</span><span class="pun">();</span><span class="pln">
- </span><span class="typ">Hor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> t</span><span class="pun">.</span><span class="pln">hour</span><span class="pun">;</span><span class="pln">
- </span><span class="typ">Min</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> t</span><span class="pun">.</span><span class="pln">min</span><span class="pun">;</span><span class="pln">
- </span><span class="typ">Sec</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> t</span><span class="pun">.</span><span class="pln">sec</span><span class="pun">;</span><span class="pln">
- val </span><span class="pun">=</span><span class="pln"> digitalRead</span><span class="pun">(</span><span class="pln">PIRPIN</span><span class="pun">);</span><span class="pln"> </span><span class="com">// read sensor input </span><span class="pln">
- </span><span class="kwd">if</span><span class="pun">(</span><span class="pln"> </span><span class="typ">Hor</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Min</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">30</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> </span><span class="typ">Min</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">31</span><span class="pun">)){</span><span class="pln"> </span><span class="com">// if the current time matches the alarm time </span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">val </span><span class="pun">==</span><span class="pln"> LOW</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">//if sensor input is LOW</span><span class="pln">
- </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> timer </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">();</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">millis</span><span class="pun">()</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> timer </span><span class="pun">></span><span class="pln"> </span><span class="lit">25000</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- timer </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">();</span><span class="pln">
- myDFPlayer</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">1</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Play the first mp3 again every 25 seconds (length of file) </span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LEDPIN1</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln"> </span><span class="com">// LED is on </span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LEDPIN2</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
- </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// if sensor input is HIGH</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LEDPIN1</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln"> </span><span class="com">// LED turns off</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LEDPIN2</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
- myDFPlayer</span><span class="pun">.</span><span class="pln">stop</span><span class="pun">();</span><span class="pln"> </span><span class="com">// stops playing applause</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">60000</span><span class="pun">);</span><span class="pln"> </span><span class="com">// runs out clock on rest of alarmed minute</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="com">// vvv MP3 PLAYER SERIAL STATUS CODE vvv //</span><span class="pln">
- </span><span class="kwd">void</span><span class="pln"> printDetail</span><span class="pun">(</span><span class="typ">uint8_t</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="kwd">value</span><span class="pun">){</span><span class="pln">
- </span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="pln">type</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">TimeOut</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Time Out!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">WrongStack</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Stack Wrong!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">DFPlayerCardInserted</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Card Inserted!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">DFPlayerCardRemoved</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Card Removed!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">DFPlayerCardOnline</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Card Online!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">DFPlayerPlayFinished</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Number:"</span><span class="pun">));</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="kwd">value</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">" Play Finished!"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">DFPlayerError</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"DFPlayerError:"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">value</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">Busy</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Card not found"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">Sleeping</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Sleeping"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">SerialWrongStack</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Get Wrong Stack"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">CheckSumNotMatch</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Check Sum Not Match"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">FileIndexOut</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"File Index Out of Bound"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">FileMismatch</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"Cannot Find File"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">case</span><span class="pln"> </span><span class="typ">Advertise</span><span class="pun">:</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">F</span><span class="pun">(</span><span class="str">"In Advertise"</span><span class="pun">));</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">default</span><span class="pun">:</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="kwd">default</span><span class="pun">:</span><span class="pln">
- </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="pun">}</span>