jianingl@andrew.cmu.edu – Intro to Physical Computing: Student Work Spring 2022 https://courses.ideate.cmu.edu/60-223/s2022/work Intro to Physical Computing: Student Work Sat, 07 May 2022 20:16:45 +0000 en-US hourly 1 https://wordpress.org/?v=5.8.9 Braille Alarm Clock by Team I/O: Final Documentation https://courses.ideate.cmu.edu/60-223/s2022/work/braille-alarm-clock-by-team-i-o-final-documentation/ Sat, 07 May 2022 20:16:45 +0000 https://courses.ideate.cmu.edu/60-223/s2022/work/?p=15816 The goal of the project was to design an assistive device for someone else. We were to get to know our client and understand where in their life they could benefit from something that we could create. We then kept in contact with them throughout the building process to make sure we were making something that addressed their goals. The notes and insights from the interview can be found here.

What We Built

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.

On the table sits 3 objects. On the left is a black disc-shaped bed shaker, in the middle is our final clock device, and on the right is Alycia's original alarm clock

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)

Narrative Sketch

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.

How We Got Here (Prototype and Process)

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?

Prototype

On a whiteboard table are drawings in yellow, green, and red, depicting different ideas for our clock

First meeting discussion possible ideas

In the center of the image are red marker drawings depicting different clock ideas, around it are 2 closed laptops and 3 markers strewn on the table

Second meeting discussing clock ideas

Drawn on a whiteball table with yellow marker are sketches of different clock interfaces

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.

 On the table are our three prototype interfaces made of chipboard. Alycia is sitting on the left of the table while Noni and David sit on the right

Showing Alycia the prototypes on prototype day

We have 3 different prototypes on the table. The leftmost prototype is based on a rotatry dial clock, the middle is made of buttons arranged in a circle, and the rightmost prototype is based on a slider mechanism

Our 3 prototype interfaces

Seated around a table are 4 people. On the right is Alycia, a middle-aged woman with long hair. On the left are 3 students, David, Noni, and Catherine who are handing Alycia chipboard cutouts to try as clock interfaces

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.

Process

There are 2 laptops open on a table and in front of them are marker drawings and writings about different clock ideas. Some buttons, wires, and chipboard are also next to the writings

Deciding on how to improve prototype after showing to Alycia

There is a rectangular board cut out of white acrylic with a flower cut out of the same acrylic on the center of it. There are 2 red buttons on the left of the rectangle and 2 green buttons on the right. In the center of the flower is a ring of 12 small red buttons

Final interface design for the clock

On the left is a piece of plywood with parts cut out of it. The parts were used to make a finger joint box that is on the right of the plywood

Lasercut plywood to build clock

 

There is a blob of coral-pink paint mixed on top of a clear acylic lid. Behind the paint are blank planks of plywood

Painting the plywood

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.

On top of a table sits a big piece of cardboard. On top of the cardboard are wires connecting buttons and switches to the clock interfcae we prototyped with white acrylic

All wiring of the clock

All wires, buttons, and breadboards are placed into pieces of plywood that are attached together with tape

Putting all components into the fingerjoint base

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.

Conclusions and Lessons Learned 

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.

Technical Details

Schematic and Block Diagram

Code

/* 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;
}

 

]]>
Interview Documentation: Team I/O https://courses.ideate.cmu.edu/60-223/s2022/work/interview-documentation-team-i-o/ Sun, 27 Mar 2022 20:53:14 +0000 https://courses.ideate.cmu.edu/60-223/s2022/work/?p=15735 A Brief Introduction

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:

  1. Introductions and icebreaker [everyone answers questions] (5-10mins)
    1. Introduce yourself
    2. Tell us a fun fact 
  2. Entering conversation [client answers] (30-40mins)
    1. Why did you volunteer for this project? What was of interest to you?
    2. Do you have any activities in your daily life that are difficult, frustrating, or otherwise seem like they could use an intervention?
    3. What are some activities that you enjoy doing?
    4. What are the main challenges you face that you would want to be addressed?
    5. If you could have anything to improve your daily experience, what would it be?
    6. What’s your daily schedule?
  3. Conclusion (2 mins)
    1. Thanking Alycia for her time 
    2. Do you have any questions for us? Or last minute thoughts/things to add?

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.

Alycia’s analog alarm clock with two plugs connected to the bed shaker and power source

Example of bed shaker Alycia uses that vibrates when the alarm goes off

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.

]]>
“Don’t Forget Your Things!” https://courses.ideate.cmu.edu/60-223/s2022/work/dont-forget-your-things/ Wed, 16 Mar 2022 06:19:54 +0000 https://courses.ideate.cmu.edu/60-223/s2022/work/?p=15474 This device reminds me to bring my things with me in the morning. If I have everything listed with me, a latch opens and my ID falls out into a tray, allowing me to leave my house.

Overall image

 

panel mount detail

servo latch detail

LED detail

Flipping the switches

Lid opens and you get your ID

Putting ID back into device and resetting it

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.

Block diagram

schematic diagram

/* "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;
  }
}
]]>