Water-spray Alarm Clock
A servo-activated alarm clock that instantly wakes you up by spraying water.
Images
Short clip of alarm clock
Decision Points
-
Switching the servo’s position
Initially, I envisioned the servo to trigger the water spray by pushing against the trigger from the front. This was conceptualized based on a previous project along the same lines. This was not feasible as I could not create a practical build where the servo provides sufficient force to trigger the water spray. However, through the guidance of the professor, he suggested to change the servo’s position to back of the water spray for a pulling mechanism which would be more efficient in triggering the water spray. This change in design ensured that proper functioning of my project!
-
Creating a separate build for the arduino, LCD and rotary encoders
My original design aspired for the alarm clock to be as compact as possible. As seen in my sketch, I wanted all the hardwares to be mounted on the water spray so it could occupy the least space on my side table. My initial trials were futile as I tried to tape and super glue the arduino and LCD display on the water spray with a box that covers it. This was potentially practical when the servo motor was at the front of the water spray. However, the servo motor required a base behind the water spray which meant none of these designs could be accomplished. So, I used laser cutting to create a separate box that included all my other hardware. Nevertheless, this change appeared to be most practical and visually appealing.
Critiques
“Such a useful device that definitely wakes me up.”
This was definitely my intention, as a person who frequently misses their morning alarms, I wanted to create a device that wakes me up in the first go. Though the mist is quite refreshing in the first spray, it gets annoying when it triggers multiple times when the alarm rings!
“Do you like to sleep with wet pillows?”
This was something I did not consider! I did not foresee that it would make my bed wet after it sprays a number of times. Thankfully, the water spray only sprays mist as compared to water droplets which mitigates this issue. However, I would have to find waterproof bedding now onwards.
Discussion
I was extremely delighted when I first saw the water spray being triggered by the servo based on the alarm time. It met the basic functionality that I had originally envisioned. I couldn’t wait to try it out in my room when it worked in the physical computing lab. The first few tests seemed to work perfectly but it filled me with dread upon realising that it would ruin my mornings if it disrupted my dreams or sleep cycles.
This project provided insights into the process of designing and building prototypes which I have never done before in my life. The structured delivery timeline ensured I was on time for all my deliverables while providing incentive to work ahead of the deadline. There were times where I was at the end of my wits when the servo did not trigger as expected. During the process, I found myself stuck in a particular way of thinking which limits my creativity and in this case, without the help of the professor, I would not have been able to overcome it. It emphasized the importance of having some degree of flexibility from the design of the prototype in the actual implementation as we cannot foresee everything from the get-go.
After finishing the project, I planned to 3D print a build that accomodates everything on the water spray but eventually dropped the idea to focus on other upcoming deliverables. I would try to create a build with a smaller base for the servo motor using other alternates besides styrofoam. Additionally, would try to find a way to screw the servo into the water spray or the base to ensure that it does not come off loose as the current project is hot glued together and might come off after frequent number of triggers. I would incorporate other design changes such as adding a snooze function which is not a simple switch at the top, add a water level sensor to remind the user when the bottle is empty.
Schematic and block diagrams
Code
/* Project Title: Water-spray Alarm Clock Name: Siddharth Parthiban Description: User sets the time for the alarm by rotating the two rotary encoders whereby controlling the hours and the minutes which is displayed by the LCD Screen. The RTC module provides the input for the current time and when both the alarm and the current time is the same, the code directs the servo to rotates 40 degrees back and forth to trigger the water spray. Additionally, as a snooze button, the switch controls whether the water spray is triggered multiple times during the alarm duration. Pin Mapping: Arduino pin | role | description ------------|---------|------------- 2 input rotary encoder(hour) pin A 3 input rotary encoder(hour) pin B 5 input rotary encoder(min) pin A 6 input rotary encoder(min) pin B 8 output Servo motor 10 input switch SCL input RTC Module/LCD SDA input RTC Module/LCD Rotary Encoder Code adapted from https://dronebotworkshop.com/rotary-encoders-arduino/#Arduino_Motor_Encoder_Sketch DroneBot Workshop 2019 */ #include <Encoder.h> #include <Servo.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <DS3232RTC.h> //Initialising variables for user input long rotatMin = 0; long prevRotatMin = -999; int alarmMinute; int alarmHour; int curMinute; int curHour; long rotatHour = 0; long prevRotatHour= -999; //Initialising variable for output int servoDegree = 20; float oldTimeDisplay = 0; //Initialising pin ports for Arduino int SWITCHPIN = 10; const int SERVOMOTORPIN = 8; //Creating Servo, Rotary Encoder and RTC module objects Servo servoMotor; Encoder hourEncod(2,3); Encoder minEncod(5,6); DS3232RTC myRTC; //Declaring LCD screen object LiquidCrystal_I2C screen(0x27, 16, 2); void setup() { Serial.begin(9600); //setting data rate pinMode(SWITCHPIN, INPUT); //declaring switch for arduino //Setting up servo motor servoMotor.attach(SERVOMOTORPIN); servoMotor.write(servoDegree); //Setting up LCD Screen screen.init(); screen.backlight(); screen.home(); } void loop() { time_t t = myRTC.get(); //Get current time //Read user input from rotary encoder rotatMin = minEncod.read(); rotatHour = hourEncod.read(); //Calculate the minutes based on rotations if (rotatMin != prevRotatMin){ prevRotatMin = rotatMin; //Rotations divided by 4 to set an arbitrary unit for 1 turn of the knob //Modulo 60 to get convert turns to respective minutes //if-else statements to consider anti-clockwise turns if (rotatMin < 0){ alarmMinute = (-(rotatMin/4)) % 60; } else { alarmMinute = (rotatMin/4) % 60; } //Display set minutes to LCD Screen screen.setCursor(12,1); screen.print((String)alarmMinute); } //Calculate hour based on rotations if (rotatHour != prevRotatHour){ prevRotatHour = rotatHour; //Rotations divided by 4 to set an arbitrary unit for 1 turn of the knob //Modulo 24 to get convert turns to respective hour //if-else statements to consider anti-clockwise turns if (rotatHour < 0){ alarmHour = (-(rotatHour)/4) % 24; } else { alarmHour = (rotatHour/4) % 24; } //Display hour on LCD Screen screen.setCursor(9,1); screen.print((String)alarmHour + ":"); } //Move servo motor if not on snooze to trigger water spray if (digitalRead(SWITCHPIN) == 0){ //Check if current time is equal to alarm time if (minute(t) == alarmMinute && hour(t) == alarmHour){ servoMotor.write(servoDegree + 90); delay(500); servoMotor.write(servoDegree - 50); delay(1000); servoMotor.write(servoDegree + 90); delay(500); servoMotor.write(servoDegree - 50); } } //Reset servo motor to neutral position servoDegree = 20; servoMotor.write(servoDegree); //Display values to LCD Screen if (millis() - oldTimeDisplay >= 250) { oldTimeDisplay = millis(); screen.clear(); screen.setCursor(2, 0); screen.print("Time"); screen.setCursor(2, 1); screen.print((String)hour(t)+ ":" +(String) minute(t)); screen.setCursor(8, 0); screen.print("Alarm"); screen.setCursor(9, 1); screen.print((String)alarmHour + ":" + (String) alarmMinute); } }