A device to help lock away your phone for a specified amount of time so you can focus on tasks at hand.
Process Images and Review
Discussion
The in-class critiques that I got were mostly just positive attributes that classmates appreciated about the design. It didn’t really give me much to move forward with, but it was good to have my design decisions validated. One person commented, “I thought the name was very cool and I liked the use of a tactile button to control the timer.” I really liked the idea of the project and what I was making so I put a lot of time into designing based on what I would like to use. I’ve always wanted an “inator” so it seemed like a perfect time to create something like that… thus the name. Another person commented “It looks like a lot of the components of your project are working really well together. I also like the LED use”. When conceptualizing this assignment, I wanted to create something simple enough that I could do everything I needed to do within the ~two week span we were allocated. Thus, all of the components of my project – the LED strip, the LCD screen and timer, the self-destruct button… It was all in an effort to finish the project on time and create something I’d want to use. So I appreciated this comment because I sought to be very intentional.
This project was unexpectedly challenging. I anticipated a walk in the park on a day with old snow (fumbling/tripping on dirty snow, a bit of slipping on ice – but ultimately being fine), but instead my casual walk included me getting wrapped up in a tornado and spit out at the end of the park. Thus, all of the components (LED strip, buttons/dials, etc.) came together somewhat easily and overall didn’t take more time than anticipated… but the timer was the tornado. I didn’t expect the logic and coding of it to be some math-heavy and difficult. I worked an entire weekend without getting anywhere, and restarted the code from scratch twice to make it work. In retrospect, I would tell myself to not overthink the logic and to go down the math route rather than scenario planning for each individual component of the timer (hour, min, sec). I also wish I hadn’t gotten too hung up on the timer – I think it would have benefitted me more to move onto the actual box/laser cutting while I waited and tried to debug the timer. However once the timer was completed, all the other components came together within two days and there were no more major storms on my walk.
Overall, I’d say I’m very proud of this project. It satisfied all of my goals and created a project that I honestly intend to use for years to come. In fact, I’d say I satisfied my goals almost to a fault. After seeing other people’s projects – I realized I could have gone even further. For example, I have a lamp that has 3 slots for USB’s, so I didn’t include a battery pack or an on/off button on the Nay-Phone Inator, instead I just left it for a USB input because that is what fit my specific needs. Also things like what happens after the self destruct button is pushed. The idea was that after the self-destruct button and phone retrieval, you simply unplug the USB (because why would the device need to be on if you had given up?), but in the final critique some people seemed surprised that there was no way to return to the Set Timer screen after the phone was retrieved. So I think small things like that would actually be my Next Steps. I don’t plan to build another iteration of the project, but if I did – I would address those small details.
Technical Information
/* Nay Phone Inator - Project 2 Noni Shelton Code for a device that locks away your phone for a specified amount of time so you can focus on tasks at hand. Credit to Professor Zach Credit to the creators of the libraries I used */ /* PIN MAPPING pin | mode | description ------|--------|------------ 2 input Rotary Encoder - hour 3 input Rotary Encoder - hour 4 input The lock (the Servo motor) 5 input The "Set" button 13 input The "self destruct" button 9 input Rotary Encoder - minute 10 input Rotary Encoder - minute */ #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <Encoder.h> #include <PololuLedStrip.h> #include <Servo.h> Servo lockMotor; const int SELF_DESTRUCT_BUTTON_PIN = 13; const int SET_BUTTON_PIN = 5; const int LOCKMOTORPIN = 4; unsigned long lcdTimer = 0; unsigned long ledStripTimerSinglecolor = 0; PololuLedStrip<6> ledStrip; // LED STRIP: Create a buffer for holding the colors (3 bytes per color). #define LED_COUNT 60 rgb_color colors[LED_COUNT]; int totalTimerSeconds = 0; int selfDestructButtonState = 0; int destructTimer = 0; bool timerCounting = true; bool countdownMode = false; bool doorLocked = false; bool endScreenPrintSequence = false; bool destructPassed = false; LiquidCrystal_I2C screen(0x27, 16, 2); Encoder knobHour(2, 3); Encoder knobMinute(9, 10); void setup() { // put your setup code here, to run once: Serial.begin(9600); #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // END of Trinket-specific code. //initalizing pins pinMode(SELF_DESTRUCT_BUTTON_PIN, INPUT); lockMotor.attach(LOCKMOTORPIN); //inital timer Serial.begin(9600); screen.init(); screen.backlight(); screen.home(); screen.clear(); //intro screen screen.print("Nay-Phone Inator"); delay(2000); screen.clear(); //set timer screen.home(); screen.print("Set Timer"); screen.setCursor(5, 1); screen.print("00hr:00min"); } void loop() { //setting up the rotary encoders int setTimerHour, setTimerMin; setTimerHour = knobHour.read() / 4; setTimerMin = knobMinute.read() / 4; //hour rotary encoder goes to 12 and loops around if (setTimerHour < 0) setTimerHour = 10; else if (setTimerHour > 10) setTimerHour = 0; //min rotary encoder goes to 12 and loops around if (setTimerMin < 0) setTimerMin = 60; else if (setTimerMin > 59) setTimerMin = 0; //bool sure set timer only prints once if (endScreenPrintSequence == false) { //printing the "Set Timer" changing values if (millis() - lcdTimer >= 250) { screen.clear(); screen.home(); screen.print("Set Timer"); screen.setCursor(5, 1); screen.print("00hr:00min"); //setting hours if (setTimerHour < 10) screen.setCursor(6, 1); else screen.setCursor(5, 1); screen.print(setTimerHour); //setting mins if (setTimerMin < 10) screen.setCursor(11, 1); else screen.setCursor(10, 1); screen.print(setTimerMin); lcdTimer = millis(); } } //LED STRIP: making the LED Strip Flash a rainbow if it's in SetTimer Mode if (countdownMode == false) { //timer updates every 1/4th of a second if (millis() - lcdTimer >= 250) { // Update the colors. uint16_t time = millis() >> 2; for (uint16_t i = 0; i < LED_COUNT; i++) { byte x = (time >> 2) - (i << 3); colors[i] = hsvToRgb((uint32_t)x * 359 / 256, 255, 255); } // Write the colors to the LED strip. ledStrip.write(colors, LED_COUNT); } } //set button pressed -- i.e. moving on to the countdown timer if (digitalRead(SET_BUTTON_PIN) == HIGH) countdownMode = true; if (countdownMode) { //updates every 1 second if (millis() - lcdTimer >= 100) { screen.clear(); screen.home(); screen.print("Timer"); screen.setCursor(4, 1); screen.print("00:00:00"); lcdTimer = millis(); if (timerCounting) { totalTimerSeconds = ((setTimerHour * 3600) + (setTimerMin * 60)); timerCounting = false; } //every second, the hours/mins/seconds are updated totalTimerSeconds--; //updates seconds int seconds = totalTimerSeconds; //updates hours int hourUpdate = seconds / 3600; seconds = seconds - (hourUpdate * 3600); //updates minutes int minUpdate = seconds / 60; seconds = seconds - (minUpdate * 60); if (totalTimerSeconds >= 0) { //servo motor: locking the door -- lockMotor.write(5); //led strip turns red for (uint16_t i = 0; i < LED_COUNT; i++) { colors[i] = rgb_color(255, 0, 0); } //Updating the timer on the LCD Screen //printing the seconds screen.setCursor(10, 1); if (seconds < 10) screen.setCursor(11, 1); else screen.setCursor(10, 1); screen.print(seconds); //printing the mins if (minUpdate < 10) screen.setCursor(8, 1); else screen.setCursor(7, 1); screen.print(minUpdate); //printing the hours if (hourUpdate < 10) screen.setCursor(5, 1); else screen.setCursor(4, 1); screen.print(hourUpdate); //SELF DESTRUCT MODE selfDestructButtonState = digitalRead(SELF_DESTRUCT_BUTTON_PIN); if (selfDestructButtonState == HIGH) { //setting a destruct countdown destructTimer++; //making sure the screen prints the proper thing endScreenPrintSequence = true; if (destructTimer < 10) { //destruct timer displays warning screen.clear(); screen.print("Hold for 10 secs"); screen.setCursor(0, 1); screen.print("to give up"); delay(1000); } else { //passing the destruct bool destructPassed = true; } } if (destructPassed) { //destruct timer displays disappointment screen.clear(); screen.print("Dang. That was"); screen.setCursor(0, 1); screen.print("disappointing."); delay(1000); //servo motor: unlock the door lockMotor.write(90); delay(1000); } } else { //TIMER HAS BEEN ENDED //making sure the screen prints the proper thing endScreenPrintSequence = true; screen.clear(); screen.home(); screen.print("Amazing job! You"); screen.setCursor(0, 1); screen.print("rock homie"); //servo motor: unlock the door lockMotor.write(90); delay(1000); //LED STRIP: updating the LED strip with congratulatory colors // Update the colors. byte time = millis() >> 2; for (uint16_t i = 0; i < LED_COUNT; i++) { byte x = time - 8 * i; colors[i] = rgb_color(x, 255 - x, x); } } // Write the colors to the LED strip. ledStrip.write(colors, LED_COUNT); } } } // THE FUNCTIONS I'M USING // Converts a color from HSV to RGB. // h is hue, as a number between 0 and 360. // s is the saturation, as a number between 0 and 255. // v is the value, as a number between 0 and 255. rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v) { uint8_t f = (h % 60) * 255 / 60; uint8_t p = (255 - s) * (uint16_t)v / 255; uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255; uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255; uint8_t r = 0, g = 0, b = 0; switch ((h / 60) % 6) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; } return rgb_color(r, g, b); }