Project 2 – Intro to Physical Computing: Student Work Spring 2023 https://courses.ideate.cmu.edu/60-223/s2023/work Intro to Physical Computing: Student Work Tue, 04 Apr 2023 18:45:30 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.6 Pill Alarm Clock https://courses.ideate.cmu.edu/60-223/s2023/work/pill-alarm-clock/ Tue, 04 Apr 2023 18:45:30 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=18101 This is an alarm clock that goes off a certain time each day and doesn’t stop until the pills on the top are removed from the red stripe.

Process Images and Review:

I decided to go from an automated refill process to refilling by hand.

I decided to make an individual moveable object rather than integrate it into my physical daily routine.

                                  

Response to Class Comments:

“I wonder if the housing could be smaller; feels like an unnecessarily large footprint for a few components”

A: I purposefully made the housing larger so that the object would call attention to itself, acting as another way to remind me that it was there and I need to take my medication.

“Maybe you could have like a weekly pill dispenser. Like pills are placed in different boxes and dispensed at alarm at each specific day, because an RTC module can also keep the date as well”

A: This was the original goal for this project and I think it’s a great idea. Unfortunately out of my skill set right now but it would be a much more productive invention than my finished product.

Self Critique:

I think that my biggest self-critique is that I could have gone further with the casing and the refill mechanism. I would have liked the casing to be more intentional in its shape and function and made of a more permanent material like wood or acrylic. My original plan was for a linear actuator to move the pills into the break beam sensor day by day as a sort of automated refill mechanism but my technical and coding skills just weren’t strong enough to make that happen for the final product.

What I Learned:

During this process, I learned that the break beam sensor is a surprisingly reliable component and I had the least amount of trouble with it as an input compared to my other inputs and outputs. I also learned that the debugging and trial and error process takes much longer than I planned for and is something that a lot of time needs to be allotted. 

Next Steps:

Going forward I would like to work to make my alarm clock more reliable than it is currently by working out the remaining code and technical bugs. I would also like to see if I can automate the day-by-day “refill” process by using my original concept with the linear actuator.

//Pill Alarm Clock
//Lily Hummel
//This code displays the time, day, and year on a LCD and sets off an alarm at a predetermined time of day.
//When the alarm goes off, it doesn't stop until the breakbeam sensor is unblocked.
//Credit to /https://www.circuitbasics.com/how-to-use-a-real-time-clock-module-with-the-arduino/ and Zach for writing portions of this code.
// YOLO LICENSE
                             //Version 1, July 10 2015

//THIS SOFTWARE LICENSE IS PROVIDED "ALL CAPS" SO THAT YOU KNOW IT IS SUPER
//SERIOUS AND YOU DON'T MESS AROUND WITH COPYRIGHT LAW BECAUSE YOU WILL GET IN
//TROUBLE HERE ARE SOME OTHER BUZZWORDS COMMONLY IN THESE THINGS WARRANTIES
//LIABILITY CONTRACT TORT LIABLE CLAIMS RESTRICTION MERCHANTABILITY SUBJECT TO
//THE FOLLOWING CONDITIONS:
//1. #yolo
//2. #swag
//3. #blazeit


#include <Wire.h>                   // for I2C communication
#include <LiquidCrystal_I2C.h>      // for LCD
#include <RTClib.h>                 // for RTC

LiquidCrystal_I2C lcd(0x27, 16, 2); // create LCD with I2C address 0x27, 16 characters per line, 2 lines
RTC_DS3231 rtc;                     // create rtc for the DS3231 RTC module, address is fixed at 0x68

/*
   function to update RTC time using user input
*/
#define BUZZPIN 9
#define SENSORPIN 4

bool Alarmtrigtoday = false;

bool Wasunblockedtoday = false;
  
// variables will change:
int sensorState = 0, lastState=0;         // variable for reading the pushbutton status

  
void updateLCD()
{

   // get time and date from RTC and save in variables
  DateTime rtcTime = rtc.now();

  

  int ss = rtcTime.second();
  int mm = rtcTime.minute();
  int hh = rtcTime.twelveHour();
  int DD = rtcTime.dayOfTheWeek();
  int dd = rtcTime.day();
  int MM = rtcTime.month();
  int yyyy = rtcTime.year();

  // move LCD cursor to upper-left position
  lcd.setCursor(0, 0);

  // print date in dd-MMM-yyyy format and day of week
  if (dd < 10) lcd.print("0");  // add preceeding '0' if number is less than 10
  lcd.print(MM);
  lcd.print("/");
  lcd.print(dd);
  lcd.print("/");
  lcd.print(yyyy);

  // move LCD cursor to lower-left position
  lcd.setCursor(0, 1);

  // print time in 12H format
  if (hh < 10) lcd.print("0");
  lcd.print(hh);
  lcd.print(':');

  if (mm < 10) lcd.print("0");
  lcd.print(mm);
 

  if (rtcTime.isPM()) lcd.print(" PM"); // print AM/PM indication
  else lcd.print(" AM");
}
void setup()
{      
  pinMode(BUZZPIN, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(SENSORPIN, INPUT);     
  digitalWrite(SENSORPIN, HIGH); // turn on the pullup
  
  Serial.begin(9600); // initialize serial

  lcd.init();       // initialize lcd
  lcd.backlight();  // switch-on lcd backlight

  rtc.begin();       // initialize rtc
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
void loop()
{
  DateTime rtcTime = rtc.now();


  if (rtcTime.second() == 0 && rtcTime.minute() == 14 && rtcTime.hour() == 12){
    tone(BUZZPIN, 200);
    Alarmtrigtoday = true;
    while (sensorState == LOW) { 
      sensorState = digitalRead(SENSORPIN);
    }
    noTone(BUZZPIN);
  }

  
 
  updateLCD();  // update LCD text

}

 

]]>
Good Morning Phone Jail https://courses.ideate.cmu.edu/60-223/s2023/work/good-morning-phone-jail/ Wed, 15 Mar 2023 13:38:13 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17919 An assistive device that prevents you from going on your phone in the morning by creating a loud buzzing noise when your phone is removed from its surface in the hour after your alarm goes off.

Moving Image

While the timer is on, removing the device will cause a buzzing noise to occur, and putting it back on makes the buzzing stop. At the end of the timer’s duration, the display shows “Timer complete!” and 3 beeps sound.

Overall Photo

An angled view of a box. There is a lower platform in the box, approximately the size of an iphone 11.

Overview of the device, with power off.

Detail Photos

A raised platform on a wooden box, with a hole cut out for a proximity sensor at the base, and a microphone at the end.

The top of my device: there’s a rectangle cutout at the top where my proximity sensor is placed. At the edge, I have another hole cut out to place the microphone directly facing the speaker of my phone, to pick up as much sound as possible. On this same side, there’s also a cutout for my charger to go into, so that I can charge my phone at night.

The back-facing view of a wooden box. There are two holes cutout, with a DC jack sticking out & connected to some wires.

The back-view of my device, where the power source can be plugged in. There’s a hole for a port to be connected to my laptop, so that I can upload any new Arduino code to adjust some parameters, as well as a DC jack.

Using the Device

A beige box with an indent at the top, and an LCD display at the front-facing view that reads "Time left: 0:0:6"

The device in use, with the timer in session and no phone.

A wooden box, with an LCD display at the front that reads "Time left: 0:0:12"

The device in use, with the phone (phone case used as substitute for sake of taking photo) present.

Process

Throughout the design and development of my project, there were a few key design decisions that had to be made. The first was the mechanism for detecting my phone’s presence. I originally was going to use a photo-resistor to detect the presence of my phone, but during my prototype presentation, some of my classmates pointed out that the photo-resistor may get incorrectly triggered by room darkness. This was especially a concern for me because my room is often quite dark in the mornings when I wake up before sunrise. A classmate recommended I use an Optical Proximity Sensor instead, so I decided to switch to that method instead.

A tangled bundle of wires hooked to an LCD monitor and photo-resistor

The first prototype of my device, with all of the wiring set up. This iteration features the photo-resistor as mechanism for detecting my phone’s presence, before switching it to an optical proximity sensor.

A series of soldered boards connected to an Arduino.

The second prototype of my device, with the photo-resistor switched out for a proximity sensor.

Another decision I made was to have the device be triggered by a microphone that can detect when my alarm goes off, rather than having an RPC module and setting a time for when the phone detection activates every morning. This made sense for my daily habits, as integrating it with when my alarm goes off most accurately ties in with my wake-up schedule, and also goes along with my regular routine of setting my alarm on my phone. If I wanted to set the timer on the device directly, I would probably have had to implement a full alarm system to make sure that the lock activates when I wake up. This would have been a lot of additional work for not much additional value, as it would’ve been more inconvenient to set the alarm on a separate device anyways. I also was unsure if any of the output devices on-hand could generate a sound as loud as my phone.

Process Images

Initial sketch of my device before modeling it on Autodesk Fusion, during the ideation process.

 

Autodesk fusion model of the box to be laser-cut. This was my first time ever doing any modeling or using Autodesk Fusion, so it was quite a challenge to design everything and model it. In the end, I was really happy with how it came out!

A bundle of wires in the beginning frames of a box.

Beginning to put the electronics components in the 3D printed box. This was a lot trickier than expected, because I had to do a lot of rearranging to account for where each component should poke out from in the box.

Discussion

Overall the process of creating this project was super fun, but challenging! It was really cool to think about the ergonomic aspect of this project and to create a device I may actually use, especially coming from Project 1, which was mostly focused on the electronics aspect. I am super happy with the results, although there are a few things I would change, some of which were also pointed out during critique.

“You could potentially try to make it sensitive to the phone so that the object is not tricked by anything else”

This is definitely the biggest thing I would change if I were to create another iteration of my project. Currently, a big limitation in my device is that it’s very easy to “trick” it into thinking my phone is there, by placing any arbitrary object on the device. Since the IR sensor only detects some sort of presence, I could easily pick up my phone and block the sensor with something else. In a future iteration, I would either supplement this method of detection with another one, or to replace the IR sensor entirely. One possible method is to lay out a few IR sensors in the shape of the perimeter of my phone, such that they are placed right under where the edges of my phone would be, as well as a few on the outside of the perimeter. Then, the device would only recognize my phone there if the sensors on the perimeter detect a presence, and the ones outside of the perimeter don’t. This would ensure that the object placed has to be exactly the shape of my phone for it to stop the buzzing. One limitation of this idea is that I could still dupe the phone by cutting an object to be the same shape, or strategically placing things on top of the inside perimeter sensors. However, this would be a lot more work to “trick” than placing any arbitrary object on top, which would probably be enough to prevent me from wanting to override it. Another method would be to switch out the proximity sensor for a pressure sensor, but again, I could also dupe this if I found a similarly weighted object to my phone. Plus, if I really wanted to stop the device I could just unplug it anyways.

Potentially have a potentiometer or some other method to adjust the waiting period”

This was definitely something I thought of doing during ideation, but I ultimately decided to hard-code the timer, as I didn’t want to give myself an easy way to lessen the waiting period and instead force myself to go the full 60 minutes. In retrospect, though, I definitely agree that this might be helpful and could still keep me accountable if I set, say, 45 or 60 minutes as a “lower limit” to the timer, and only allowed myself to adjust the timer up. This is definitely something I would consider doing in a future iteration.

Besides the changes described above, something else I would want to do is to refine the form of my device. Right now, it’s a bit clunky, and the bottom portion is a bit large since I wasn’t very space-efficient in my wire management. Since it was my first time fabricating, the appearance was also a bit clunky, with some accidental cutouts I didn’t mean to include, as well as lots of glue everywhere. I also would want to add an “emergency override” button. One idea that I had been thinking about in my ideation to avoid making this “emergency override” make me less accountable was to add time, say 5 minutes, to the timer for the next lock session every time I pressed it. I also would want to refine the microphone threshold a bit more, as it was still slightly too sensitive, and would get triggered if there was a super loud noise that wasn’t my phone.

Overall, though, I’m super happy with how my project came out! My main goal of this project was to build a useful device for myself and to fabricate something I could be proud of, which I think I definitely satisfied. While there were a few things I would like to refine, especially regarding the form, I am still pretty happy with it, especially given that it was my first time using a laser-cutter or doing any sort of modeling or physical prototyping. In general, I learned a lot about both the technical side of fabrication (i.e. using the software), as well as the design-thinking it takes to plan out the form factor and ergonomics of a physical device. I also definitely learned that fabrication can take multiple iterations to get right, and to not underestimate how long this might take in the future. Next time, I would also plan out the electronics part more in tandem with the physical form. This time, I did all of the wiring first without thinking much into how I would put everything together into the final physical device at the end, and then did all the modeling and laser-cutting after this. This caused me to have to spend a lot of time reconfiguring my wiring to fit into the device and trying to cram it in, which could’ve been avoided if I had thought about the physical form more and knew things like approximately how long to make the wires, which parts should be wired closer together, etc.

Technical Information

Block Diagram

block diagram with optical proximity sensor and microphone as inputs into an arduino uno, and active buzzer & lcd module as outputs

 

Schematic

Code

/*
* Good Morning Phone Jail
* Michelle Liu
* 
* An assistive device that prevents you from going on your phone in the morning by
* creating a loud buzzing noise when your phone is removed from its surface in the
* hour after your alarm goes off.
* 
* Pin Map:
  variable name | mode | pin | description
  -----------------------------------------------
  SOUND_GATE_PIN | input | 2 | detect sound from mic
  SOUND_ENVELOPE_PIN | input | A3 | read sound from mic
  PHOTO_PIN | input | A0 | reads IR sensor data
  BUZZER_PIN | output | 9 | makes buzzing noise
* 
* Credits:
* 
* LCD display code referenced from the course website: 
* https://courses.ideate.cmu.edu/60-223/s2023/tutorials/I2C-lcd
* 
* Piezo buzzer code:
* https://www.instructables.com/How-to-use-a-Buzzer-Arduino-Tutorial/
*/


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C screen(0x27, 16, 2);

const int SOUND_GATE_PIN = 2;
const int SOUND_ENVELOPE_PIN = A3;
const int PHOTO_PIN = A0;
const int BUZZER_PIN = 9;

const int SOUND_THRESHOLD = 300;
const int LIGHT_THRESHOLD = 320;

// actual mode (60 min)
const unsigned long WAIT = 60 * 60 * 1000;

// demo mode (30 sec)
//const unsigned long WAIT = 30000;

boolean timerActive = false;
unsigned long timer = 0;
int dispDelay = 0;

void setup() {
  Serial.begin(9600);
  pinMode(SOUND_GATE_PIN, INPUT);
  pinMode(PHOTO_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);

  screen.init();

  // set cursor to home position, i.e. the upper left corner
  screen.home();

  timerActive = false;
}

// convert milliseconds to a string for display on the LCD
String millisToString(unsigned long currentMillis) {
  unsigned long seconds = currentMillis / 1000;
  unsigned long minutes = seconds / 60;
  unsigned long hours = minutes / 60;
  unsigned long days = hours / 24;
  currentMillis %= 1000;
  seconds %= 60;
  minutes %= 60;
  hours %= 24;
  return (String(hours) + ":" + String(minutes) + ":" + String(seconds));
}

// print the current amount of time left on the timer
void printTime() {
  screen.clear();
  screen.setCursor(0, 0);
  if (!timerActive) {
    screen.noDisplay();
    screen.noBacklight();
  } else {
    screen.backlight();
    screen.display();
    screen.print("Time left: ");
    screen.setCursor(0, 1);
    unsigned long timeLeft = WAIT - (millis() - timer);
    screen.print(millisToString(timeLeft));
  }
}


void loop() {
  int sound = analogRead(SOUND_ENVELOPE_PIN);
  
  printTime();

  // case 1: timer is currently active
  if (timerActive && millis() - timer < WAIT) {
    int photo = analogRead(PHOTO_PIN);

    // play a sound if no device is detected
    if (photo >= LIGHT_THRESHOLD) {
      tone(BUZZER_PIN, 500);
    } else {
      noTone(BUZZER_PIN);
    }
  } else if (!timerActive && sound >= SOUND_THRESHOLD) {
    // case 2: alarm detected -> activate the timer
    
    // start timer
    timerActive = true;
    timer = millis();
    Serial.print("Timer activated: ");
    Serial.println(sound);
    noTone(BUZZER_PIN);
  } else if (timerActive && millis() - timer >= WAIT) {
    // case 3: time is up -> deactivate timer & turn off buzzer
    timerActive = false;
    timer = millis();

    noTone(BUZZER_PIN);
    screen.clear();
    screen.setCursor(0, 0);
    screen.print("Timer complete!");

    // beeping sound to indicate timer is complete
    for (int i = 0; i < 5; i++) {
      tone(BUZZER_PIN, 1000);
      delay(200);        // on for 1 sec
      noTone(BUZZER_PIN);     // Stop sound
      delay(200);
    }
    delay(3000);
  } else {
    timer = millis();
    noTone(BUZZER_PIN);
  }
  delay(300);
}

 

]]>
Social Shield 2023 https://courses.ideate.cmu.edu/60-223/s2023/work/my-social-shield/ Wed, 15 Mar 2023 12:23:21 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17948 Description

This is a wearable piece that includes a pair of glasses that can change the opacity of the lens and a little installation that can be attached to clothes and will display text and make sounds when the sensor senses things within its range.

Overview

 The lens is transparent when there is no one within 50 cm;

and the LCD screen displays”Hi. Do not approach” The lens becomes dark when someone is standing within 50 cm;

and the LCD screen displays “!!!STEP BACK!!!”

 

Simulation of you walking up to a person wearing this device

This is a jacket on a hanger. The glasses’ lens will become dark when the distance is within 50cm, just like what happens in the photo above.

 

 

The overall device. (I don’t have anyone with me, so I have to put it on a table and record this. )

 

 

Detail of the device:

The glass frame has an angle and a rail that allows me to slide the lens in simply if I need to change the lens.

Background

This is an assistive device for me.

First, it’s about social distance. I feel that the term “social distance” was used everywhere during the pandemic. During that time, most of us were used to keeping our distance from others. But as we are now in the post-pandemic era, I don’t see a lot of people still maintaining social distance now. However, I still like to keep a certain distance from other humans in social situations. I also sometimes find it difficult to interact with people at a close distance, especially at social events.

The reason is probably that I read a novel called “No Exit” by Jean-Paul Sartre, a French playwright. He proposed a derived philosophical theory called “others are hell.” This sentence doesn’t mean that other people are the devil. It means that everyone is free without others’ intervention. In the book, Sartre describes four people whose souls have fallen into hell. There is no torture or fire as expected, but only a closed chamber that locks the four people so that whatever they do has to be done in the presence of others. The lights are always on, and the knife cannot kill other people. Sartre considered such to be the suffering of hell. My understanding is that in such a situation, the gaze of others can influence my free will, shape my choices and cause me pain, especially when I sometimes make choices against my will under the influence of others. I see other people as people that are “not me.” In this case, the difference between “me” and “others” defines the scope of “self.” So, without others, I would not be the person I am now, but the person I am now is in danger of losing my ability to judge and choose freely because of others.

To put it in perspective of vision, human vision is more than simply looking at things. When I look at the outside world as an individual, the world comes together towards me, hence, I am the center of the world, and I am completely free. This gives rise to a transcendence, meaning that I am subjective, which is also called the  ‘subject self’ by Sartre. But when in groups or in public, all my activities will be branded with the shadow of others, and I will find myself gazed at by others. I then will degenerate under the gaze of others because I take the gaze of others as my own possibility in my activity. This is also an alienation, an objectification, and a deprivation of freedom and transcendence as a subject. Thus the ‘subject me’ becomes the ‘object me,’ and the OTHERS become the subject in my eyes. The “my world”  built up by my perspective collapses, and this is the so-called “other is hell.”

If we reflect this theory into reality, I think people become “objects” when they interact with each other in any form, for example, eye contact or conversation. I don’t want to lose my subjective self in social and public events, so I thought of making this device. Basically, there is an ultrasonic ranger on the installation that can be attached to clothing. This is to sense the distance. When no one is in my social comfort zone (50cm), the lens of the glasses (light valve) is clear, like normal light-colored indoor sunglasses, and the LCD screen will display “Hi. Do not approach”. But when someone steps into my social comfort zone, the lenses of the glasses will darken, basically impossible to see through, and the device that is attached to the clothing will start going on an alarm. The text on the screen will change to a flashing “!!! STEP BACK!!!”. This device is also an artificial social shield for me.

 

Process

Decision 1:

I spent a lot of time thinking and experimenting with two kinds of sounds for a ‘warning sound.’

  1. Use a buzzer. This will create a sound that really sounds like a warning. but people may wonder if there’s anything bad happening.
  2. 2. Use a speaker that plays my own voice saying “Step back.” This fits my ideation more; however, as I tested it with my friends, I got feedback like “I heard Angie’s voice, so I want to come closer.” This totally contradicts my intention. But I found it interesting that sometimes the result will be different from my ideation until I really experiment with my design with people.

I finally decided to use the buzzer because it is small so it can be glued to the back of the screen together with the ultrasonic ranger. Most importantly, it turns out to be less attractive than using my own voice.

 

 

Decision 2:

For the glasses’ frame, I want it to have a futuristic look like the 3D model I made, ideally.

The modeling process took a very long time because this was my first time using Rhino to build a 3D model.

 

I initially wanted to use 3D printing because the nylon material is more suitable for a wearable device since it can bend a little. However, the 3D printer failed my printing several times, and almost 20 hours were wasted.

These are pictures of the first and second time of printing failures.

 

 

So, Cody suggested and helped me a lot to use the laser cutter instead. Since I have never used a laser cutter before, I also spent time learning how to operate the machine and put the parts together.

 

 

 

 

But the dimension of my model is wrong when the software automatically converts the 3D model to the slices. The original dimension of the frame should exactly fit my head. And the failed 3D printing actually fits according to my original dimension. However, the laser-cut pieces turned out to be much bigger than the dimensions I set. This also resulted in I had to hold the glasses during the showcase. The frame on the right is the 3D printing (third failed version), and the one much bigger on the left is the laser cutting version.

 

Discussion

I prefer to call it my work rather than a project. The idea of my creation has always been to do something meaningful. For example, this work combines the philosophical theory of Sartre while curing my fear of social interaction. So in a macro sense, I am satisfied with it.And I like the process of me brainstorming about things.For example, the futuristic glasses reminded me of my other work about bionic robots. So when I was finishing the wiring, I thought of wrapping the wires with soft pipes. This not only solves the problem of messy wiring but also leads me to think about another possibility: what if a bionic robot were to wear the device? Can these wires be plugged directly into its body? Maybe this can be a way to train it to learn and ‘feel’ like a real person, a person that has problems socializing with other people.

However, there are still some regrets about this work, such as the fabrication part. In fact, the final version of laser cutting is not quite what I wanted in mind. And the size of the cut is not the same as the one I measured, so the work is not perfect. But anyway, I think this is a good start, and I am grateful for everyone’s help. I have never used laser cutters and 3D printers before, so I learned a lot of skills from quick learning and operation this time.

I also received a lot of meaningful feedback. One is about the choice of sound that the device would make when people are getting closer. This is also one of the most tangled questions during the process. It is interesting to hear that different people have different suggestions and preferences on sounds choice. Some say that they would be attracted more by the buzzer sound, while some say they definitely will come closer and take a look if it is displaying a sound of me or a robot. I think this is something associated with psychology and sociology. I definitely would dig into related research and see which way may fit my concept better. Another interesting piece of feedback is from one of the faculties. He commented that maybe it would be better to create a device that could make me invisible in public places. But I thought about it for a long time, and I think that this is not the best solution for me. I think my main point is to avoid social interactions that make me uncomfortable, like getting too close, rather than hiding myself completely. When others step into my comfort zone, even if I don’t want to be forced to be an “object, I am physically present in the world, so I have no right to prevent anyone from gazing at me or interacting with me. This is their freedom. All I can do is shield myself and avoid interactions. After all, all I want is to remain my own self when socializing, and perhaps choosing to avoid unnecessary interactions is also a manifestation of the subjective self.

Technical information

Block Diagram:

Schematic Diagram:

 

Code

// My Social Shield
// Angie (Chuyi) Wang
// This code allows you to make a sound with a buzzer, display different texts on an LCD screen and control the transparency of 
// a light valve while the ultra sonic ranger detects the distance.
//For the light valve, one wire goes to the GND and another wire must be connected to analog pin. (I used A0)
// References: https://courses.ideate.cmu.edu/60-223/s2023/tutorials/I2C-lcd
//             https://www.instructables.com/How-to-use-a-Buzzer-Arduino-Tutorial/

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define trigPin 10
#define echoPin 13

#define LIGHTVALVE A0
int brightness = 0;
int fadeAmount = 5; 

const int buzzer = 7; //buzzer to arduino pin 7
long transparency;


// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);


void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(buzzer, OUTPUT); // Set buzzer - pin 7 as an output
  pinMode(LIGHTVALVE, brightness);
  lcd.init();
     lcd.begin(10,2);
}

void loop() {
  float duration, distance;
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0344;

  int d1 = distance;
  // mapping the distance to brightness
   if(d1 > 90){
     d1 = 90;
   }

  // analogWrite(LIGHTVALVE , brightness);
  brightness = map(d1, 0, 90, 255,0);
  analogWrite(LIGHTVALVE,brightness);

  lcd.clear();

 // delay(100);
  if (distance >= 50 || distance <= 2){
    Serial.print("Distance = ");
    Serial.println("Out of range");
   // Serial.println(distance);
    //panelState = 0;
    brightness = 0;
    // delay(1000);
    //analogWrite(d1 , LIGHTVALVE);

    	// Turn on the blacklight and print a message.
    lcd.backlight();
    lcd.setCursor(4,1);
    lcd.print("HI.");
    lcd.setCursor(4,2);
    lcd.print("DO NOT APPROACH.");
    delay(500);

  }
  else {
    lcd.backlight();
    lcd.setCursor(1, 5);
   // lcd.clear();
    lcd.print(" !!!STEP BACK!!!");
    //print distance to serial
    Serial.print("Distance = ");
    Serial.print(distance);
    Serial.println(" cm");
    delay(200);

    //Buzzer
    tone(buzzer, 1000); // Send 1KHz sound signal...
    delay(500);        // ...for 1 sec
    noTone(buzzer);     // Stop sound...
    delay(200);        // ...for 1sec
    
    //change the transparency
    // analogWrite(LIGHTVALVE , brightness);
    brightness = brightness + fadeAmount;


  }
  
}

 

]]>
The Hot Grog-inator https://courses.ideate.cmu.edu/60-223/s2023/work/the-hot-grog-inator/ Tue, 14 Mar 2023 23:48:40 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17546 Project 2: A Personal Assistive Device for Caleb

The Hot Grog-inator is a personal assistive device that helps me keep track of tea-steeping and prevent mouth-burning.

Demo –

Please note that the device is in demo mode right now, meaning it’s timer functionality is set to activate at 3 seconds and it’s temperature functionality is set to activate when it reaches above 50 degrees Celcius. In practice, the Grog-inator’s timer buzzer will be set to go off at 3 minutes, and the temperature buzzer will go off when reaching below 65 degrees Celcius.

Details –

Close-up of the temperature probe on underside of device

Temperature probe on the underside of the Grog-inator

Electronic components of the device, with a 9 volt battery, an arduino micro, and a breadboard

Interior of the Grog-inator

Process –

Initial ideating of the hot grog-inator

Initial ideation of the hot-groginator. I was inspired by burning my mouth on tea one too many times, and wanted to make a device that could prevent that from happening.

Electrical components in a light green housingSmall protoboard and components

Decision 1:

Redo the soldering. Due to the micro requiring soldering, I had to solder everything to prototype. I ended up restarting because the wires got too hard to work with. It was a good learning experience on when to give up and when to try to prototype with the least permanent medium as possible.

Image of Solidworks process with housing

CAD Modeling process

Decision 2:

Give up on the lighting. I made lighting windows that would be connected to the power to indicate a clear on and off state, but they didn’t work well with all the electrical components inside. Additionally, the second light would be much dimmer than the first. I thought it would be a cool decoration, but couldn’t justify it with the issues I was having, so I ended up scrapping the idea. It was a good lesson on knowing the limits of time and electrical capability.

Feedback –

Can’t wait to see it all come together a little scared of condensation accumulating on electronics, but I think your casing will protect it.

I definitely considered how the electronics are going to be close to hot water. It’s something that’s hard to contend with given the limitations of my fabrication skills, but I believe that by limiting the use of the lid to just a short part of the life cycle of a hot drink, and enclosing the electronics in a sealed case that will be finished with water-proof material should suffice. Ideally, of course, it would be created using cast plastic if actually put into production.

What are the housing considerations for the electronics? Given the scale of the drawings, it seems like it would be hard to fit everything.

I’m going to use an Arduino Micro and a 9-volt battery for the brains and power of the grog-inator, and that should limit the footprint of the electronic components significantly. While designing the housing, I just need to make sure to accommodate for everything.

Self Critique –

I’m pretty satisfied with the Hot Grog-inator. I think that given the scope and timeline of the project, the fidelity that I got the device to felt appropriate. It’s self-sufficient and doesn’t require being plugged into the computer, and is programmed fairly robustly, being able to be reset with a button. Overall, though, this feels like a proof-of-concept prototype that I’m very happy with.

Learning –

I learned a lot about coding through this project. I think this project was relatively simple electronically all things considered. However, coding the right behavior and making it reliable and robust when not having the ability to access or reset the Arduino was a significant challenge. I wanted to make the device reset automatically when it was powered on, and when that didn’t work I tried to have it reset every 30 minutes. When that didn’t work, I ended up just adding a button to trigger a reset.

Another thing I learned was to not get ahead of myself with fabrication. I ended up having to reprint the lid twice due to being impatient and not measuring things correctly, and still having very little room to work with. Seeing as this was my first time 3D printing, it’s kind of to be expected, but should still be a more thought-out step next time.

Next Steps –

I think if I had more time I would try to make the interior more neat, in that I would try to use a smaller protoboard and divide the wires up so that they weren’t as confusing as before. I would also make the housing more fit to different cups, with a more dramatic cone-line bottom. Currently the grog-inator doesn’t fit all of my cups and that significantly decreases usability. I’d also try to create more exact housing that secures the protoboards and batteries into place, so that everything isn’t just clunking around in the device.

Finally, I would also not paint over the entire device. I like the color I chose, but it’s definitely not something that helped the final fidelity and the imperfect paint job bothers me endlessly.

Block Diagram –

A block diagram for the electronics of the Hot Grog-inator

Block diagram

Schematic Diagram –

Schematic diagram for the Hot Groginator

Code –

//Hot Grog-inator Code
//Caleb Sun
//Code activates buzzer to beep 3 times 3 minutes after button is pressed to indicate tea-doneness, and 5 times after temperature sensor detects that drink is at safe drinking temperature (65 degrees C)
#include <OneWire.h>
#include <DallasTemperature.h>

#define tempPin 3
#define buzzerPin 4
#define buttonPin 5

OneWire oneWire(tempPin);	

DallasTemperature sensors(&oneWire);

int teaTemp = 0;
int buttonState = 0;
int buzzCounter3 = 0;
int buzzCounter5 = 0;
const int threeMin = 180000;
const int BuzzDelay = 300;
unsigned long buzzerTimer = 0;
unsigned long threeMinTimer = 0;

bool buzzerState = LOW;

void setup(){
  pinMode(tempPin,INPUT);
  pinMode(buzzerPin,OUTPUT);
  pinMode(buttonPin,INPUT);
  sensors.begin();	// Start up the library
  Serial.begin(9600);
}

void loop()
{ 
  if (millis() == 10000){
    buzzCounter5 = 0;
  }
  sensors.requestTemperatures(); 
  teaTemp = sensors.getTempCByIndex(0);
  if (teaTemp < 65){
    if (((millis() - buzzerTimer) >= BuzzDelay) && (buzzCounter5 < 5)){
      buzzerState = !buzzerState;
      buzzerTimer = millis();
      buzzCounter5 = buzzCounter5 +1;
      }
    else {
      buzzerState = LOW;
    }
    digitalWrite(buzzerPin,buzzerState);
  }

  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {
    threeMinTimer = millis();
    buzzCounter3 = 0;
  }

  if (((millis() - threeMinTimer) > threeMin) && (threeMinTimer != 0)) {
    if (((millis() - buzzerTimer) >= BuzzDelay) && (buzzCounter3 < 3)) {
      buzzerState = !buzzerState;
      buzzerTimer = millis();
      buzzCounter3 = buzzCounter3 + 1;
    }
    else {
      buzzerState = 0;
    }
    digitalWrite(buzzerPin,buzzerState);    
  }
}

 

 

]]>
Pen-Corecting Device https://courses.ideate.cmu.edu/60-223/s2023/work/pen-corecting-device/ Tue, 14 Mar 2023 18:42:53 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17882 This device works to train the user to hold their pen correctly. If the user holds their pencil incorrectly they face consequences.

box device with 3 LEDs and a spray bottle, there is a drawing of a hand writting with two rings and wires connected. The same rings and wires can be seen in front of the device connecting to it.

The back reads “learn to hold your pen the correct way, simply place on the rings and get to writing. Pen-Correct will make sure to keep you on track!”

box opened up so you see Arduino and wires inside. a servo is sticking out of the left side.

The red box half is 3D printed and holds the servo motor tightly against the bottle cap. The bottle can be taken in and out from the bottom. The right side is foam core housing the rest of the electronics

The device works through a switch connected to your ring and pointer finger. When they connect you get a strike. Your strikes are counted on the lights displayed on the box. After three strikes, a servo is triggered and water is sprayed on your work! After three strikes the count resets and you can continue.

Process images and review

notebook page with notes from the first critique. There is a crude sketch of the box in front of a hand attached to it with wires

notes from the first crit

One of the main decisions points in my process was deciding what I wanted the consequence to be for holding your pen incorrectly. At first I was thinking a whole cup of water would spill on you and your work, but I decided that would be a bit excessive. During our first feedback session my group gave me a lot of good ideas, one of which included a spray bottle. I liked the spray bottle because it would ruin your work and be high stakes, but be more contained and more subtle. I has a few ideas for pressing down on the spray bottle, but I was surprised on how much force it took to do so successfully. First I tried a solenoid, but that wasn’t strong enough so I though a linear actuator, but that was too big, so then I landed on a servo motor which was perfect.

two rings made of copper take attached to wires attached to a switch layout on a breadboard

This is my first iteration of the switch activated sensor. The copper rings would flip a switch when ring and pointer finger connect (a sign that you hold your pen wrong)

final finger switch layout with more flexible wires, and a Velcro around the wrists

final finger switch layout with more flexible wires, and a Velcro around the wrists

Discussion

From the feedback in our first critique, one of the major things we talked about was how I would pursue the consequence of one holding their pen incorrectly. We talked first about water as a consequence, whether or not I should target the user or the work, as well as other methods pertaining to sound or vibration. Everyone was in agreeance that a whole cup of water might be excessive. One critique suggested I use a spray bottle which I ended up using. Another discussion came up about wire placement on the fingers. at first I was thinking they would be placed on the middle phalanx, but this might cause false positives even when holding the pen correctly, so from this point I learned it would be better if I moved them up to rest on the distal phalanx, that way the pen would be in-between the two figures increasing accuracy. Finally we talked about ergonomics. A lot of people were concerned on how I would manage the wires on the hand. I ended up just having two rings so orientation wasn’t important, and then had them connect to a wrist band that was Velcro. I attached the wires to the machine on the right side so they would go around the outside of your work space, but they might get in the way for a left handed user.

Overall, I am happy with the outcome of the project. It was accurate enough in sensing the fingers touching together and the servo worked well in spraying the water bottle onto your work. I think although I may not use this device everyday, it could be a fun training device for children or others who are learning to hold their pens correctly. I simply wish I had done so in my youth for the hand pain it has caused me today, but I think the chances are low that I will ever actually learn to correct this bad habit. I enjoyed working on this project because it was light hearted and relatively simple allowing room for creativity.

Throughout this project I really liked working with physical devices. I am jealous of other’s projects that had more satisfying physical responses and interactions like switches or buzzers. I only wish that mine had more of this response, especially when counting strikes. Besides this, I had a lot of time exploring the physical form for the project, making everything neat, and color matching all the components. On the more technical side, I found that my java script coding knowledge came in handy as they bases of the languages were similar. When coding different responses for different strikes I made different variables that were counted and then wrote conditional statements for each stage.

Like I mentioned above, If I could make this again I would make for more response when gaining strikes. During the final crit someone had mentioned that by moving the servo when you had a strike, not enough to trigger the bottle, but enough to make a sound, that that would be a great way of having and auditory feedback to the strikes without having to add other components. I also like this idea because it would instill fear in the user when they get a strike because they wouldn’t be sure or not if their work was going to get prayed or not. I would also try to be neater with the wire, heat shrinking them might have been nice, but I am unsure if this would effect their flexibility.

Technical information

 

//PEN CORRECT 
//evette LaComb - physcial computing project 2 
//

//      Servo Motor Control using the Arduino Servo Library
//            by Dejan, https://howtomechatronics.com

int light1 = 5;
int light2 = 4;
int light3 = 3;
int finS = 8; //fingure switch

#include <Servo.h>
int strike;
Servo myservo;  // create servo object to control a servo

void setup() {
  myservo.attach(9,600,2300);  // (pin, min, max)
  myservo.write(90);

  pinMode(finS, INPUT);
  pinMode(light2, OUTPUT);
  pinMode(light1, OUTPUT);
  pinMode(light3, OUTPUT);
}

void loop() {

//if there are no strike, lights off
  if (strike == 0){
    digitalWrite(light2, LOW);
    digitalWrite(light1, LOW);
  }

//if strikes go over 3 reset
  if (strike >= 3){
      strike = 0;
  }
  
//if switch is low aka holding pen incorecty add a strike  
  if (digitalRead(finS) == LOW){
    strike += 1;
    delay(1000);
  }  

//if strike is one turn the first light on 
  if (strike >= 1){
    digitalWrite(light1, HIGH);
  }  

//if strike is two turn on the second light
  if (strike >= 2){
    digitalWrite(light2, HIGH);
  } 

//if 3 strikes then turn on the third light and spray 
  if (strike == 3){
    digitalWrite(light3, HIGH);

    myservo.write(180);              
    delay(1000);
    myservo.write(90);
    delay(1000);

    digitalWrite(light3, LOW);
    
  } 

  Serial.println(strike);
          
}
]]>
Physical Wake-up Service https://courses.ideate.cmu.edu/60-223/s2023/work/physical-wake-up-service/ Tue, 14 Mar 2023 05:22:42 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17755 Physical Wake-up Service:

A very effective alarm clock that gives you an wake-up experience you’ve never had before.

 

Images:

Front view of device

Side view of device

 

 

Processing

 

Key decision point

When I finished working on the servo motor through time control I actually finished the basic work. After that I decided to add buttons to make it easier for the user to operate. I didn’t intend to include these buttons in my earliest preconceptions, but it would result in the inconvenience of having to upload the set time once every time I set the alarm, which is very inconvenient.

 

I didn’t want to add an LCD screen in my earliest preconceptions, but eventually I thought it would be a good idea to add an LCD screen to visualize the whole process, after all, as an alarm clock, it would be unreasonable for the user not to be able to see the time directly. But this eventually led me to the assembly of the line gave me a lot of trouble.

 

Process

As the earliest model, I initially wanted to stick everything on a can of compressed air, but this made the device very awkward to use, so the idea was abandoned.

 

In this image I only decided to stick the servo motor with the canned compressed air. This way the servo motor can directly touch the trigger of the canned air. I used zip ties to keep the servo motor in place on the canned air, and I added a layer of double-sided tape between them to increase friction so the servo motor wouldn’t move around.

 

This image shows the Real Time Clock, which reads the current time and runs itself internally, so it keeps the correct time after one code upload. So it becomes the most important component.

 

This image shows the earliest prototype of the device, which was assembled into a small model, eventually making rewiring the device the most difficult task. And the original small button had to be replaced with a red button, but the red button had poor contact. So I still think the small button is more suitable for this device.

 

Discussion:

First we discussed the comments about the classroom, and as I looked through the comments I found that there were no comments with substantive suggestions. So I thought I would respond to the verbal suggestions that were made at the time. There were two points in total, the first was about the model, the model was not designed very well. The cans of air and servo motor are completely exposed, and it would be better to cover them up to keep the user mystified. And the tube used to extend the distance of air injection needs to be fixed in a better way. I couldn’t agree more with these two points, first of all the first point was not envisioned when I designed the model and I think it makes perfect sense. This is really a design flaw that I need to improve. But the second point is also something I had thought about, in my opinion I need a tube that is closer to the material of the water pipe, since this material is soft enough and can be extended while fixing a certain shape.

Going back to my own opinion about my project, I think I am very satisfied with my project, but the result is not 100% satisfying to me. One of the main reasons is that when I should use the red buttons, I can’t set the alarm time accurately with these buttons. The link to it is very unstable due to the soldering. I tried to use smaller buttons but they could not be firmly fixed on the model. So it would be a great success if I could solve this problem. The next point of dissatisfaction is the model, I think the model design has many defects. In addition to not covering the canned air well as mentioned before, I think I designed the model too delicate, which gave me a lot of trouble when lining up the wires. All the wires were messed up which made me struggle a lot during assembly, so a bigger model was necessary. In addition, I also need to design an extra socket on the model to connect the Arduino to the computer, so that it is more convenient to upload.

Through the process of working on this project, I realized that I need to be more attentive in designing models. I don’t think I’m incapable of doing this well, I just think I need more time and more common sense. So I think this project is a very good attempt. Next time I will consider the wiring first and the aesthetics second. Also if I could give my previous self a suggestion, I would tell him that.

In the follow-up I hope to have the opportunity to continue building another iteration of this project. First I will solve the model problem, I will make the model bigger to make the wiring easier, and make the appearance more user-friendly. After that I will figure out how to solve the button problem, I hope there is a better way or I can find a suitable button to solve the poor contact problem. When the two problems are solved I believe the device can really be put into use.

 

Technical Information:

 

 

 

Code

/*
Project Name: Physical Wake-up Service
Made by Yuxi(Ethan) Xu

- LCD screen display real time and set alarms
- use button to set alarms
- servo motor will be activated when the set time is reached
- servo motor presses the trigger of can of compressed air

Pin Mapping:
3: Servo motor
4-7: Button Power In 1-4
12: Switch Power In

Some of the code is adapted from the following sources
- DS3231 RTC (Real Time Clock) Interfacing with Arduino to build DIY Digital Clock, Author: Harshil Patel
- ArduinoGetStarted.com: Arduino - Switch
*/

#include <RTClib.h>
#include <Wire.h>
#include <Servo.h>
#include <ezButton.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C screen(0X27, 16, 2);
ezButton toggleSwitch(12);
RTC_DS3231 rtc;

//Servo motor
const int SERVOPIN = 3;
Servo Servo1;

//Buttons
const int buttonPin1 = 4;
const int buttonPin2 = 5;
const int buttonPin3 = 6;
const int buttonPin4 = 7;
int PbuttonState1;
int PbuttonState2;
int PbuttonState3;
int PbuttonState4;
int buttonState1;
int buttonState2;
int buttonState3;
int buttonState4;

//Alarm clock
int alarmhr;
int alarmmin;
int h;
int m;
char t[32];

void setup() {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  Servo1.attach(SERVOPIN);
  toggleSwitch.setDebounceTime(50);

  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);

  rtc.adjust(DateTime(F(__DATE__),F(__TIME__))); //adjust Real Time Clock to current time (You can delete it after uploading it once)

  screen.init();
  screen.backlight();
}

void loop() {

  //Real Time Clock setup:
  DateTime now = rtc.now();
  sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());  
  h=now.hour();
  m=now.minute();

  //Switch setup:
  toggleSwitch.loop();
  if (toggleSwitch.isPressed()){
    Serial.println("The switch: OFF -> ON");
  }
  if (toggleSwitch.isReleased()){
    Serial.println("The switch: ON -> OFF");
  }
  int state = toggleSwitch.getState();

  //LCD setup:
  if (state == LOW){
    Serial.print(F("Date/Time: "));
    Serial.println(t);

    //Print "Time/Date: " and Real Time Clock on LCD
    screen.home();
    screen.print(F("Time/Date: "));
    screen.setCursor(0, 1);
    screen.print(t);
  }
  else{
    //Print "SetAlarmHr/Min: " and "SetAlarmHr/Min: " on LCD
    Serial.print("SetAlarmHr/Min: ");
    screen.home();
    screen.print("SetAlarmHr/Min: ");

    //Button setup:
    PbuttonState1 = buttonState1;
    PbuttonState2 = buttonState2;
    PbuttonState3 = buttonState3;
    PbuttonState4 = buttonState4;

    //Read state of button
    buttonState1 = digitalRead(buttonPin1);
    buttonState2 = digitalRead(buttonPin2);
    buttonState3 = digitalRead(buttonPin3);
    buttonState4 = digitalRead(buttonPin4);

    //Set hours and minutes when pressed button
    if(buttonState1 == HIGH && PbuttonState1 == LOW){
      alarmhr += 1;
    }
    if(buttonState2 == HIGH && PbuttonState2 == LOW){
      alarmhr += 10;
    }
    if(buttonState3 == HIGH && PbuttonState3 == LOW){
      alarmmin += 1;
    }
    if(buttonState4 == HIGH && PbuttonState4 == LOW){
      alarmmin += 10;
    }

//Print set alarm time
screen.clear();
    Serial.println(alarmhr);
    Serial.println(alarmmin);
    screen.setCursor(0, 1);
    screen.print(alarmhr);
    screen.setCursor(3, 1);
    screen.print(alarmmin);
    
    //Servo motor works according to the time set by the alarm clock
    if((h==alarmhr) && (m==alarmmin)) {
      Servo1.write(175);
      delay(300);
      Servo1.write(90);
      delay(300);
    }
  }
}

 

]]>
Count by Hand! https://courses.ideate.cmu.edu/60-223/s2023/work/count-by-hand/ Sat, 11 Mar 2023 21:39:17 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17735 by Mo Cambron

Count by Hand! is a stitch and row counter for knitting and crocheting.

The Count by Hand! counter box. (approx. 4″ x 2.5″ x 1.75″)

The glove with integrated buttons.

In action while knitting!

Process

In the beginning ideation phase, my initial idea was to have the counter be a part of a yarn bowl (a bowl that holds the yarn so it doesn’t roll around while you knit). When we talked with small groups about our idea, I talked with my group about how to make it easier to hit the buttons to add to the count. It was then that I decided to incorporate the buttons into a glove that would be right there on your hand.

My initial sketch with the yarn bowl concept.

For the glove fabrication, I first soldered silicone coated wires to three tactile push buttons. Then I determined the placement of the buttons and cut very small holes in the glove. I mounted the buttons to a small piece of fabric stabilizer, then sewed the whole thing to the inside of the glove. The mechanics and wiring are all contained inside the stabilizer, so it is comfortable to the touch inside the glove.

Glove fabrication!

I initially used a medium size breadboard just so I could figure out the connections for everything before making final decisions. I then realized that I wanted a smaller board so I could fit everything into a smaller container. This began the bread board saga. I first tried to switch everything over to a small breadboard. I then ran into issues with the power running the small one. I tried using a different small breadboard, but had the same results. I finally decided to just hack a medium breadboard in half with a saw in order to have a smaller overall size, but still be able to use the power rails on the board.

The breadboard saga!

I learned how to four strand braid to contain the wires from the glove to the box in a functional and beautiful way.

Four strand braid.

 

My friend trying to figure out how high the count could go – they gave up before they reached the max.

Discussion

I received some really helpful feedback from my peers in our final presentation. One person said that they “would like to see some user study info from [me] and other people to find the perfect button type and placement.” I totally agree with this – I would love to experiment more with the exact button placement on the glove for myself, as well as taking into account other fiber artists grips and styles of holding the tools. Finding a placement that could work well for a lot of different types of people would be a very exciting endeavor.

Another person asked if it was “possible for the buttons to activate without meaning to?” It’s pretty unlikely with the way the needles lay on my hand while I’m knitting, but it is certainly possible. I would love to add a function to undo or remove stitches without completely resetting the count in the future.

Overall, I’m pretty happy with how this project turned out. I’m very pleased with the electronic aspect of it – the functions that I was aiming for all turned out well. There are certainly more functions that I could add moving forward, but as far as the ones I included, they were very successful. The fabrication is definitely something that I would like to put more time and precision into in the future. I didn’t leave myself enough time for the fabrication, and so I rushed and cut corners a bit, then attempted to go back and fix those mistakes afterwards. I’d like to really take my time and be precise with my fabrication in the future.

I felt that I improved quite a bit on the electronics throughout this project. I’ve had very little experience in electronics and coding before this class, so I’ve definitely had a large learning curve. I liked the process of this project in that I had a problem to solve in my own life, and I had to figure out the specific functions that would solve it, rather than being assigned specific functions without much of a practical function like Project 1. It felt like there was more at stake here, and I enjoyed that. A fun little skill that I learned during this project was how to braid with four strands, which I used to braid the silicone wires that connected the glove to the counter.

If I were to take the project further, I would definitely focus on the fabrication more. I would like to streamline the design to be the most portable it could be, while still fitting all the components that it needs to. Additionally, I would like to add a function to adjust the count up and down to account for mistakes in addition to being able to reset the count totally.

 

Technical Information

Block diagram:

 

Schematic:

 

// Count by Hand: Keep track of your stitch and row counts!
// Mo Cambron

// Tactile push buttons sewed into a glove allow user to count the stitch
// and row count of a knitting/crochet project. 5V runs to three buttons,
// each button then runs back to Arduino Pro Micro. "St" adds to the stitch count.
// "Row" adds to the row count. "Res" resets the stitch count. Stitch and row count
// are displayed on an LCD screen. "Res" button next to LCD screen resets all counts.

// Pin mapping:
// - pin 5 = stitch reset button
// - pin 7 = stitch add button
// - pin 9 = row add button
// - pin 14 = total reset button


const int stRes = 5;
const int St = 7;
const int Row = 9;
const int Res = 14;

int stVal = 0;
int stPrev = 0;
int stCount = 1;
int stPress = 0;

int rowVal = 0;
int rowPrev = 0;
int rowCount = 1;
int rowPress = 0;

int stresVal=0;
int resVal=0;

const int stAddress = 0;
const int rowAddress = 5;


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#include <EEPROM.h>

LiquidCrystal_I2C screen(0x27, 16, 2);

void setup() {
  pinMode(stRes, INPUT);
  pinMode(St, INPUT);
  pinMode(Row, INPUT);

  Serial.begin(9600);

// LCD setup:
  screen.init();
  screen.backlight();
  screen.home();
  screen.print("Count by Hand!");
  delay(2000);
  screen.clear();

// Print "St=" and "Row=" on LCD
  screen.setCursor(0, 0);
  screen.print("St=");
  screen.setCursor(8, 0);
  screen.print("Row=");

// Get previous row and st counts for project
  EEPROM.get(stAddress,stPress);
  EEPROM.get(rowAddress,rowPress);
  stCount=stPress;
  rowCount=stPress;

// Print previous row and st counts onto LCD
  screen.setCursor(3, 0);
  screen.print(stPress);
  screen.setCursor(12, 0);
  screen.print(rowPress);
}

void loop() {

// St button read
  stPrev=stVal;
  stVal=digitalRead(St);
  if(stVal==HIGH && stPrev==LOW){
    stPress=stCount++;
    EEPROM.put(stAddress,stPress);
  }

// slight delay to account for bounce
  if(stVal==LOW && stPrev==HIGH){
    delay(20);
  }


// Row button read
  rowPrev=rowVal;
  rowVal=digitalRead(Row);
  if(rowVal==HIGH && rowPrev==LOW){
    rowPress=rowCount++;
    EEPROM.put(rowAddress,rowPress);
  }

// slight delay to account for bounce
  if(rowVal==LOW && rowPrev==HIGH){
    delay(20);
  }


// St reset button read
  stresVal=digitalRead(stRes);
  if(stresVal==HIGH){
    stPress=0;
    stVal=1;
    stCount=1;
    screen.setCursor(3,0);
    screen.print("    ");
  }

// Reset all
  resVal=digitalRead(Res);
  if(resVal==HIGH){
    stPress=0;
    stVal=1;
    stCount=1;
    rowPress=0;
    rowVal=1;
    rowCount=1;
    screen.setCursor(3,0);
    screen.print("    ");
    screen.setCursor(12,0);
    screen.print("    ");    
  }

// Print current st count to LCD
  screen.setCursor(3,0);
  screen.print(stPress);

// Print current row count to LCD
  screen.setCursor(12,0);
  screen.print(rowPress);
}

 

]]>
Task Box https://courses.ideate.cmu.edu/60-223/s2023/work/task-box/ Sat, 11 Mar 2023 06:35:47 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17674  

Task Box

This project is a modular physical to do list that allows the user to customize which tasks they do each day. It tracks task completion and task progress.

Images:

Large black box with switches and lights on front panel and large gray top panel

Top view of device

black front panel of box; all switches are in the down position, all lights are flashing red

All Front Switches flipped to red; indicating 0% completion

panel with 3 switches up and 3 switches down. in the top row of LED's 3 are red and 3 are green, a light bar on the bottom is 50% filled and yellow in color

Half of the switches are flipped to complete, the top row of LED’s show individual task progress, the progress bar on the bottom shows % of tasks complete.

task box demo

Process images and review:

Key Decision points

The first decision point came after prototyping a switch panel. The initial idea was to use a limit switch to detect the presence of a tile. After fabricating a sample switch it was determined that it would be difficult to create a tile system that was strong enough to toggle the switches. From this prototype, I decided to use IR proximity sensors instead to track tile placements.

The second decision point occurred after completing the full wiring for the device as pictured above. It was clear that I had underestimated the amount of space that all of the wires would take up, thus the acrylic casing that I had cut for to store the wires was far too small. Given limited time and resources, my solution was to construct a temporary larger box out of chipboard for the presentation, and then redesign the outer case at a later date.

Process

A tan panel with various switches, lights and sensors glued into it

This is the Completed front panel. consisting of 12 LED’s 6 switches, 6 IR sensors, and 3 Neopixel light strips. There are also slots precut for tile placement as well as a hinge hole located in the top to aid with electronic access in the final product.

a small breadboard with wires linking to an arduino

This is a sample circuit that I made in order to run test code for IR proximity sensor as well as check sensors for any defects. The final version uses the same circuit.

Lots of wires

This is the completed wiring for the number 6 IR proximity sensor, at this point in the project the switches and LED’s are already wired and working. The remaining step is to wire the other 5 IR sensors and adjust the code to incorporate them. The wiring process was very time consuming, but troubleshooting issues was less difficult than expected due to my diligence with color coding. The final version required 1.5 full breadboards and 2 additional power rails.

Arduino Mega with many wires

Here is the completed Arduino wiring. The color coding is as follows, Green: Green LED power, Red: Red LED power, White: toggle switch signal, Blue: IR sensor signal. There is also additional wiring in the device not pictured above that follow an equally strict color convention. Black: Ground from switches/LED’s/Colorstrip/Pulldown resistors/IR emitter, Grey: Ground from IR photoresistor, Red: Power for LED’s/Colorstrip/IR emittor, Orange: Power for IR sensor. Brown/Yellow: Power in between all of the subsystems.

Discussion:

I am overall pleased with the outcome of the project and intend to use it myself. The presentation also went relatively smoothly. Looking at the critique comments one person noted that “Make it smaller if possible. I thought the finish a circuit idea was really good.” For the first part of the comment, I would agree with the recommendation. Given the relative simplicity of the devices operation, it would be nice for the design to be less invasive in terms of the amount of space that it would take up. Ideally it would be a small box that sits on my desk as per the initial design. However, as the device is constructed currently, creating a new smaller casing would not be feasible as the amount of wiring restricts the minimum size of the casing. I think that in order to achieve a sleeker design, it would require major rewiring to shorting the existing wires and soldering every connection such that the process of cramming the wires into a case does not affect the connections. The second half of this critique was commenting on tile detection methods. I initially experimented with using conductive tape to bridge a circuit to indicate the presence of a tile. This was with the intention that I could add resistances into the tiles that the Arduino could measure to encode tasks. Since then I have discovered the IR sensor solution which I think is better than the solution that the critique proposes. I think that the IR sensors are easier to work with, require less manufacturing of each tile, and are still task encodable by using different color acrylic. Another comment from the critique noted: “I really like the idea and the tactility to it makes it more satisfying. “. It was my intention to create a lot of tactile, auditory, and visual feedback from completing a task to create a system that is more satisfyingly than conventionally marking off a to do list. I’m glad to hear that there is some consensus that the design that I envisioned has a similar satisfying aspect to others.

The final presented project works as intended. I am a little upset that the sleek black casing could not be shown during the presentation but I intend on making a new case for my own use. The operation of the devices is exactly as I envisioned and I think that this will be genuinely useful for my everyday life. For this project, I wanted to build upon the skills from project 1 and ultimately create a devices with a better aesthetic and design than project 1, and create a deceives with significantly higher consistency and durability than my project 1. I think that even though the end product was not what I had envisioned, I have sufficiently met these two goals.

The process of creating this project was filled with significantly more complications than project 1. Unlike many in this class, I have no background in creative or practical design or much experience with fabrication. Being a Statistics and Machine learning major, my strength lies in the coding portion of this project. I intentionally decided on a device where aesthetic, design, and construction would be more challenging and coding would be rather simple in order to work on those skills. If I had more time, I would’ve liked to go through multiple iterations of the design portion. Unfortunately, with limited time and resources, I was not able to adjusted the design of the case as I would have liked to. I also underestimated the amount of time and the difficulty of the wiring of the final product. I had constructed multiple little circuits of each component prior to the final assembly in order to finalize circuit layout and also test each part for defects, but when combining all of the components together, it was very difficult to plug things in and organize stuff with the quantity of wires I was working with. A large reason was due to some of the wires from my components being too short, this either restricted the location of breadboards, or necessitated extending the wire with a new one and heat shrink. Both resulted in complications that took a lot of time to resolve. For the future, when I anticipated complicated wiring, I would cut longer leads for components as well as consider using softer more flexible wires.

I have a lot of ideas for improvements and iterations for this project. Firstly, I will design and create a new casing for the version that I already have so that I can use it on my desk. I intend on doing this within the next couple of weeks as time permits. This will probably be the only thing that I do with regards to project 2, however, If I were to build another version, I have many improvements that I’d pursue.

The first adjustment would be encoding tasks with different color tiles. This would primarily be a coding change as the sensors have the capability of distinguishing between colors. another adjustment would be implementing a photoresistor that would detect external lights. Since the LED’s are quite bright, I wouldn’t want them to be on if I am sleeping. This photoresistor would turn all lights off if the surrounding room is dark. In addition to these new features, I would also like to make the wiring changes that I previously talked about in this next iteration.

Technical Information:

/*
Project Name: Task Box

Author: Harry Ren

- tracks tile placement with 6 IR proximity sensors
- tracks task completeness with 6 toggle switches
- uses information to light up 12 LED's signaling task completeness

Pin Mapping:
A0-A5: IR Proximity Sensor Out 1-6
3: LED Data IN
24,26,28,30,32,34: Red LED Pwr Out 1-6
25,27,29,31,33,35: Green LED Pwr Out 1-6
46-51: Switch Pwr IN 1-6

Portions of code are adapted from the following sources
- NEOPIXEL by ADAFRUIT example: strandtest
relevant functions are credited

code by Harry Ren at Carnegie Mellon University (hjren@andrew.cmu.edu)
released by author to public domain, Mar 2023
*/



#include <Adafruit_NeoPixel.h>
#include <Servo.h>
#include <NewPing.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#ifdef __AVR__
#include <avr/power.h>  // Required for 16 MHz Adafruit Trinket
#endif

// Neopixel connection Pin?
#define LED_PIN 3
// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 24
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

//Set Pin constants
//LEDS
const int r1 = 24;
const int g1 = 25;
const int r2 = 26;
const int g2 = 27;
const int r3 = 28;
const int g3 = 29;
const int r4 = 30;
const int g4 = 31;
const int r5 = 32;
const int g5 = 33;
const int r6 = 34;
const int g6 = 35;
//Switches
const int sw1 = 51;
const int sw2 = 50;
const int sw3 = 49;
const int sw4 = 48;
const int sw5 = 47;
const int sw6 = 46;
//IR sensors
const int sensor6 = A0;
const int sensor5 = A1;
const int sensor4 = A2;
const int sensor3 = A3;
const int sensor2 = A4;
const int sensor1 = A5;

void setup() {

  pinMode(sw1, INPUT);
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);
  pinMode(sw4, INPUT);
  pinMode(sw5, INPUT);
  pinMode(sw6, INPUT);

  pinMode(r1, OUTPUT);
  pinMode(g1, OUTPUT);
  pinMode(r2, OUTPUT);
  pinMode(g2, OUTPUT);
  pinMode(r3, OUTPUT);
  pinMode(g3, OUTPUT);
  pinMode(r4, OUTPUT);
  pinMode(g4, OUTPUT);
  pinMode(r5, OUTPUT);
  pinMode(g5, OUTPUT);
  pinMode(r6, OUTPUT);
  pinMode(g6, OUTPUT);

  pinMode(sensor6, INPUT);
  pinMode(sensor5, INPUT);
  pinMode(sensor4, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor1, INPUT);



  Serial.begin(9600);

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(1);  // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() {

  int threshold = 800;
  //boolean flags for if tile exists
  int tilebool6 = false;
  int tilebool5 = false;
  int tilebool4 = false;
  int tilebool3 = false;
  int tilebool2 = false;
  int tilebool1 = false;

  int sen6 = analogRead(sensor6);
  int sen5 = analogRead(sensor5);
  int sen4 = analogRead(sensor4);
  int sen3 = analogRead(sensor3);
  int sen2 = analogRead(sensor2);
  int sen1 = analogRead(sensor1);


  //adjust flags given sensor readings
  if (sen6 > threshold) {
    tilebool6 = true;
  }
  if (sen5 > threshold) {
    tilebool5 = true;
  }
  if (sen4 > threshold) {
    tilebool4 = true;
  }
  if (sen3 > threshold) {
    tilebool3 = true;
  }
  if (sen2 > threshold) {
    tilebool2 = true;
  }
  if (sen1 > threshold) {
    tilebool1 = true;
  }
  //set light on booleans
  bool tag1 = false;
  int on1 = 0;
  int on2 = 0;
  int on3 = 0;
  int on4 = 0;
  int on5 = 0;
  int on6 = 0;
  //read switches
  int switch1 = digitalRead(sw1);
  int switch2 = digitalRead(sw2);
  int switch3 = digitalRead(sw3);
  int switch4 = digitalRead(sw4);
  int switch5 = digitalRead(sw5);
  int switch6 = digitalRead(sw6);

  //tile 1 logic
  if (tilebool1) {
    if (switch1 == 0) {
      digitalWrite(g1, HIGH);
      digitalWrite(r1, LOW);
      on1 = 1;
    } else {
      digitalWrite(r1, HIGH);
      digitalWrite(g1, LOW);
      on1 = 0;
    }
  } else {
    digitalWrite(r1, LOW);
    digitalWrite(g1, LOW);
  }
  //tile 2 logic
  if (tilebool2) {
    if (switch2 == 0) {
      digitalWrite(g2, HIGH);
      digitalWrite(r2, LOW);
      on2 = 1;

    } else {
      digitalWrite(r2, HIGH);
      digitalWrite(g2, LOW);
      tag1 = true;
      on2 = 0;
    }
  } else {
    digitalWrite(r2, LOW);
    digitalWrite(g2, LOW);
  }
  //tile 3 logic
  if (tilebool3) {
    if (switch3 == 0) {
      digitalWrite(g3, HIGH);
      digitalWrite(r3, LOW);
      on3 = 1;

    } else {
      digitalWrite(r3, HIGH);
      digitalWrite(g3, LOW);
      tag1 = true;
      on3 = 0;
    }
  } else {
    digitalWrite(r3, LOW);
    digitalWrite(g3, LOW);
  }
  //tile 4 logic
  if (tilebool4) {
    if (switch4 == 0) {
      digitalWrite(g4, HIGH);
      digitalWrite(r4, LOW);
      on4 = 1;

    } else {
      digitalWrite(r4, HIGH);
      digitalWrite(g4, LOW);
      tag1 = true;
      on4 = 0;
    }
  } else {
    digitalWrite(r4, LOW);
    digitalWrite(g4, LOW);
  }
  //tile 5 logic
  if (tilebool5) {
    if (switch5 == 0) {
      digitalWrite(g5, HIGH);
      digitalWrite(r5, LOW);
      on5 = 1;

    } else {
      digitalWrite(r5, HIGH);
      digitalWrite(g5, LOW);
      tag1 = true;
      on5 = 0;
    }
  } else {
    digitalWrite(r5, LOW);
    digitalWrite(g5, LOW);
  }

  //tile 6 logic
  if (tilebool6) {
    if (switch6 == 0) {
      digitalWrite(g6, HIGH);
      digitalWrite(r6, LOW);
      on6 = 1;

    } else {
      digitalWrite(r6, HIGH);
      digitalWrite(g6, LOW);
      tag1 = true;
      on6 = 0;
    }
  }

  else {
    digitalWrite(r6, LOW);
    digitalWrite(g6, LOW);
  }
  delay(10);


  //progress bar calculations and display code
  int number_in_use = tilebool1 + tilebool2 + tilebool3 + tilebool4 + tilebool5 + tilebool6;
  int number_complete = on1 + on2 + on3 + on4 + on5 + on6;

  int lightperon = (int)24 / float(number_in_use);
  int colscale = (int)300 / float(number_in_use);

  //edge case for 5 tiles
  if (number_in_use == 5) {
    lightperon = 5;
  }
  strip.clear();

  //neopixel bar code
  for (int i = 0; i < number_complete * lightperon; i++) {
    //Serial.print(i);
    strip.setPixelColor(i, get_col(colscale * number_complete));
  }
  strip.show();
}

//helper func to get color value from project 1
uint32_t get_col(int i) {
  //red to yellow
  if (i < 170) {
    i = map(i, 0, 170, 0, 255);
    return strip.Color(255, i, 0);
  }
  //yellow to green
  else if (i < 340) {
    i = map(i, 170, 340, 0, 255);
    return strip.Color(255 - i, 255, 0);
  }
  //green to cyan
  else if (i < 510) {
    i = map(i, 340, 510, 0, 255);
    return strip.Color(0, 255, i);
  } else if (i < 680) {
    i = map(i, 510, 680, 0, 255);
    return strip.Color(0, 255 - i, 255);
  } else if (i < 850) {
    i = map(i, 680, 850, 0, 255);
    return strip.Color(i, 0, 255);
  } else {
    i = map(i, 850, 1023, 0, 255);
    return strip.Color(255, i, 255);
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

]]>
Ulnar Entrapment Elbow Sleeve https://courses.ideate.cmu.edu/60-223/s2023/work/ulnar-entrapment-elbow-sleeve/ Sat, 11 Mar 2023 03:51:59 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17684 An elbow sleeve that vibrates when your elbow is bent past 90 degrees for too long, and when you put excessive pressure on your elbow joint.

 

Fits around halfway up your upper arm, and covers the elbow. Pancake vibration motors are placed over the bicep.

 

Fabric is elastic and bends with the elbow without restriction

 

Flex sensor and pressure sensors located under the elbow joint.

 

Arduino Pro Micro powered by a 9V battery. All connections are soldered.

 

Closeup of electronics and shoddy hot-gluing and sowing.

 

Process

I started by picking out some components and wiring them on a breadboard to get an idea of what I’ll be using and how they work, as well as the code needed to run it.

First attempt getting a pancake vibration motor to respond to a flex sensor and pressure sensor.

 

 

After getting an idea of the components I’ll be using, I taped the flex sensor underneath my elbow as a proof-of-concept prototype. It worked surprisingly well! Next up is trying to fit it all on an elbow sleeve.

 

First attempt at fitting a pancake vibration motor, flex sensor, battery and Arduino Pro Micro on an elbow sleeve.

 

Everything works as expected – the motor vibrates when the elbow is bent past 90 degrees – but its still lacking the pressure sensor. Also, the wiring is very un-robust. The Arduino Pro Micro and pancake vibration motors are connected directly to the 9V battery. From here I worked on the hardware to make sure its safe and reliable.

 

Wiring the battery to a latch switch and voltage regulator.

I used silicon cables to wire up the flex sensor as to not hinder any movement of the joints.

 

Pancake vibration motors and pressure sensors wired up. Pancake vibration motors connected to an N-channel MOSFET.

 

With the hardware working, I started attaching the hardware to the elbow sleeve with Velcro, shoddy sowing and hot-glue. Since the flex sensor itself can’t stretch and compress, it was most difficult trying to fix the flex sensor to the sleeve in a way that allows it to travel when the elbow is bent, but not so fixed that the sensor flexes outwards when the arm is straightened.

 

The flex sensor bends outwards when the arm is straightened, if there isn’t any tension pulling the strip upwards or downwards.

 

Closeup of everything secured to the elbow sleeve.

 

First-person view of elbow sleeve with components attached.

 

Discussion

Looking at the responses from my classmate, it’s clear that my solution would work better if it looked better – and I agree. That would turn the solution from something that works to something someone would actually want to use everyday, as one of my classmates put it. In its current state, all the electronics are exposed and haphazardly attached to the sleeve, which renders the whole thing useless as soon as it gets cold and someone has to put on a jacket, or when it just rains a little. The reason why my final product looks this way is because of timeframe and my inexperience with fabrics. Early on in the project, I was very interested in the types of fabrics I could use, especially ones that were used in existing compression elbow sleeves. They seemed to have a good balance of stiffness and elasticity, such that I could reasonably create a pouch to house the electronics. It was also mentioned that to improve the solution, there should be some indication as to how the sleeve should be worn, which was a very valuable piece of critique I hadn’t addressed. For the flex sensor and pressure sensors to work accurately, the flex sensor has to be centered over the elbow joint, but there aren’t any affordances or even instructions that lead to this consideration. I can think of some ways to implement this off the top of my head – like cutting a hole at the ‘hinge’ of the elbow sleeve so that there’s a more apparent top-side and bottom-side, or using an accelerometer and the pancake vibration motors to help the user position the arm sleeve correctly? I’m not sure what would work to be honest.

All-in-all, I’m still quite happy with how the final product turned out, because it works reliably and consistently (if worn right of course). It’s wearable, it detects when you’ve bent your elbow past 90 degrees for too long, it detects if you’re putting too much pressure on your elbow, and it tells you to stop. It was most fulfilling being able to create something that responds directly to the biomechanics of the human body on a wearable device, which isn’t just pushing buttons and flipping switches. Part of the reason why I think something like this should exist in the world is because elbow braces designed to prevent ulnar entrapment are intentionally stiff, to make it physically harder for you to bend your elbow for prolonged periods of time – but I wanted there to be a sleeve that still allowed freedom of movement, and I think my final product achieved that goal to a degree. I was able to practice some simple soldering and learn about building robust circuits. Though building the circuit was very simple on the breadboard, I spent a lot of time planning out my soldered breadboard, working around including components to improve the robustness of the circuit, and the placement of wires and resistors so I can see what I’m doing myself. I think I want to move towards building circuits that are less stuck to breadboards now, especially if I’m going to work on more wearables.

If I were to build another iteration, I think I would focus all my energy on fabrication to house the electronics. This would also mean making the hardware more low-profile and resistant to deformation – to bring the product to something more close to a ‘living’ piece of fabric? And less of hardware tacked onto fabric. I think this would mean using stiffer and thicker fabrics and foams, and soldering closer to the breadboard so that the overall height of the hardware can be brought down. As for the battery, I’m not sure what I’d do without the 9V battery. It just makes sense to charge and replace the battery. Or I guess coin batteries wired in series could work too.

 

Block Diagram

Circuit Diagram

Code

const int flexPin = A0;
const float VCC = 5;
const float R_DIV = 10000.0;
const float flatResistance = 10000.0;
const float bendResistance = 30000.0;

const int vibrPin = 3;
const int pressurePin = A2;

int bentTimer = 0;

// flex sensor code from: https://www.instructables.com/How-to-use-a-Flex-Sensor-Arduino-Tutorial/

void setup(){
  Serial.begin(9600);
  pinMode(flexPin, INPUT);
  pinMode(vibrPin, OUTPUT);
  pinMode(pressurePin, INPUT);

// turn on sequence

  digitalWrite(vibrPin, HIGH);
  delay(300);
  digitalWrite(vibrPin, LOW);
  delay(300);
  digitalWrite(vibrPin, HIGH);
  delay(300);
  digitalWrite(vibrPin, LOW);
  delay(300);
  digitalWrite(vibrPin, HIGH);
  delay(300);
  digitalWrite(vibrPin, LOW);

}

void loop(){
  int flexNum = analogRead(flexPin);
  int pressureNum = analogRead(pressurePin);

  float Vflex = flexNum * VCC / 1023.0;
  float Rflex = R_DIV * (VCC / Vflex - 1.0);
  Serial.println("Reistance: " + String(Rflex) + " ohms");
  
  float angle = map(Rflex, flatResistance, bendResistance, 0, 180.0);
  Serial.println("Bend: " + String(angle) + " degrees");
  Serial.println("Pressure: " + String(pressureNum) + " units");
  Serial.println();

// if arm is bent past 70 degrees, begin counter.

  if (angle >= 70){
    bentTimer += 1;
  } else{
    bentTimer = 0;
  }

// if counter exceeds 10 seconds, or pressure is detected, activate vibration motors. 

  if (bentTimer > 50 || pressureNum > 850){
    digitalWrite(vibrPin, HIGH);
  } else{
    digitalWrite(vibrPin, LOW);
  }

  Serial.println("Timer: " + String(bentTimer) + " seconds");

  delay(200);
}

 

]]>
Breathing Lamp: An Improved Bed-Time Routine https://courses.ideate.cmu.edu/60-223/s2023/work/nightly-breathing-lamp-an-improved-bed-time-routinue/ Thu, 09 Mar 2023 20:41:08 +0000 https://courses.ideate.cmu.edu/60-223/s2023/work/?p=17625 A lamp that integrates with my room set-up and nighttime routine to initiate a period of mindful breathing through a series of brightening and dimming light cycles before sleep.

The photoresistor facing a light, and the meditation lamp is off. The photoresist is taken away from the lamp to imitate darkness, and the meditation lamp starts a cycle.

A video of the project working!

Scale and proportional context photo!

Detail Photos

Showing the back of the lamp, with the arduino, arrangement of led strip, wiring, hook for handing, and power cord.

The inner workings of the lamp! Slightly tight wiring, but otherwise, fit everything quite well inside the shell. Hook for hanging as well!

Photoresistor that extends out of the lamp to face the main source of light before sleeping.

Little legs that prop the lamp off the wall to achieve the backlight effect from the LEDs

In-use photos

Cool glowing effect when dark!

Brightening and dimming of the lamp!

Process

A drawing with a cylindrical lamp form and another with it mounted on a wall with a person looking at it to follow a meditation cycle

First brainstorming of the concept!

My idea is to create a lamp that is seamlessly integrated into my bedtime routine to encourage a period of reflection and pause before sleep. I felt a need for this because I found myself coming back home from long busy days, with no time to truly just be with myself and reflect— it would always be a shower, brush, scroll on phone, often with no step between looking at a screen and actually sleeping. I wanted to create a tangible object that would integrate with this existing rough routine I had, not forcing me to stop going on my phone or texting my parents but instead just creating a natural buffer between all of that and sleep.

I felt like a lamp, as a big fan of ambient lighting, would be an appropriate object in my room, and a nice physical representation of calming down and taking a break. I considered adding a bunch of fancy functionalities like programming the amount of time I wanted to spend with the lamp with a dial, or being able to change light color settings, but decided against these for both keeping it simpler for myself to realistically make, but also allowing a more effortless use of the lamp. Sensing the presence of someone with an ultrasonic ranger was also something I considered (as shown in the drawing above), but I decided against, because it would also add an extra step to initiate the routine that I wanted to avoid. Instead, I opted for a photoresistor that would point to a night light that I already use, and have the breathing lamp be triggered by switching off of the light to indicate I was ready to go to sleep and start my brief time of breathing and reflection before sleeping!

 

I started by thinking about some of the form considerations for the lamp, especially since having a nice shell that looked clean, and contained all the electronic components well would be important.

The final lamp shell design! It fit the Ideate 3D printers well and had ample room for the LEDs, and Arduino to fit inside. Theres also little legs to prop it off the wall, and a hook for hanging.

Wiring of the LED strip, photoresistor, and arduino

Getting the LED’s to work with the photoresistor

Folding the led strip to make it more flexible and be able to fold around the lamp.

Sanding the 3D print

Working back and forth between paint and sanding

The surface of the 3D print was a struggle to work with. To save on plastic and time, I had done a lower-quality print, but this meant I had a lot more imperfections in the surface of the shell. The only way that really made sense to counter this was to sand it— so I did! But sanding also wasn’t really enough to get the “perfect” soft surface I had originally intended. During the sanding process, I had noticed how the sanded black PLA looked a bit like the moon, so I decided to lean into that idea and added more texture through paint.

final finishing of paint with my fingers to create more texture

 

the empty shell of the 3d print, and showing how the electrical parts would fit inside.

The assembly of the lamp

Discussion

Some of the comments I got: “Simple and effective”, “Great impact can’t wait to see it on a wall”, “Could consider Bluetooth module for the photoresistor” and  “Would love to see different casings with quality materials, wood glass ect, the simplicity would make that possible”. I think I approached my project from quite a product perspective, and with those considerations, it would make a lot of sense to have pushed the materiality and form of the project.

The wires and open back are definitely a concern too, but given the scope of the project, and my experience, I am quite satisfied with the overall project. I think I satisfied my own goals but had also set the goals quite conservative to begin with. However, there are a lot of the features that I could build on, such as a better solution to the photoresistor sticking out the way it does, and having a self clock on the lamp that only allows it to work at certain hours of the day, but given the time constraint, I’m happy with what I presented and that at its core it does what it’s supposed to!

Now, feeling better about coding for the Ardunio and being resourceful about libraries, I also think I can push the intervals of breathing times as I had originally planned— with the lamp guiding you from expected breaths times to slowly slower breaths during the course of the cycle. I would also like to turn some nice wood on a lathe and try creating a more organic feeling shell in the near future too! 

I think I really enjoyed thinking about and designing the interaction and storyboarding how the object could be used, and be useful to me but struggled a bit more with the technical side of coding.  I think the syntax and learning how to communicate with the Arduino was hard for me, especially because I knew what I wanted it to do, and would put it down in a similar way as you would in javascript (which is something I’m a bit more familiar with), but then it just wouldn’t work. It helped to ask for help though, and some of my classmates were really nice to share their knowledge on how to efficiently write code and create the loops I wanted.

Technical information

Block diagram showing the photoresistor input, and LED output.

Electrical schematic diagram. Only showing 3 LEDs for simplicity, but there are 30 in the strip.

 

// Breathing Lamp
// Sapna Tayal

// This code communicates the turning off of a light source (lamp before sleeping)that is measured by a photoresistor, and communicates, via an Arduino, to start a LED strip brightening and dimming cycle.
// I used the Pololu LedStripGradient example code as a jumping off point.

#include <PololuLedStrip.h>

// Create an ledStrip object and specify the pin it will use.
PololuLedStrip<12> ledStrip;

const int pResistor = A0;

// Create a buffer for holding the colors (3 bytes per color).
#define LED_COUNT 30
rgb_color colors[LED_COUNT];
int Brightness = 0;

int cycleCount = 1;
bool up = true;
int lightVal = 0;
bool lightOn = false;
int cycles = 0;

void setup() {
  pinMode(pResistor, INPUT);
  Serial.begin(9600);
}

void loop() {

  lightVal = analogRead(pResistor);
  Serial.println(lightVal);

  // setting the LED strip to plain white, and having the brightness be the driving variable
  for (uint16_t i = 0; i < LED_COUNT; i++) {
    colors[i] = rgb_color(Brightness, Brightness, Brightness);
  }

  // Write the colors to the LED strip.
  ledStrip.write(colors, LED_COUNT);

  // mapping the photoresistor to notice the change of a bright lamp light.
  // variable LightOn to start the lamp
  if (lightVal < 900) {
    lightOn = true;
  }

  //
  if (lightOn == true && cycles < 15) {
    if (cycleCount == 235) {
      up = !up;
      cycleCount = 1;
      cycles = cycles + 1;
    }

    // slowly increasing brightness
    if (up) {
      Brightness++;
      delay(20);
      cycleCount++;
    }

    // slowly decreasing brightness
    else {
      Brightness--;
      delay(20);
      cycleCount++;
    }
  }

  // turn of when done with 15 cycles
  else {
    digitalWrite(7, LOW);
  }
}

 

]]>