We created a braille alarm clock. The alarm clock is fully functional by someone who is both without sight and hard of hearing. The user can check and reset the current time, as well as set the time for when they’d like their alarm to go off, and it will reliably do so.
Final clock with bed shaker and original alarm clock on presentation day
Top interface of clock with 12 red buttons in a circle for the clock, and 2 red buttons on the left (alarm and clock), and 2 green buttons (set and clear)
Right side of prototype with solenoid and rocker switch
Back of clock with acrylic flower details and power plug
Additional flower acrylic details at the front
Alycia testing out our final device. (Seated to the right of the a table is Alycia, a middle-aged woman with long hair. She is pressing buttons on a pink box that acts as a clock with brailled on it)
Alicia has a big day tomorrow and wants to get an early start in the morning. She goes to her alarm clock, presses the arcade button marked Alarm and then shifts her hand to the clock buttons. She presses the fifth button, and then the sixth button: 5:30.She then presses a different button market Set. Just to double check that she didn’t make a mistake, she presses the Alarm button once more. Now the exciting part… she shifts her hand to the right wall of the clock, feeling for a circle opening with felt under it. Two of her fingers lightly rest on the felt and she waits. Tap, Tap, Tap, Tap, Tap. 5. There’s a short pause. Tap, Tap, Tap. 3. There’s a much pause. 0. A quick Tap-Tap. Knowing that the end of the sequence is always marked by the Tap-Tap, she goes to bed content.
Come morning time, the bed shaker violently rocks her bed waking her up. She gets out of bed, goes to the alarm clock and switches the switch from ON to OFF. The bed shaker stops immediately. She wants to check the time just to ensure she didn’t miss anything in her day, so she presses Clock and moves her fingers to the felt again. 5 taps, 3 taps, and 1 tap. 5:31am. She nods with satisfaction and starts her day.
This prototype was designed to help answer the design question: How do we make an alarm clock for a blind person that is hard of hearing?
First meeting discussion possible ideas
Second meeting discussing clock ideas
Final 3 ideas for prototyping
Prototype 1: Two clocks where each number is a button. The first clock would be for setting the hours, and the second clock would be for setting the minutes.
Prototype 2: A finger slider, where you put your finger on a slider and the top of your finger would slide across different braille numbers. When you got to the number you wanted first, you would press set, and that would set the hours. Then for the minutes, you would slide to the number you wanted and that would set the minutes.
Prototype 3: The third idea is similar to a rotary phone where you would put your finger in a small hole and circle around all the numbers to the number you were looking for. In each number spot would be braille that the user can read, and they would use the rotary system to set the hours and then minutes of their alarm.
testing prototypes with Alycia
Alycia showing us how to make braille on dymo tape
(Alycia is using a poking device and a braille grid to press indentations onto sticky tape)
All of our prototypes were feasible, yet how we moved forward was solely to the discretion of our client and what her personal preference was in terms of the alarm. She chose Prototype 1, where the interface is all buttons in a circle.
We were a bit surprised that the client chose the option she did. When she went over her reasoning, she explained that practicality and ease-of-use in the long term were her main decision factors. The other ideas were fun and exciting, but there’s much less that could go wrong with simple buttons. She also gave feedback that was eye-opening in the sense that we were underestimating her skills ability to a great extent. Things such as only needing one button clock interface and not two, and needing less braille options, her intuit knowledge that could help her use the alarm with ease. Initially when designing and speaking amongst each other, we were approaching the prototype as if we had just lost our vision and were encountering the world for the first time. However, after talking with Alyicia, we were able to revise our prototypes and make them not only braille friendly, but also extremely intuitive to her needs.
Feedback we took from the critique was to make it only one clock interface, as well as to change the button size. Alicia opted for smaller buttons around the clock as those would decrease the overall size of the alarm. She also mentioned the need for there to be ample space around each button as that would ensure there was enough room for her dymo tape to stick on. Thus, we made sure to account for the braille attachments and their length and width in each button design. She also told us she had no need for a Snooze button, nor did she need an option to set any time more than the multiples of five. This type of feedback was pivotal to our further discussion of how to implement the alarm clock successfully.
Something we hadn’t even considered before she brought it up, was being able to tell the normal time of the day using the alarm clock. She informed us this was normal practice on her existing braille alarm clock that didn’t work that well. Initially we chose not to focus on this as the clock module should have been able to reliably keep the time and there would be no reason to doubt it. However, after much discussion as a team and with our professor, we reimplemented it as a feature.
The programmable portion of the alarm clock was based on a finite state machine, a concept that David was familiar with from his ECE studies. This style of design was chosen because an alarm clock enters through many states during its usage, and transitioning between states based on inputs (and generating outputs at the right time) are all central ideas to an FSM. The final product ended up with seven states, and it worked extremely well- it allowed for coding details much easier, as it helped partition up the overall complicated structure into smaller, more manageable pieces. That being said, coding did have its fair share of difficulties. Converting a button into a toggle-able input was surprisingly complex; it involved debouncing a button to prevent erroneous multiple readings upon press and release of the button, as well as checking to make sure when a button is pressed and held (and not causing the incorrect interpretation of multiple button presses). The code also involved understanding a RTC (real-time clock) library, which had its own hidden difficulties (we had spent nearly an hour panicking as to why the clock was not working until we realized we hadn’t written the code to actually START the clock!). With respect to the Gantt chart, there was some divergence from the original plan, because testing the code proved to be more reliant upon the hardware it worked with- for example, it was impossible to check if anything related to the clock was working if there was no clock module, which we did not receive until much later than anticipated. Nonetheless, the code was still completed and thoroughly debugged.
There were a few tricky components to the circuitry, such as the solenoid and the interfacing of the bed shaker and its power supply. The solenoid needed to be powered directly by a 12VDC power supply, yet it had to be controlled by the Arduino; as such, a transistor circuit was used to act as a “switch” that the Arduino could control to allow for power to the solenoid. Interfacing with the bed shaker proved to be very complicated, due to the strange peculiarity that it ran off of 9VAC. Creating a switch for 9V, being alternating current as well, was rather difficult, since that implied it would require a power supply that could not be unified in any way with the Arduino (unlike the solenoid, whose 12VDC power supply could also be used for the Arduino). Controlling an AC power supply also required the use of a relay, which was in essence, a switch for AC power supplies, similar to the transistor. The relay proved to also be troublesome in that it would draw too much current from the Arduino should it be directly connected, and that meant that another transistor circuit was needed for the relay- in essence, a switch for the switch. It was certainly a confusing set of circuitry- a memorable moment was when the transistor was actually fried due to an incorrect wiring, which then caused subsequent correct wirings to not work as well.
We learned throughout the process that planning was very important to ensure that we could get all the different parts done well. Since we each had different responsibilities, it was important that we communicated our schedules well and adjusted our work plan as needed so that everyone in the group could work on their responsibilities. Especially for our code-heavy project, we found that it was always better to test early and test more. There would often be small edge cases that would mess with how our clock worked. Changes also needed to be made physically, such as adding another button or changing where the buttons were placed, which would help make using the device easier for Alycia. Additionally, we realized that we could make the best device only if we knew what the client actually needed and wanted. Rather than making assumptions, we always made sure to ask Alycia on what she thought would work the best for her as well as what she wanted from the project. There were times when her responses reassured our progress, and other where we were surprised by what she said and would have to rethink our ideas. In the end, we were grateful that Alycia was very cooperative and responsive to us during this project as we were able to produce a product that she liked as well.
A common, but important piece of advice that was given was that “Though it’s for a blind person, for presentations sake, there could have been some visual labels.” This would allow for those who were NOT Alycia (eg. caretakers, friends, etc.) to be able to understand what was what on the clock. This would be a simple change, but extremely necessary, since as of now, we only know which buttons are what simply because we are the creators. There were also comments on the alarm clock having “other features that many clocks have (i.e., snooze).” This was also a fair point, and was considered by our team; given more time, this definitely could have been done. While we considered the situation of having too many inputs and causing confusion rather than more features, simple thoughts like “Different shape on the “12” button” to help find/distinguish the clock buttons easier would be useful and helpful to implement.
/* Project Title: Tactile Alarm Clock * Creator: David Wu, Noni Shelton, and Catherine Liu * * This code is similar to a finite state machine for * an alarm clock. There are 12 button inputs for the 12 * numbers on the clock. There are 4 other button inputs * for miscellaneous purposes, being the alarm, clock, * set, and clear buttons. The 16 button inputs are each * involved in 2 arrays to facilitate checking for button * presses and button holding. An on/off input is used to * determine if the alarm is turned on or not. An output signal * to a solenoid allows it to tap the time in an specified, * encoded manner. The code outputs its alarm signal at a certain * pin, and for this project, this is intended to connect the * bed shaker to its power supply. * * Pin Mapping: * Clock 12 : 12 Clock 6 : 6 * Clock 1 : 13 Clock 7 : 7 * Clock 2 : 2 Clock 8 : 8 * Clock 3 : 3 Clock 9 : 9 * Clock 4 : 4 Clock 10 : 10 * Clock 5 : 5 Clock 11 : 11 * Doing Alarm : 27 * Doing Clock : 26 * Set : 24 * Clear : 22 * Alarm On/Off : 28 * Solenoid : 30 * Alarm output (bed shaker) : 33 * */ #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; // clock 12 inputs const int CLOCKPIN0 = 12; const int CLOCKPIN1 = 13; const int CLOCKPIN2 = 2; const int CLOCKPIN3 = 3; const int CLOCKPIN4 = 4; const int CLOCKPIN5 = 5; const int CLOCKPIN6 = 6; const int CLOCKPIN7 = 7; const int CLOCKPIN8 = 8; const int CLOCKPIN9 = 9; const int CLOCKPIN10 = 10; const int CLOCKPIN11 = 11; // the miscellaneous buttons const int DOING_ALARMPIN = 27; const int DOING_CLOCKPIN = 26; const int SETPIN = 24; const int CLEARPIN = 22; // alarm on/off const int ON_OFFPIN = 28; // outputs const int SOLEPIN = 30; const int BEDSHAKERPIN = 33; // state management int currState = 0; int nextState = 0; const int defaultState = 0; const int alarmState = 1; const int clockState = 2; const int setAlarmHourState = 3; const int setClockHourState = 4; const int setAlarmMinState = 5; const int setClockMinState = 6; const int alarmTriggered = 7; // clock 12 inputs int clockInput[12]; int clockPressed[12]; // the miscellaneous buttons // misc inputs: doing_alarm, doing_clock, set, clear int miscInput[4]; int miscPressed[4]; // alarm on/off bool isOn = true; // time management // arbitrary default setting when clock is first turned on const int DEFAULT_HOUR = 7; int alarmHour = DEFAULT_HOUR; int alarmMin = 0; int tempHour = DEFAULT_HOUR; int tempMin = 0; void setup() { pinMode(CLOCKPIN0, INPUT); pinMode(CLOCKPIN1, INPUT); pinMode(CLOCKPIN2, INPUT); pinMode(CLOCKPIN3, INPUT); pinMode(CLOCKPIN4, INPUT); pinMode(CLOCKPIN5, INPUT); pinMode(CLOCKPIN6, INPUT); pinMode(CLOCKPIN7, INPUT); pinMode(CLOCKPIN8, INPUT); pinMode(CLOCKPIN9, INPUT); pinMode(CLOCKPIN10, INPUT); pinMode(CLOCKPIN11, INPUT); pinMode(DOING_ALARMPIN, INPUT); pinMode(DOING_CLOCKPIN, INPUT); pinMode(SETPIN, INPUT); pinMode(CLEARPIN, INPUT); pinMode(ON_OFFPIN, INPUT); pinMode(SOLEPIN, OUTPUT); pinMode(BEDSHAKERPIN, OUTPUT); // ensure rtc is found and we can start if (!rtc.begin()) { while (1); } // initialize an arbitrary time (12:34) // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); rtc.adjust(DateTime(2000, 1, 1, 12, 34, 0)); Serial.begin(9600); } void loop() { // clock 12 inputs clockInput[0] = digitalRead(CLOCKPIN0); clockInput[1] = digitalRead(CLOCKPIN1); clockInput[2] = digitalRead(CLOCKPIN2); clockInput[3] = digitalRead(CLOCKPIN3); clockInput[4] = digitalRead(CLOCKPIN4); clockInput[5] = digitalRead(CLOCKPIN5); clockInput[6] = digitalRead(CLOCKPIN6); clockInput[7] = digitalRead(CLOCKPIN7); clockInput[8] = digitalRead(CLOCKPIN8); clockInput[9] = digitalRead(CLOCKPIN9); clockInput[10] = digitalRead(CLOCKPIN10); clockInput[11] = digitalRead(CLOCKPIN11); // misc inputs: doing_alarm, doing_clock, set, clear miscInput[0] = !digitalRead(DOING_ALARMPIN); // normally closed button miscInput[1] = !digitalRead(DOING_CLOCKPIN); // normally closed button miscInput[2] = digitalRead(SETPIN); miscInput[3] = digitalRead(CLEARPIN); // alarm on/off isOn = digitalRead(ON_OFFPIN); // find if/which clockInput was pressed int trigClockButton = -1; for (int i = 0; i < 12; i++) { if (clockInput[i] == 1) { trigClockButton = i; } } // find if/which miscInput was pressed int trigMiscButton = -1; for (int i = 0; i < 4; i++) { if (miscInput[i] == 1) { trigMiscButton = i; } } // when to start output if (isOn) { DateTime now = rtc.now(); if ((convert12Hour(now.hour()) == alarmHour) && (now.minute() == alarmMin) && (now.second() < 5)) { currState = alarmTriggered; } } // figure out next state and output if (currState == alarmTriggered) { if(!isOn) { digitalWrite(BEDSHAKERPIN, LOW); nextState = defaultState; } else { digitalWrite(BEDSHAKERPIN, HIGH); nextState = alarmTriggered; } } else if (trigMiscButton != -1) handlePressedMiscButton(trigMiscButton); else if (trigClockButton != -1) handlePressedClockButton(trigClockButton); else nextState = currState; // update unpressed buttons // when a clockInput is unpressed and was pressed before for (int i = 0; i < 12; i++) { if (!clockInput[i] && clockPressed[i]) { delay(30); } } // when a miscInput is unpressed and was pressed before for (int i = 0; i < 4; i++) { if (!miscInput[i] && miscPressed[i]) { delay(30); } } //update info clockPressed[0] = clockInput[0]; clockPressed[1] = clockInput[1]; clockPressed[2] = clockInput[2]; clockPressed[3] = clockInput[3]; clockPressed[4] = clockInput[4]; clockPressed[5] = clockInput[5]; clockPressed[6] = clockInput[6]; clockPressed[7] = clockInput[7]; clockPressed[8] = clockInput[8]; clockPressed[9] = clockInput[9]; clockPressed[10] = clockInput[10]; clockPressed[11] = clockInput[11]; miscPressed[0] = miscInput[0]; miscPressed[1] = miscInput[1]; miscPressed[2] = miscInput[2]; miscPressed[3] = miscInput[3]; currState = nextState; } void handlePressedClockButton (int index) { // when the clockInput is pressed and was not pressed before if (!clockPressed[index]) { delay(30); switch (currState) { // if alarm is triggered, ignore everything case alarmTriggered: break; case alarmState: tempHour = index; if (tempHour == 0) tempHour = 12; nextState = setAlarmHourState; break; case clockState: tempHour = index; if (tempHour == 0) tempHour = 12; nextState = setClockHourState; break; case setAlarmHourState: tempMin = index * 5; nextState = setAlarmMinState; break; case setClockHourState: tempMin = index * 5; nextState = setClockMinState; break; default: nextState = currState; break; } } } void handlePressedMiscButton (int index) { // misc inputs: doing_alarm, doing_clock, set, clear // when the miscInput is pressed and was not pressed before if (!miscPressed[index]) { delay(30); // if alarm is triggered, ignore everything if (currState == alarmTriggered) { nextState = alarmTriggered; } // doing_alarm else if (index == 0) { solenoidTapping(alarmHour, alarmMin); nextState = alarmState; } // doing_clock else if (index == 1) { DateTime now = rtc.now(); solenoidTapping(convert12Hour(now.hour()), now.minute()); nextState = clockState; } else { switch (currState) { case alarmState: case setAlarmHourState: if (index == 2) { // not complete inputs tempHour = DEFAULT_HOUR; tempMin = 0; nextState = defaultState; } else if (index == 3) { tempHour = DEFAULT_HOUR; tempMin = 0; nextState = alarmState; } break; case clockState: case setClockHourState: if (index == 2) { // not complete inputs tempHour = DEFAULT_HOUR; tempMin = 0; nextState = defaultState; } else if (index == 3) { tempHour = DEFAULT_HOUR; tempMin = 0; nextState = clockState; } break; case setAlarmMinState: if (index == 2) { alarmHour = tempHour; alarmMin = tempMin; nextState = defaultState; } else if (index == 3) { tempHour = DEFAULT_HOUR; tempMin = 0; nextState = alarmState; } break; case setClockMinState: if (index == 2) { // DateTime(YYYY, M, D, h, m, s) rtc.adjust(DateTime(2000, 1, 1, tempHour, tempMin, 0)); nextState = defaultState; } else if (index == 3) { tempHour = DEFAULT_HOUR; tempMin = 0; nextState = clockState; } break; default: nextState = currState; break; } } } } // Taps: Hours, Tens place of Mins, Ones place of Mins // Ex. 9:47 is 9 taps, 4 taps, 7 taps void solenoidTapping (int timeHour, int timeMinute) { for (int i = 0; i < timeHour; i++) { digitalWrite(SOLEPIN, HIGH); delay(50); digitalWrite(SOLEPIN, LOW); delay(450); } delay(2000); int minuteTens = timeMinute / 10; int minuteOnes = timeMinute % 10; for (int i = 0; i < minuteTens; i++) { digitalWrite(SOLEPIN, HIGH); delay(50); digitalWrite(SOLEPIN, LOW); delay(450); } delay(2000); for (int i = 0; i < minuteOnes; i++) { digitalWrite(SOLEPIN, HIGH); delay(50); digitalWrite(SOLEPIN, LOW); delay(450); } delay(2000); // a quick TAP-TAP to signal done tapping digitalWrite(SOLEPIN, HIGH); delay(50); digitalWrite(SOLEPIN, LOW); delay(100); digitalWrite(SOLEPIN, HIGH); delay(50); digitalWrite(SOLEPIN, LOW); delay(100); } // converts hours from 24-hour format to 12-hour format int convert12Hour(int timeHour) { // later half of day if (timeHour > 12) return timeHour - 12; // midnight else if (timeHour == 0) return 12; else return timeHour; }
]]>
For the final project in Physical Computing, we have formed a team of three (Team I/O) in order to create an accessible device for someone with physical disabilities. Our end goal is to create something that is useful and relevant for our client, something driven by her specific wants or needs so she can take home a device unique to her. Our client is Alycia, a blind woman who is also hard of hearing. The purpose of this meeting was threefold: to get to know her and introduce ourselves further, to get to know her wants that would make her life easier, and to get to know her needs – the immediate things that need to be addressed in her life. Present at the meeting was Alycia, Noni, Catherine, and David. It was held over zoom on Monday, March 21st at 10:30am.
Our Meeting Agenda
The meeting agenda was intentionally loosely structured. We wanted to allow room to run in whichever direction we were taken, while also being able to hear enough of Alycia’s needs and wants to ideate a device that addresses them. Here is what we initially planned:
Meeting Summary and Major Takeaways
We started off the meeting by asking Alycia why she chose to take part in this project, to which she said that she wanted to connect with more people and help raise disability awareness. She also mentioned that there are many products that claim to help people with disabilities, but without actually speaking with one and finding out what they need help with, these products oftentimes cause more harm than good.
We continued this conversation by asking Alycia if there are any activities in her current life that she finds difficult or frustrating. This led to one of our main ideas: a braille-friendly alarm clock. Alycia explained that her current alarm clock is an analog one that connects to a bed shaker. However, it is hard to set the alarm time accurately as she has to feel for the hands’ position while adjusting the clock so it is hard to set the exact time she needs. This often leads to her alarm going off five minutes before she actually wants to wake up. She has also tried talking clocks, but because she is hard of hearing, those don’t work well for her either. Alycia also showed us what her alarm clocks looked like, which we took screenshots of through zoom.
Through this, we found that Alycia is a very diligent person who keeps to a strict schedule. Whenever her alarm rings, she gets up immediately and carries out her day, which is why having a well-working alarm clock is very important to her. She also told us she wakes up at 5:30 am every day and we were curious why she did that, so we asked if she could describe what she does in a day. As she was describing her day, she started talking about how she spends a lot of time figuring out how to find directions to her microwave meals.
Because of her debilitating eyesight, she can’t see the box directions and relies on an app to scan the packaging for cooking directions and read it out for her. The app she uses to scan for directions is called Seeing AI, developed by Microsoft. The app is constantly improving and new features are being added, which is very helpful for Alycia Even so, it’s hard for her to position the phone correctly so that the app can see the directions, and she doesn’t know which side the directions are on so she has to continuously rotate the box.
Apart from these two main frustrations, she says that she is able to do most things well and doesn’t need too much help. She spends her days going to class, watching hockey games, playing dice world, and taking care of her cats. There are also many new developing technologies like seeing AI that she finds which greatly help her through her daily activities.
Post-Meeting Thoughts and Reflection
In general, the meeting went very well. We managed to get some good ideas to work with, which was the main goal we had when we entered the interview. Alycia provided us with a clear problem she had right off the bat, allowing us a good starting point, albeit skipping through the initial process of finding what her general life was like and “base scoping” ideas. That being said, it was a bit difficult to get off this initial path once we were on it, and there was a bit of concern that, should this initial idea not work, that we would not have anything to work with. Thus, we tried generalizing the topic more to break away from going down one idea too quickly; we went back to our initial agenda of finding what her life was like, and what she typically did. This allowed us to investigate and find other ideas, like the issue with scanning and packaging. As such, our ideation process went better, though still with concerns that we walked away with only two directions. Further discussion afterwards revealed that we should have asked more about certain details, such as the specifications of the bed shaker, or more about her life in general. This would allow us to explore other ideas to these problems, like wearables as an alternative alarm clock, or entirely different directions, such as something involving her cat or other aspects of her life.
]]>Overall image
servo latch detail
I made some initial ideation sketches based on problems I had daily. (include sketches) I settled on creating a prize box for myself since I often found myself lacking the motivation to finish tasks, eat well, or exercise. I was also inspired by some projects from previous years where they used a combination of switches and LEDs to create tactile and visual interaction. The initial idea was to create a box-shaped device with switches and LEDs. Each switch represented something I had to do and as each switch gets flipped to signify completing a task, the corresponding LED will light up. Once all the switches are flipped, a servo motor would rotate to open a lid to reveal a prize I left for myself beforehand (so I’m rewarding myself).
Initial idea sketches
Since I had quite a lot of individual components (5 switches, 5 LEDs, and a servo motor), I wanted to make sure there were enough plugs on my Arduino by first wiring everything in draw.io. I also had experience working with these components before so I was able to get the wiring and code done relatively quickly. However, I had significant difficulty with the physical fabrication of my device.
For my prototype, I used cardboard to make a box with the LEDs and switches in their own rows. But I was having trouble figuring out how to place the servo so that it could open the lid vertically. Instead, I could only position the motor to rotate the lid horizontally. So during the prototype crit, someone suggested: “I think that you can open it vertically by placing the servo motor parallel to the ground. It would be the servo rotate vertically”. I thought that was a good idea so I incorporated that into my design with the motor in the back of the box moving like a hinge to open the door
Since I had most of my wiring and code working by prototype crit, I wanted to challenge myself a little more. For the few days prior, I had been forgetting to bring things like my ID, AirPods, and water bottle with me in the morning. So I changed my concept to be a device that reminds me to check that I have all my things before I leave my house. Using the same base, I added 2 additional components: an ultrasonic ranger and buzzer. The device will therefore be mounted on my door so when I pass it in the morning it will beep and remind me to check it. Each switch corresponds to an item I need to bring, which I will flip if I have it in my bag. Instead of it being a prize, it will instead be my ID that will drop down. Once I have my ID, I can leave my house.
Updated idea sketch
wiring of all the components
After adding the additional components, I started 3D modeling my device in Solidworks to 3D print, making sure to leave holes in some areas to panel-mount the different electronic components. But after talking to Zach, I realized 3D printing takes a long time and some holes on my box faces may ruin the dimensions needed to fit edges together and fit switches through. So I laser-cut pieces instead for a finger-joint box and welded them together.
soldering switch wires
initial 3D model for 3D print
Lasercut pieces
plastic welding pieces together
After I finished putting together the box, I had a problem with the servo again where the arm wasn’t long enough to fully support the lid and couldn’t hold it in place against gravity.
Instead of working against gravity, I thought to work with it and changed the servo position so instead of acting as a hinge to open the bottom door, it is more of a latch. When the arm rotates away, the lid naturally falls open so the ID can drop down.
During the final crit, I got a couple feedback points on how to improve my device. Someone said “If you wanted to go further, you could maybe add a motor to open/close the door, and not just rely on gravity” which was my original goal and is something I’d still like to achieve. I think I will need a more secure and longer arm to support the lid. The guest critiquer also said that the motor makes the device look slightly unfinished and suggested using magnets that work only when electricity is running through it to lock and unlock the lid. I also think this is a viable idea and probably something I would have tried too if I had more time. Someone else also pointed out “The gravity might lead the key to drop to the ground; is it possible to place a basket below the machine to avoid the key from going all the way down?” This is something I actually forgot to consider and I think is a great suggestion. I will probably make another tray to be mounted below the device that will catch the ID if it misses the user’s hand.
Overall, I’m quite happy with my project since it is pretty similar to my concept and it works well too. While I think the aesthetic design can be improved slightly, such as making it less box-shaped and making it smaller, I’m proud of what I was able to make with my minimal Arduino skills. It was also an exciting process since I’ve never designed and made something with electronics before even though it was something I’ve always wanted to try and incorporate into my work as a design student. Compared to the previous project where my partner and I struggled with coding the parts to make them work together, I was surprised that the wiring and coding were relatively straightforward for me and how well the components were working. I’d like to think it shows some improvement between the 2 projects and how I’ve learned from my mistakes before.
However, I was still slightly disappointed in the physical aspect of it since I had more details in mind but I couldn’t incorporate with the material and form. If I had more time, I would have probably prototyped more and experimented with different materials. I’d also try changing it from being too box-shaped and looking at possibilities for softer edges and possibly rounded designs. For that, I’d also try 3D printing my device to achieve those details. While not everything went according to plan, I think I responded well and was flexible with changing my idea as needed, and still made a project I can proudly present.
/* "Don't Forget Your Things!" * * Catherine Liu * * This code is for a device that reminds you to take your things with you in the morning. Each switch is * wired to an LED and a servo motor rotates when all switches are flipped * * Pin Mapping: * pin | mode | description * ----|--------|------------- * 2 . output . servo motor * 3 . output . LED 1 * 4 . output . LED 2 * 5 . output . LED 3 * 6 . output . LED 4 * 7 . input . ultrasonic ranger trigger pin * 8 . input . switch 1 * 9 . input . switch 2 * 10 . input . switch 3 * 11 . input . switch 4 * 12 . input . ultrasonic ranger echo pin * 13 . output . buzzer * re * Code Used: * Robert Zacharias: Displaying data on an I²C LCD screen (https://courses.ideate.cmu.edu/60-223/s2022/tutorials/I2C-lcd) */ #include <NewPing.h> #include <Servo.h> #include <LiquidCrystal_I2C.h> //LCD Display Module library LiquidCrystal_I2C screen(0x27, 16, 2); //initiate screen //LED pins const int LEDPIN1 = 3; const int LEDPIN2 = 4; const int LEDPIN3 = 5; const int LEDPIN4 = 6; //switch pins const int SWITCHPIN1 = 8; const int SWITCHPIN2 = 9; const int SWITCHPIN3 = 10; const int SWITCHPIN4 = 11; int switchCount = 0; // //buzzer pin const int BUZZERPIN = 13; bool buzzerSound = false; int buzzerCount = 0; //servo pin Servo lidMotor; const int MOTORPIN = 2; //distance sensor pin #define TRIGGERPIN 7 #define ECHOPIN 12 #define MAXDISTANCE 200 NewPing sonar(TRIGGERPIN, ECHOPIN, MAXDISTANCE); // NewPing setup of pins and maximum distance. //boolean for resetting the device bool switchReset = false; void setup() { Serial.begin(115200); pinMode(LEDPIN1, OUTPUT); pinMode(LEDPIN2, OUTPUT); pinMode(LEDPIN3, OUTPUT); pinMode(LEDPIN4, OUTPUT); pinMode(SWITCHPIN1, INPUT); pinMode(SWITCHPIN2, INPUT); pinMode(SWITCHPIN3, INPUT); pinMode(SWITCHPIN4, INPUT); pinMode(BUZZERPIN, OUTPUT); lidMotor.attach(MOTORPIN); lidMotor.write(5); screen.init(); screen.backlight(); screen.home(); screen.print("Hi!Make sure you"); screen.setCursor(0,1); screen.print("have everything"); } void loop() { int buttonState1; int buttonState2; int buttonState3; int buttonState4; buttonState1 = digitalRead(SWITCHPIN1); buttonState2 = digitalRead(SWITCHPIN2); buttonState3 = digitalRead(SWITCHPIN3); buttonState4 = digitalRead(SWITCHPIN4); //checking distance delay(50); int distVal = sonar.ping_cm(); Serial.println(distVal); //buzzer sounds 3 times max if object is detected if ((distVal < 30) && (buzzerSound == false)) { digitalWrite(BUZZERPIN, HIGH); delay(100); digitalWrite(BUZZERPIN, LOW); buzzerCount = buzzerCount + 1; } if (buzzerCount == 3) { buzzerSound = true; } //switch 1 if (buttonState1 == LOW) { switchCount = switchCount + 1; digitalWrite(LEDPIN1, HIGH); } if (buttonState1 == HIGH) { digitalWrite(LEDPIN1, LOW); } //switch 2 if (buttonState2 == LOW) { digitalWrite(LEDPIN2, HIGH); } if (buttonState2 == HIGH) { digitalWrite(LEDPIN2, LOW); } //switch 3 if (buttonState3 == LOW) { digitalWrite(LEDPIN3, HIGH); } if (buttonState3 == HIGH) { digitalWrite(LEDPIN3, LOW); } //switch 4 if (buttonState4 == LOW) { digitalWrite(LEDPIN4, HIGH); } if (buttonState4 == HIGH) { digitalWrite(LEDPIN4, LOW); } //rotate motor, and change LCD text after all switches are flipped if ((buttonState1 == LOW) && (buttonState2 == LOW) && (buttonState3 == LOW) && (buttonState4 == LOW)) { screen.clear(); screen.home(); screen.print("Goodbye!"); lidMotor.write(170); switchReset = true; } //motor returns to relatch lid else { lidMotor.write(70); } //reset buzzer when switches are flipped back if ((buttonState1 == HIGH) && (buttonState2 == HIGH) && (buttonState3 == HIGH) && (buttonState4 == HIGH) && (switchReset == true)) { screen.home(); screen.print("Hi!Make sure you"); screen.setCursor(0,1); screen.print("have everything"); buzzerSound = false; switchReset = false; buzzerCount = 0; } }]]>