This device works to hold my phone while I am studying or doing work, preventing me from distracting myself by using my phone while I should be focusing on the task at hand.
Overall Photo
Detail Photos
Usage Photos
Process and Review
During this project, I had to make many decisions that significantly changed the outcome of my design and project as a whole.
One challenge I ran into early was that my phone did not activate the pressure sensor. My whole idea thus far had relied on the phone activating the pressure sensor, and this realization frustrated me early on. With some testing, I knew that the pressure sensor did work when I used my finger to apply pressure, just not when my phone rested on top of it.
As a result, I concluded that the pressure applied needed to be concentrated. Since my phone is wider than the sensor, the weight of the phone was too distributed to impact the resistance in the FSR.
To solve this problem, I created the following 3D printed part to hold up a wide body, and concentrate its weight in a smaller location:
Since the phone still could not rest solely on this part, I had to attach it to the piece of wood that would act as the casing for the phone. In order to prevent the assembly from falling over, I used springs in each of the four corners for stability. This worked well to hold up the corners and allow for slight vertical displacement when the phone applies pressure to the assembly, which then applies pressure to the FSR sensor, activating my device.
Another challenge I ran into during the design process was what to do with the door that covered my phone during work time. Since I cut the entire box out of wood, the axels that the door hinges on are actually rectangular. To make them fit in the holes of the hinge, I had to sand the corners of the rectangular cut out until they allowed the door to open and close smoothly. I am proud of this work around, as it allowed me quickly adapt my prior work with out the use of additional materials or design components.
I knew I wanted to have some visibility so that the user could identify if a notification was an emergency that needed a response. However, with the door there, there was nothing discouraging the user from just opening the door to use their phone while still activating the pressure sensor. To combat this, I wanted to somehow sense if the door was closed or not to punish the user when the door was open for too long by ringing the alarm that sounds when the phone is removed from the device.
I felt that this discouragement was sufficient enough for me, as the buzzer used makes a really loud sound at a pitch I am fairly sensitive to. I will defiantly be motivated to close the door as soon as it starts going off.
I wrestled with a few ideas on how to sense if the door was closed or not. I ended up using a photoresistor to detect a change in light brightness when the door closes. The photoresistor would stick out on the top of the box, next to the phone as shown below. This way it is covered when the door is closed and is un-intrusive to the user.
To wire and attach the photoresistor to the top of my box, I soldered it to a protoboard, along with the rest of the wiring needed to power the photoresistor.
Despite my efforts, the photoresistor value of the door being closed was inconsistent in different lighting environments since the door was not completely flush with the top of my box. To combat this, I glued some scrap wood on the edge of the door until it was flush with the top of my box, over the photoresistor. I also placed black electrical tape on the surface of the scrap wood to further darken the area the photoresistor sensed when closed. This solution worked well and made the values produced by the photoresistor much more consistent despite the brightness of the room.
Additional Process Pictures
While I knew that soldering all of the electrical components would make better connections, I ended up doing so sparingly. While all wiring for the FSR sensor and the photoresistor are soldered in the final product, I determined it was unnecessary to solder the potentiometers and the buzzer. Since I am a novice at soldering, I did not want to risk damaging the potentiometers during that process, a consequence that can occur if done without precision. Also, the breadboard provided a great base that helped control the height of the potentiometer, which helped when designing the box to encase them in. Since the box only sits on my desk and the wires are not intended be thrown around, I deemed it less important to solder each component, and used that time to improve the ergonomics and sleek design of my device.
Discussion
When presenting my project to the class, I received some great critiques and feedback. One piece of feedback I received was that I should have had the buzzer quickly go off to alarm the user that they have transitioned into the break time from the work time. This is a great idea and something that I had originally thought of during the prototyping phase. However, I ended up forgetting to incorporate the idea, and it completely slipped my mind until I was given feedback. Additionally, it was suggested that I added an emergency stop to my device, so that it would not alarm when I discontinued use in the event of an emergency. While I also considered this, I decided that if there was a true emergency, I could just unplug the device from my computer. I know that I would not abuse this power, as it defeats the whole purpose of what I am trying to do. If my phone is in my assistive device, it will remind me of my goal to keep working until the break. Despite these minor shortcomings, I am proud of the project that I created. Not having a partner who knew electronics left me responsible for figuring out the unknown by myself and challenged me to learn and grow as an engineer. I exceeded my personal expectations and I believe that I delivered a complete and robust project. I learned so much during this project, including a better understanding of electrical components, soldering, simple algorithms and how they are integrated with mechanical design. The project challenged me to think about problems using different perspectives and challenged me to solve those problems in a creative and elegant way. While it is safe to say that this will be the final version of my device for now, there are a few modifications that I could make to clean up the user experience. For example, the buzzer indicating the transitions as mentioned above. I would also like to add a button that takes the user back to the home screen to let them set new work and break time durations without having to unplug the device. These additions would be nice, but are not significant enough to require iteration in order to use the device. It works well for me and my need!
Block Diagram
Electrical Schematic
Code
/* Study Time Phone Jail By Matthew Wagner 60-223 Introduction to Physical Computing Professor Robert Zacharias Due 11/2/2021 This project helps someone stay focused when studying by trapping their phone in the 'Jail', preventing use. The user can set how long they want to work and take a break for. While working, if the phone is removed, or the door cover is opened for too long, the device alarms the user to return to their task and put the phone back. The user gets a set break time after each work time. Pin mapping: Arduino pin | role | description ------------|--------|------------- A0 input potentiometer (Sets Work Time) A1 input potentiometer (Sets Break Time) A2 input FSR Pressure Sensor (Square) A3 input photoresistor 13 output active buzzer SDA output LCD Screan (modified) SCL output LCD Screen (modified) I^2C LCD: Modified code from Robert Zacharias Used Library by Frank de Brabender, based on work from DFRobo (Nov. 2018) millis: Modified code from Robert Zacharias */ ///////////////////////////// // LIBRARIES // ///////////////////////////// #include <Wire.h> #include <LiquidCrystal_I2C.h> // create LCD Display called "screen" LiquidCrystal_I2C screen(0x27, 16, 2); byte frowny[] = { B00000, B11011, B11011, B00000, B00000, B01110, B10001, B00000 }; // track time passed using: millis() const unsigned long DISPUPDATETIME = 500; unsigned long lastUpdate = millis(); // FSR const int FSRPIN = 2; int fsrReading; // photoresistor const int PHOTOPIN = 3; int photoVal; // active buzzer const int BUZZERPIN = 13; int screenPeekTime = 0; // User interface initial values/ settings: int workTime = 45; int breakTime = 5; int seconds = 0; bool phoneSensed = false; bool working = false; bool onBreak = false; bool buzzerOn = false; bool screenCoverClosed = false; void setup() { // work time potentiometer pinMode(A0, INPUT); // break time potentiometer pinMode(A1, INPUT); // buzzer pinMode(BUZZERPIN, OUTPUT); digitalWrite(BUZZERPIN, LOW); // photoresistor pinMode(PHOTOPIN, INPUT); // initialize the screen (only need to do this once) screen.init(); // turn on the backlight to start screen.backlight(); // set cursor to home position, i.e. the upper left corner screen.home(); } void loop() { // let user set work and break time before starting work if (!working && !onBreak){ // read potentiometer value, map to work time workTime = map(analogRead(A0), 0, 1023, 6, 36); // multiply by 5 to only display 5 minute increments between // 30 mins and 3 hrs workTime = 5 * workTime; // read potentiometer value, map to break time breakTime = map(analogRead(A1), 0, 1023, 1, 6); // multiply by 5 to only display 5 minute increments between // 5 and 30 mins breakTime = 5 * breakTime; if (millis() - lastUpdate >= DISPUPDATETIME){ screen.clear(); // display work time screen.print("Work Time: "); screen.setCursor(11, 0); screen.print(workTime); screen.print("m"); // display break time screen.setCursor(0, 1); screen.print("Break Time: "); screen.setCursor(12, 1); screen.print(breakTime); screen.print("m"); screen.home(); lastUpdate = millis(); } } // keep a timer while working else if (working && !buzzerOn && millis() - lastUpdate >= 2 * DISPUPDATETIME){ screen.clear(); // display time screen.print("Time Until Break"); screen.setCursor(5, 1); screen.print(workTime); screen.print(":"); if (seconds < 10){ screen.print("0"); } screen.print(seconds); screen.home(); // update timer if (seconds == 0){ if (workTime == 0) { working = false; onBreak = true; } else{ workTime = workTime - 1; seconds = 59; } } else{ seconds = seconds - 1; } // check if user is peeking if (!screenCoverClosed){ screenPeekTime = screenPeekTime + 1; } lastUpdate = millis(); } // keep a timer while on break else if (onBreak && millis() - lastUpdate >= 2 * DISPUPDATETIME){ screen.clear(); // display time screen.print("On Break for:"); screen.setCursor(5, 1); screen.print(breakTime); screen.print(":"); if (seconds < 10){ screen.print("0"); } screen.print(seconds); screen.home(); // update timer if (seconds == 0){ if (breakTime == 0) { // back to work when break is over working = true; } else{ breakTime = breakTime - 1; seconds = 59; } } else{ seconds = seconds - 1; } lastUpdate = millis(); } // sensor fsrReading = analogRead(FSRPIN); if(fsrReading > 500){ phoneSensed = true; digitalWrite(BUZZERPIN, LOW); buzzerOn = false; if (!working && !onBreak){ working = true; onBreak = false; seconds = 0; } // reset work time and break time for next session after break else if (working && onBreak){ onBreak = false; // read potentiometer value, map to work time workTime = map(analogRead(A0), 0, 1023, 6, 36); // multiply by 5 to only display 5 minute increments between // 30 mins and 3 hrs workTime = workTime = 5 * workTime; // read potentiometer value, map to break time breakTime = map(analogRead(A1), 0, 1023, 1, 6); // multiply by 5 to only display 5 minute increments between // 5 and 30 mins breakTime = 5 * breakTime; } // buzz if user is peeking for too long else if (working && !screenCoverClosed && screenPeekTime >= 12){ digitalWrite(BUZZERPIN, HIGH); buzzerOn = true; if (millis() - lastUpdate >= DISPUPDATETIME){ screen.clear(); screen.print("CLOSE COVER NOW!"); screen.setCursor(0,1); screen.print("NO PEEKING!"); screen.home(); lastUpdate = millis(); } } } else{ phoneSensed = false; // buzz if break ends and phone isn't sensed if (working && onBreak){ digitalWrite(BUZZERPIN, HIGH); buzzerOn = true; if (millis() - lastUpdate >= DISPUPDATETIME){ screen.clear(); screen.print("BREAK IS OVER!"); screen.setCursor(0,1); screen.print("PUT PHONE BACK!"); screen.home(); lastUpdate = millis(); } } // buzz if phone isn't sensed while working else if (working && !onBreak){ digitalWrite(BUZZERPIN, HIGH); buzzerOn = true; if (millis() - lastUpdate >= DISPUPDATETIME){ screen.clear(); screen.print("NO!!! IT IS NOT"); screen.setCursor(0,1); screen.print("BREAK TIME YET"); screen.home(); lastUpdate = millis(); } } } // read photoresistor photoVal = analogRead(PHOTOPIN); if (photoVal <= 300){ screenCoverClosed = true; screenPeekTime = 0; digitalWrite(BUZZERPIN, LOW); buzzerOn = false; } else { screenCoverClosed = false; } }