Project 2 – Intro to Physical Computing: Student Work https://courses.ideate.cmu.edu/60-223/f2018/work Intro to Physical Computing: Student Work Sun, 16 Dec 2018 16:38:47 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.25 Digital Stylist https://courses.ideate.cmu.edu/60-223/f2018/work/digital-stylist/ https://courses.ideate.cmu.edu/60-223/f2018/work/digital-stylist/#respond Mon, 29 Oct 2018 12:51:46 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4750 Overview

It’s not a special day, facing the closet, you hesitate about what to wear to go to class today. Don’t want to waste time choosing clothes every day? Digital Stylist will help you make the decision!

The appearance of Digital Stylist when the power is off.

The appearance of Digital Stylist when the power is on.

The front of the Digital Stylist.

Top view of the Digital Stylist.

The detail of the LED stripe.

The detail of the buttons and the LCD screen.

The randomly generated numbers represent different combinations of clothing (T: T-shirt, J: Jacket, C: Winter Coat, S: Shorts, P: Pants), and you can switch between different seasons (Spring/Fall, Summer, Winter). The lights will also tell the color you will wear today. With the help of Digital Stylist. you don’t have to make the difficult decision every morning!

Process images and review

Some other ideation sketchings.

Some other ideation sketchings.

My initial concept was to make a machine to help me pick what I wear every day. Since 90% of my clothes are black, I didn’t think of the color combination in the beginning. But after discussing with Professor Zach and TA Runchang, I thought it would be interesting to visualize the results. So I decided to add the LED strip to my project.

The biggest problem I encountered during the production was the coding of the LED strip. I chose a library called “FastLED” at first, which was a little complicated for me. Although I tried my best to understand it and the code was actually running perfectly, the LED strip didn’t work at all. So after meeting, I took Zach’s advice and switched to another simpler library called “PololuLedStrip”. Although the final assembly was a bit rough because the coding part took me so much time, it worked very well.

The prototype of the Digital Stylist.

I tried to add the LED strip to the prototype.

I replaced the small buttons with bigger and colorful buttons since it would be easier for people to press.

Due to time constraints, I made the box manually.

The main panel was assembled.

The main structure of the box was completed.

The internal structure of the Digital Stylist.

It was born twenty minutes before the presentation!

Discussion

I did learn a lot from the project critique. The advice gave me a lot of inspiration that I hadn’t thought of before.

For example, “I appreciate the design for its idea of choosing clothes! I guess it would be even better if it actually has the algorithm to memorize your past choices so that you can change the probability of generating the random number according to your past choices.” Because at that time, the project requirement was to make an assistive device for my own use. For a guy who only has dark color clothes and doesn’t care much about dress collocation, I didn’t think much of this perspective. My original intention of the Digital Stylist is for lazy people who don’t care about dressing (like me). But it’s a really interesting idea to generate numbers according to the past choice or fixed number combination instead of generating some random numbers, which would make the dressing choice much more reasonable.

Here is another great feedback:” What do you do to categorize your clothes that are in your dirty laundry? Maybe a laundry basket by RFID could eliminate options from the database.” I did think of the laundry issue when I started writing the code. But because there are lots of color combinations for different random numbers, the code became more complex than I expected (more than 550 lines). So I left the laundry part on hold in order to finish the project on time. Although I’m not sure if the RFID is the best way, this feedback definitely gave me a new approach to solve this problem.

I’m quite satisfied with the final result of this project. Although the appearance seems a bit rough, it works pretty well. The buttons are satisfying and the UI screen is fluent, which showed my idea clearly. What’s more, I am very happy that this concept has struck a chord with many people.

In the meantime, I think the code part and the LED strip did not work very well as I expected. Due to problems using “FastLED” library, I didn’t have time to optimize my final code. My final solution was listing every possible number combinations to change the LED colors, which was a time-consuming work. I’m pretty sure that there will be a better and easier way to optimize the code. Originally, I was planning to take Zach’s advice to put the LED strip as a person’s shape so that people can have a more intuitionistic feeling to the color collocation of the dress. At last, I didn’t make it because I spent most of my time in coding.

However, I also learned a lot from working on my own. The same electronic component can always have many different libraries to make it work. It can save much time if you choose the easiest one to learn and understand. On the other hand, there is an old saying goes that “the onlooker sees most of the game”. In the conceptual stage, we should not just bury our head in the hard work, but discuss with teachers and classmates, so as to get more comprehensive thinking. And feedback after a completed project is often valuable.

If I have the chance to build another iteration of the Digital Stylist, I want it to be “smarter” so that it can remember the preferred dressing choice and eliminate the laundry clothes from the database. At the same time, I hope to further reduce the size of the device to provide more space for a better shaped LED strip.

Technical information

Digital Stylist Schematic

/*
  Project 2: Digital Stylist
  Author: Jianxiao Ge (jianxiag)
  Date: October 10th,2018
  Brief explanation:
  It's not a special day, facing the closet, you hesitate about what to wear to go to class today.
  Don't want to waste time choosing clothes every day? Digital Stylist will help you make the decision!
  The randomly generated numbers represent different combinations of clothing, and you can switch between different seasons. The light will also tell the color you will wear today.
  With the help of Digital Stylist. you don't have to make the difficult decision every morning!
*/

// Assume I have
// 10 T-shirts: 1-5 are orange (250,110,0), 6-10 are cyan (0,250,130)
// 10 Jackets: 11-15 are blue(0,0,255), 16-20 are purple(170,0,255)
// 5 Winter Coats: 21-25 are grey (160,160,160)
// 5 Shorts: 1-2 are yellow(230,230,0), 3-5 are Light red(255,0,70)
// 5 Pants: 6-7 are Light blue(0,180,255), 8-10 are white(255,255,255)

// Set up the LCD
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Set up the LED Strip
#include <PololuLedStrip.h>
// Create an ledStrip object and specify the pin it will use.
PololuLedStrip<6> ledStrip;
// Create a buffer for holding the colors (3 bytes per color).
#define LED_COUNT 30
rgb_color colors[LED_COUNT];

int tshirtDressNumber;
int jacketDressNumber;
int winterCoatDressNumber;
int shortsDressNumber;
int pantsDressNumber;
const int SPRINGFALLBUTTON = 2;
const int SUMMERBUTTON = 3;
const int WINTERBUTTON = 4;
const int RESETBUTTON = 5;
int springFallButtonValue = 0;
int summerButtonValue = 0;
int winterButtonValue = 0;
int resetButtonValue = 0;

void setup() {
  pinMode(SPRINGFALLBUTTON, INPUT_PULLUP);
  pinMode(SUMMERBUTTON, INPUT_PULLUP);
  pinMode(WINTERBUTTON, INPUT_PULLUP);
  pinMode(RESETBUTTON, INPUT_PULLUP);

  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Digital  Stylist");
  lcd.setCursor(5, 1);
  lcd.print("Howdy!");

  byte time = millis() >> 2;      // initialize the LED strip
  for (uint16_t i = 0; i < LED_COUNT; i++)
  { byte x = time - 8 * i;
    colors[i] = rgb_color(x, 255 - x, x);
  }
  // Write the colors to the LED strip.
  ledStrip.write(colors, LED_COUNT);
  delay(10);
}

// Make the LED strip shine as rainbow
rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v)
{
  uint8_t f = (h % 60) * 255 / 60;
  uint8_t p = (255 - s) * (uint16_t)v / 255;
  uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255;
  uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255;
  uint8_t r = 0, g = 0, b = 0;
  switch ((h / 60) % 6) {
    case 0: r = v; g = t; b = p; break;
    case 1: r = q; g = v; b = p; break;
    case 2: r = p; g = v; b = t; break;
    case 3: r = p; g = q; b = v; break;
    case 4: r = t; g = p; b = v; break;
    case 5: r = v; g = p; b = q; break;
  }
  return rgb_color(r, g, b);
}

void loop() {

  springFallButtonValue = digitalRead(SPRINGFALLBUTTON);
  summerButtonValue = digitalRead(SUMMERBUTTON);
  winterButtonValue = digitalRead(WINTERBUTTON);
  resetButtonValue = digitalRead(RESETBUTTON);

  // Spring Mode
  if (digitalRead(SPRINGFALLBUTTON) == LOW) {
    tshirtDressNumber = random (1, 10);
    jacketDressNumber = random (10, 20);
    pantsDressNumber = random (6, 10);
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("   Season:S/F   ");
    lcd.setCursor(0, 1);
    lcd.print("  T:");
    lcd.setCursor(4, 1);
    lcd.print(tshirtDressNumber);
    lcd.setCursor(5, 1);
    lcd.print(",J:");
    lcd.setCursor(8, 1);
    lcd.print(jacketDressNumber);
    lcd.setCursor(10, 1);
    lcd.print(",P:");
    lcd.setCursor(13, 1);
    lcd.print(pantsDressNumber);
    lcd.setCursor(14, 1);
    lcd.print("  ");

    //LED displays randomly selected clothing colors
    if ((tshirtDressNumber <= 5) && (jacketDressNumber <= 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber <= 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber > 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber > 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber <= 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber <= 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber > 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber > 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 10; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 10; i < 20; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 20; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }
  }

  // Summer Mode = T-shirt + Shorts
  if (digitalRead(SUMMERBUTTON) == LOW) {
    tshirtDressNumber = random (1, 10);
    shortsDressNumber = random (1, 6);
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print(" Season:Summer  ");
    lcd.setCursor(0, 1);
    lcd.print("T-shirt:");
    lcd.setCursor(7, 1);
    lcd.print(tshirtDressNumber);
    lcd.setCursor(8, 1);
    lcd.print(",shorts:");
    lcd.setCursor(15, 1);
    lcd.print(shortsDressNumber);

    //LED displays randomly selected clothing colors
    if ((tshirtDressNumber <= 5) && (shortsDressNumber <= 2)) {
      for (uint16_t i = 0; i < 15; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 15; i < 30; i++)
      {
        colors[i] = rgb_color(230, 230, 0);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (shortsDressNumber > 2)) {
      for (uint16_t i = 0; i < 15; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 15; i < 30; i++)
      {
        colors[i] = rgb_color(255, 0, 70);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (shortsDressNumber <= 2)) {
      for (uint16_t i = 0; i < 15; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 15; i < 30; i++)
      {
        colors[i] = rgb_color(230, 230, 0);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (shortsDressNumber > 2)) {
      for (uint16_t i = 0; i < 15; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 15; i < 30; i++)
      {
        colors[i] = rgb_color(255, 0, 70);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }
  }

  // Winter Mode = T-shirt + Jacket + Winter Coat + Pants
  if (digitalRead(WINTERBUTTON) == LOW) {
    tshirtDressNumber = random (1, 10);
    jacketDressNumber = random (10, 20);
    winterCoatDressNumber = random (20, 26);
    pantsDressNumber = random (6, 10);
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print(" Season:Winter  ");
    lcd.setCursor(0, 1);
    lcd.print("T:");
    lcd.setCursor(2, 1);
    lcd.print(tshirtDressNumber);
    lcd.setCursor(3, 1);
    lcd.print(",J:");
    lcd.setCursor(6, 1);
    lcd.print(jacketDressNumber);
    lcd.setCursor(8, 1);
    lcd.print(",C:");
    lcd.setCursor(11, 1);
    lcd.print(winterCoatDressNumber);
    lcd.setCursor(13, 1);
    lcd.print(",P");
    lcd.setCursor(15, 1);
    lcd.print(pantsDressNumber);

    //LED displays randomly selected clothing colors
    if ((tshirtDressNumber <= 5) && (jacketDressNumber <= 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber <= 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber > 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber <= 5) && (jacketDressNumber > 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(250, 110, 0);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber <= 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber <= 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(0, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber > 15) && (pantsDressNumber <= 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(0, 155, 155);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    if ((tshirtDressNumber > 5) && (jacketDressNumber > 15) && (pantsDressNumber > 7)) {
      for (uint16_t i = 0; i < 7; i++)
      {
        colors[i] = rgb_color(0, 250, 130);
      }
      for (uint16_t i = 7; i < 15; i++)
      {
        colors[i] = rgb_color(170, 0, 255);
      }
      for (uint16_t i = 15; i < 22; i++)
      {
        colors[i] = rgb_color(160, 160, 160);
      }
      for (uint16_t i = 22; i < 30; i++)
      {
        colors[i] = rgb_color(255, 255, 255);
      }
      // Write the colors to the LED strip.
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }
  }

  // Reset Button, there will be a little surprise if you keep pressing reset button!
  if (digitalRead(RESETBUTTON) == LOW) {
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Digital  Stylist");
    lcd.setCursor(0, 1);
    lcd.print("Have a nice day!");

    // Update the colors.
    uint16_t time = millis() >> 2;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      byte x = (time >> 2) - (i << 3);
      colors[i] = hsvToRgb((uint32_t)x * 359 / 256, 255, 255);
    }

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

 

Jianxiao Ge

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/digital-stylist/feed/ 0
Don’t Chew Your Nail https://courses.ideate.cmu.edu/60-223/f2018/work/dont-chew-your-nail/ https://courses.ideate.cmu.edu/60-223/f2018/work/dont-chew-your-nail/#respond Thu, 25 Oct 2018 19:05:12 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4588 Don’t Chew Your Nail

The glasses helps people stop chewing their nails by warning them with a vibrator when their hands come to close to their faces.

Detailed look of the glasses

Overview of the glasses that helps you stop chewing nails

 

 

Inside of the glasses

Look of Vibrator from the Outside

Tape for hiding wires has Consistent Color With the glasses Frame

How the glasses work

  1. Wear the glasses
  2. Try to chew your nail
  3. The vibrator of the glasses starts vibrating

Decision Points in the Design Process

First Decision Point: IR Proximity Sensor to IR Distance Ranger

Initially my design was to use the infrared proximity sensor, since it is small and fit good onto a glasses. Yet after testing on the breadboard, I figured out that the proximity sensor is only sensible to items around 5 centimeters away from it, which is shorter than the distance from my eyes to my mouth.

The initial design was to use the IR proximity sensor

Thus, I researched online the sensor distance for all available distance sensors in the lab and it turned out that IR distance ranger is able to detect items 20 centimeters away from it. Thus, I changed my design, even though IR distance ranger will look larger than the proximity sensor.

Later design changed to use IR ranger

Second Decision Point: From 9v Battery to 6v button Batteries

Change to the button battery

Initially, I made use of 9v amazon battery, yet later on I changed to use battery buttons which are easier to hide and significantly lighter.

Other process Images

Try to solder wires onto Arduino nano

Try to record the correct position of sensor I finally got by a lot of trials

Discussion

Response

Critique One: Hide the mechanical part better

“Use a better containment to hold wires/sensors.”

“It would look better if the sensors can be hidden.”

“Think of making aesthetic improvements to your sunglasses, especially since you would be wearing them everyday.”

I agree that I need to make improvement to the look of the glasses by hiding mechanical parts better. The overall look of the glasses could have been largely improved if I have drilled holes through the glasses and pull wires through the interior of the glasses. However, because of the limitation of time and some wires needed to be re-soldered frequently, that failed to achieve finally.

Critique 2: Good use of sensors for detection

“Cool use of sensors”

“Two sensors: great way to detect the motions”

Besides using two sensors for detection,  I also need to figure out the orientation of both sensors so that they can be directed towards user’s mouth. This turned out to be tons of trials and errors and since I used tape to hold the sensors, it took me some time to fix sensors towards a certain direction to prevent them from turning away as the tape looses.

Self-critique

I really need a device to solve my nail chewing problem, so the idea behind the project was good initially. However, the sunglasses is not something wearable for daily life, especially not in winter of Pittsburgh. Yet, the sunglasses is a good choice for simply demo of the concept, since it is cost effective and reduces the difficulty of hiding wires with its large frame. Another problem is that I should have hided wires better by cutting and drilling the glass frame, so I can get rid of tapes on the glasses. Before the critique, when I resolved to use tapes because I needed to re-solder the Arduino frequently, I chose to use tapes that have consistent color with the glasses to hide wires below them better.

Also, in retrospect,  I could have done better with soldering. My project eventually failed to work because several wires broke just before the critique. Now, I realized that probably I should have used softer wires to connect different components on Arduino. Specifically, when I tried to connect the button battery to the Arduino, I used wires so hard that they frequently broke free of the soldering tin that wrapped around them.

What I Learned

What I learned about soldering is mentioned in the self-critique. Apart from that, another thing I learned is to make better management of time. Setting milestones for my project could have saved me more time to make better fabrication in my project.

Next steps

The next step will be changing from the sun glasses to glasses with lenses fitting to my eyes. To achieve this, I should re-solder my Arduino nano and figure out a working configuration for holes to contain wires on  the sunglasses. Then, I can redo the fabrication that I have done to the sunglasses to a normal glasses and transfer the chip to the normal glasses.

Schematic

“Don’t Chew Your Nail” Schematic

 Code

/*
 * Author: Caroline Sun
 * Description:
 * the code takes input from 2 distance sensor
 * and turns on the vibrator only when the object 
 * is close to both sensors
 */

int DISTANCEPIN = A3;
int DISTANCEPIN2 = A0;
int VIBRATORPIN = 11;
int LIGHTPIN = 13;

//Initialization
void setup() {
  pinMode(DISTANCEPIN,INPUT);
  pinMode(DISTANCEPIN2,INPUT);
  pinMode(VIBRATORPIN,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int dis = analogRead(DISTANCEPIN);
  int dis2 = analogRead(DISTANCEPIN2);
  Serial.println(dis);
  //Only start the vibrator if the hand is at the middle of the face
  if(dis>200 && dis2>200){ 
   digitalWrite(VIBRATORPIN,HIGH);
   digitalWrite(LIGHTPIN,HIGH);
  }
  else{
   digitalWrite(VIBRATORPIN,LOW);
   digitalWrite(LIGHTPIN,LOW);
  }
  delay(20);
  
  
}
]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/dont-chew-your-nail/feed/ 0
Laptop Light Extension https://courses.ideate.cmu.edu/60-223/f2018/work/laptop-light-extension/ https://courses.ideate.cmu.edu/60-223/f2018/work/laptop-light-extension/#respond Thu, 25 Oct 2018 18:35:33 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4254 This device changes color after set periods of time to encourage laptop users to look away from their screens.

Images of Project

3/4 view of project.

Front view of the light.

The hardware of the project–Arduino and accelerometer screwed into the acrylic band.

Side view of the project.

Example of use.

Process images and review

One of the hardest decisions I had to make was how to display the light in a way that was not distracting and was seamlessly integrated into the product. I had a few ideas for this, such as having the light strip on the sides of the laptop or have the light pop out either through a motor or having the user physically pull the lights out after every use. However, the first idea would not allow the laptop to close and the second idea was interfering with the user’s interaction of the actual laptop. Thus, having light emitted from the top of the laptop through a waveguide was the best way to display light while also maintaining normal interaction with a laptop and allowed the design to be integrated into the design of the case without much interference.

One of the initial ideas for how light is displayed, however this gets in the way of the functionality of the laptop when closing.

A second challenge was to decide the light pattern that would not distract the user, yet still effectively alerts the user to look away. I played around with the whole rainbow– which would have gone from red to orange to green to blue to green to orange and back to red. However, this didn’t make sense because the light patterns repeat. Thus, I decided to do half the rainbow, from blue to red. I chose blue to be first because red was more of an attention-grabbing color. This was still challenging to decide because blue light tires the eyes as well, making both colors have drawbacks as the initial light color. However, after testing this range from blue to red on my own eyes I decided that it was more important to have the end color be attention-grabbing.

Red light working on the LED strip.

Draft of the waveguide, without securing the accelerometer and Arduino into the acrylic.

Discussion

Response to Critique

“Ending with red light definitely gives an alarming feel. What if yours started from a soothing light and it would slowly turn to red? (Or dim red/pink -> bright red) Because there are blue light filters because blue lights tire your eyes. Having lights at the other end of the acrylic is so cool. It’s like you made a light cable but in a curved plane.”

I agree that the range of lights is alarming and bright. The whole point of the shape of this project was to keep the device subtle and non-evasive, however, the lights are striking to the eye. I think a good way to fix this would be to change the range of lights and dim it down. The lights don’t have to iterate through the entire color spectrum, instead, it could range from a specific and more friendly set of colors.

“Front facing aesthetics are great! A simple line of light. Perhaps think about what people can change about the color(RGB, brightness, etc). Definitely consider how to mount it to any possible laptop. Think about an adjusting timer via hardware.”

I think that this is a good idea for personalization! I think that being able to change the range of color and the brightness of the light will definitely add to the project. Also, an adjusting timer is a good idea for when people want to focus on different amounts of time. For example, if I had an assignment due soon I would adjust the timer for it to be a longer period of focus, whereas if I am just watching Netflix the timer could be shorter to prevent eyestrain.

“The lights are a bit bright–somehow covering them would help (instead of clear acrylic, white? fewer LEDs? Maybe think of a way to improve the aesthetic on the back? So that the laptop can close comfortably without looking or feeling odd. Case idea sounded cool. “

I think the case idea is a good way to integrate the project into a product. Had the Arduino and accelerometer been embedded into a case, then the back hardware would be seamless and there would be no wires and blue tape. This would improve the aesthetics and the ease of use of the product. I also agree that the lights are bright, tying in with the previous critique, the brightness of the light could be adjustable.

Self-critique of Project

I am happy with how the project turned out. I wanted a device that would allow me to see how long I was using my laptop screen in a subtle way that did not interfere with how I used my laptop and this project accomplishes that. I did end up using my project in class and I found myself catching when the light turned red and looking away from my screen for a few minutes. I think had the hardware been integrated into a fitting laptop case, I would use this project in my day to day life.

What I Learned

Taking in the critique from Project 1, I wanted to incorporate a better presentation for this project. With this in mind and clear acrylic’s light-bending property, I decided to learn more about how to use this versatile material. I learned some basics of laser cutting through the people who manned the laser cutting lab including how to create the shape, transferring the shape file to a physical plastic cutout, and how to process the acrylic afterward to reduce burning. After having the cut of acrylic, I learned how to manipulate my cut shape to best fit my project. I used a heat gun and clamp to bend the rectangular plastic into an “L” shape. I also learned how to create a waveguide, which was an essential part of this project. After numerous attempts at creating the optimal way to incorporate the light, I found that I had to think outside of the box to achieve my goal.

In the next iteration of this project, I would take the advice from my critique to add more user controls such as light pattern and the timer. This would be much better because everyone’s attention span is different and are sensitive to different types of light. This would also allow the user to experiment with what kind of timing or light pattern works best for them, making the device more personalized. Also, I would have made the prototype more production ready and embed the Arduino and Accelerometer more securely into the acrylic without free wires on the back. Instead of an attachment, I could integrate the Arduino and the light into a laptop case instead of having it as an attachment. This would encourage use because it would be a much more seamless and durable design.

Technical information

Schematic for Light Extension

/*
 * Laptop Light Extension
 * Jenny Han (jennyh1)
 * 
 * Based on the angle that the accelerometer, the code determines whether or 
 * not the laptop is at an angle that the user is looking at the screen. 
 * If the user is not, then the light turns off and the program resets. 
 * If the user is, then the program runs code to change the light pattern 
 * of the LED strip over the course of a set time.
 * 
 * Referenced from ADAFruit NeoPixel example "buttoncycler"
 * Referenced from https://github.com/infomaniac50/ADXL335/blob/master/examples/ADXL335_Demo/ADXL335_Demo.pde
 */
 
#include <ADXL335.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6
unsigned long timer = 0;


Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

//pins for the ADXL chip
const int pin_x = A0;
const int pin_y = A1;
const int pin_z = A2;
const float aref = 3.3;
int counter = 127;

ADXL335 accel(pin_x, pin_y, pin_z, aref);

void setup()
{

  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  
  Serial.begin(9600);
  //prints out the angles that the ADXL senses
  Serial.println("X,\tY,\tZ,\tRho,\tPhi,\tTheta");
  strip.begin();
  strip.show();
  rainbow2(1,counter);
}

void loop()
{
  //this is required to update the values
  accel.update();
  
  //this tells us how long the string is
  int string_width;

  float x;
  float y;
  float z;
  
  //for these variables see wikipedia's
  //definition of spherical coordinates
  float rho;
  float phi;
  float theta;  
  
  x = accel.getX();
  y = accel.getY();
  //if the project is laying flat and top up the z axis reads ~1G
  z = accel.getZ();
  rho = accel.getRho();
  phi = accel.getPhi();
  theta = accel.getTheta();
  //prints out different position angles
  Serial.print(formatFloat(x, 2, &string_width));
  Serial.print(",\t");
  Serial.print(formatFloat(y, 2, &string_width));
  Serial.print(",\t");
  Serial.print(formatFloat(z, 2, &string_width));
  Serial.print(",\t");
  
  Serial.print(formatFloat(rho, 2, &string_width));
  Serial.print(",\t");
  Serial.print(formatFloat(phi, 2, &string_width));
  Serial.print(",\t");
  Serial.print(formatFloat(theta, 2, &string_width));
  Serial.println("");
  
  //if vertical angle is less than 128, then the laptop is on
  if (theta<128 ){
    Serial.println("on!");
    if (millis() - timer >= 500 ){    // 30000 ~ 60 minutes
    // this happens once per second
      timer = millis();
      //run colors on LED Strip
      rainbow2(1,counter);
      Serial.println(counter);
      if(counter==0){
        Serial.println("keep");
      } else {
        counter--;
      }
    
    }

  } else {
    //turn it off
    Serial.println("off!");
    counter = 127;
    colorWipe(strip.Color(0, 0, 0), 10);    // Black/off
    
  }
  delay(1000);
}
//run color pattern, a rainbow strip
void rainbow2(uint8_t wait,int j2) {
   uint16_t i;
    //set color for every led in strip
    for(i=0; i<strip.numPixels(); i++) {
      //strip.setPixelColor(i, Wheel((i+j) & 255));
      strip.setPixelColor(i, Wheel((j2) & 255));
      delay(wait);
    }
    strip.show();
    delay(wait);
}
//removes color when turned off
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}
//helper function to set color of strip
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

//this function was taken from my format float library
//used to make the angles taken from the ADXL human readable
String formatFloat(double value, int places, int* string_width)
{
  //if value is positive infinity
  if (isinf(value) > 0)
  {
    return "+Inf";
  }
    
  //Arduino does not seem to have negative infinity
  //keeping this code block for reference
  //if value is negative infinity
  if(isinf(value) < 0)
  {
    return "-Inf";
  }
  
  //if value is not a number
  if(isnan(value) > 0)
  {
    return "NaN";
  }
  
  //always include a space for the dot
  int num_width = 1;

  //if the number of decimal places is less than 1
  if (places < 1)
  {
    //set places to 1
    places = 1;
    
    //and truncate the value
    value = (float)((int)value);
  }
  
  //add the places to the right of the decimal
  num_width += places;
  
  //if the value does not contain an integral part  
  if (value < 1.0 && value > -1.0)
  {
    //add one for the integral zero
    num_width++;
  }
  else
  {

    //get the integral part and
    //get the number of places to the left of decimal
    num_width += ((int)log10(abs(value))) + 1;
  }
  //if the value in less than 0
  if (value < 0.0)
  {
    //add a space for the minus sign
    num_width++;
  }
  
  //make a string the size of the number
  //plus 1 for string terminator
  char s[num_width + 1]; 
  
  //put the string terminator at the end
  s[num_width] = '\0';
  
  
  //initalize the array to all zeros
  for (int i = 0; i < num_width; i++)
  {
    s[i] = '0';
  }
  
  //characters that are not changed by 
  //the function below will be zeros
  
  //set the out variable string width
  //lets the caller know what we came up with
  *string_width = num_width;
  
  //use the avr-libc function dtosrtf to format the value
  return String(dtostrf(value,num_width,places,s));  
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/laptop-light-extension/feed/ 0
Semi Hi-Tech Backpack https://courses.ideate.cmu.edu/60-223/f2018/work/semi-hi-tech-backpack/ https://courses.ideate.cmu.edu/60-223/f2018/work/semi-hi-tech-backpack/#respond Thu, 25 Oct 2018 18:31:05 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4475

The LEDs poking out indicate if the chargers are inside my backpack in an organized fashion.

This backpack lets me know if I have the chargers I need in my backpack by lighting up the LEDs on the top and forces me to organize them at the same time.

Front view of the Semi Hi-Tech Backpack

Overview of the electronics inside the backpack

Wire for the pressure sensor on the bottom of the backpack runs down the side.

Wire connecting the pressure sensor is hidden using the side pocket.

 

Code for the project:

/*
Project Title: Semi Hi-Tech Backpack
Description: The project uses two RFID sensors to read RFID tags and compare it to the IDs of known tags. When the correct RFID tag is read by the reader, respective LEDs would turn on to indicate that the RFID tag has been sensed. This entire code will only run when the force sensitive resistor reads pressure, which is equal to when the backpack is put on the floor.

RST Pin 5
MOSI Pin 11
MISO Pin 12
SCK Pin 13
*/


//include libraries
#include <SPI.h>
#include <MFRC522.h>

//define important rfid reader pins
#define RST_PIN 5
#define SS_1_PIN 9 //same to reader 0
#define SS_2_PIN 10  //same to reader 1

//some necessary RFID stuff
#define NUM_OF_READERS 2

MFRC522 mfrc522[NUM_OF_READERS]; //Create MFRC522 instance

//set "simpler" pins
const int PRESSUREPIN = A0;
const int LED1PIN = 2;
const int LED2PIN = 3;

//"simpler" variables
int force;

void setup() {
  //Initiate SPI bus
  SPI.begin();

  //Initiate each MFRC522 card
  mfrc522[0].PCD_Init(SS_1_PIN, RST_PIN);
  mfrc522[1].PCD_Init(SS_2_PIN, RST_PIN);

  //set up "simpler" pins
  pinMode (PRESSUREPIN, INPUT);
  pinMode (LED1PIN, OUTPUT);
  digitalWrite (LED1PIN, LOW);
  pinMode (LED2PIN, OUTPUT);
  digitalWrite (LED2PIN, LOW);
}

void loop() {
  //read pressure
  force = analogRead(PRESSUREPIN);

  //IDs I'm looking for
  byte card1[4] = {69, 96, 94, 201};
  byte card2[4] = {181, 70, 94, 201};

  //backpack is resting on the floor 🙂
  if (force > 100) {
    //create variables for rfids that the reader finds
    byte readCard1[4];
    byte readCard2[4];

      //Sensing the stickers
      if (mfrc522[0].PICC_IsNewCardPresent() && mfrc522[0].PICC_ReadCardSerial()) {
        byte readCard1[4];
        for (uint8_t i = 0; i < 4; i++) { //put the id number that the reader found into the variable
          readCard1[i] = mfrc522[0].uid.uidByte[i];
        }
        //compare the wanted id and found id
        if (compareArrays(readCard1, card1)) {
          digitalWrite(LED1PIN, HIGH);
        }
      }
      if (mfrc522[1].PICC_IsNewCardPresent() && mfrc522[1].PICC_ReadCardSerial()) {
        byte readCard2[4];
        for (uint8_t i = 0; i < 4; i++) {
          readCard2[i] = mfrc522[1].uid.uidByte[i];
        }
        if (compareArrays(readCard2, card2)) {
          digitalWrite(LED2PIN, HIGH);
        }
      }
      
      //Halt PICC
      mfrc522[0].PICC_HaltA();
      mfrc522[1].PICC_HaltA();
      
      //Stop encryption on PCD
      mfrc522[0].PCD_StopCrypto1();
      mfrc522[1].PCD_StopCrypto1();
  }


  //if backpack is off the floor, reset every value
  else {
    digitalWrite(LED1PIN, LOW);
    digitalWrite(LED2PIN, LOW);
  }

}

bool compareArrays(byte array1[], byte array2[]) {
  for (int i = 0; i < 4; i++) {
    if (array1[i] != array2[i]) return false;
  }
  return true;
}

(Schematic photo)

Process

The problem I needed to solve was dealing with the monstrosity of chargers I carried everyday. I usually carry four chargers, which are for my laptop, iPad, cellphone, and wireless earbuds. I had to carry them all the time because otherwise it would be a painful day to have a laptop or phone not working. On top of that, unfortunately, none of the chargers were the same, so I had to carry four different wires which eventually tangled with each other and created a big mess in my backpack.

Chargers inside my backpack are all tangled up.

My initial idea was to create a small box in which I could organize all of my chargers inside. Since I had four wires, the idea was to have a RFID tag on each of the wires and have four RFID readers to sense that each wire has been placed in the right section of the box. The readers would look for the tag that they have been assigned to, and once they find the correct tag, they would turn on the LED on the outside and all I would need to grab would be the box with the LED lit up.

Initial idea for charger organizer box on the bottom right corner

It also involved exploring the RFID tags I could use, which ranged from cards and key fobs to little circular stickers.

But this seemed to be unnecessary and less rational at some point because if I had a box, all I would need to do is open it to check if I have all chargers. Plus, the smallest RFID tag I could find, the sticker, was still too large to put on a wire, which basically had no flat surface. The biggest problem I had to solve was if I always carry my chargers in my backpack, so creating another item that I potentially may forget to throw into my backpack seemed like it was not the ultimate solution. Thus, I had to come up with an alternative which would fundamentally tackle the situation.

Electronics incorporated into backpack, initial sketch

A new iteration was to incorporate the electronics into my backpack. The core objective was to make my backpack know if it had all of my chargers. So all I had to do was make the RFID readers a part of the backpack and have LEDs poke out so that I can see it easily without opening it. I was able to convince myself that this was plausible because; 1. by pure luck I learned that I could pierce through the fabric of the zippers with the LED; 2. I had pockets in my backpack that I never used but was large just enough that I would have to really force myself to organize the wires before I put them in; and 3. my backpack has a rather stiff box shape which would make it easier to organize and attach the electronics and keep them in place.

For the electronics I went through the process of learning how RFID readers and tags work, learning how to connect two RFID readers to one Arduino Uno, learning what code is used with the RFID readers, and then adding two more readers. I also realized that I may have battery issues if the LEDs were on all the time, so I also added a force sensitive resistor to the bottom of the backpack that would initiate the entire program when the FSR would be pressed by the backpack, which means when it is put down on the ground, and would reset the entire program when there is no pressure on it. In the midst of this, I ran into multiple problems in every facet, which can be summarized to:

  1. The function dump_byte_array that was used in an example sketch was difficult to decipher and mold into the way I wanted to code to run. I tried multiple ways I could think of but it just simply did not give the output that I wanted it to. This was harder especially when I had two readers. I could already know that if I could not figure it out with two readers, I definitely would not be able to do it with four readers.
  2. Connecting four RFID readers and two controlled LEDs to one Arduino Uno board was rough. I was basically running out of pins. Even when I shared every pin that could be shared, I was using all of the digital pins with a bunch of wires, which would be difficult to organize in my backpack.

    Four RFID readers involved lots of wires and lots of pins.

  3. Placing four RFID readers in my backpack also became an issue. My backpack has one big pocket and two smaller pockets, so I was planning to divide the big pocket and place one reader in each pocket, but that meant some readers could possibly overlap with each other, which sometimes made the entire electronics stop working.
  4. I still had the problem of putting a circular sticker on wires which had no big enough surface to put the sticker on.

To resolve this, I decided to stick to two RFID readers and two RFID tags only. One tag was put on my laptop charger and the other was put on an adaptor where I could plug all three of my chargers into one outlet. This simplified the electronics immensely and also solved the problem of placing an RFID tag on each charger.

Refined sketch of two RFID readers and a pressure sensor on the bottom

Resolved to two RFID readers with two LEDs and an FSR

Discussion

As for the final product, I am proud of how I incorporated electronics into a pre-existing object but frustrated about the ‘finicky’ nature RFID readers. As I was planning and sketching for the final product, I did expect that I inevitably would have to solder electronics while they are inside my backpack, regardless of planning the wire plot as much as I can.

Soldering as wires are piercing through the backpack’s fabric

I definitely would allocate more time into soldering things because it took more time than I expected. I think I focused too much on the code, which was also difficult not to mention. The physical restraints of soldering very close to fabric or soldering in a smaller space were potentially dangerous (and I was very nervous about it too), but in the end I soldered everything into place without causing any hazards or resulting in any unconnected electronics. This success allowed my backpack, the project, to look really natural from the outside, and this specifically brought a lot of positive feedback such as; “Super minimalistic and subtle but still gets the job done!”, “From the outside your backpack looks normal, which is cool too”,  and “really cool how you integrated it into the backpack and you can’t see any wires from the outside!” I’m particularly glad and proud that the majority of the feedback I received was about how it was integrated nicely into the object.

There also was a followup feedback about tidying the inside saying “maybe make wires on inside neater?” and “For very far off improvement, it would be cool if it was weather-proof. Since you put a lot of items inside your backpack, I’m worried about durability”, which I totally agree on. This falls into my initial wish of allocating more time into soldering and tidying up the insides. The wires in the current state do get in the way, so I would need to do a better job on sewing the wires more tightly and tucking them away to a corner.

For the frustration with the readers, I want to research more into it and find a way to fix it. The sad part for the critique was that it did not work, and I was tired of it. So, the RFID readers apparently would ‘get tired’ (as I like to call it) after a few runs of reading the tags. It would work perfectly as intended, but all of a sudden it would not respond. And when I ran the example code for using two readers, the serial feedback would say that communication failed and I would need to check the connection. The problem was odd because if I switched out the reader to a different one several times, then it was fine. When the new reader ‘got tired’ and I switched it back to the first reader I was using, it would work perfectly fine again. After I soldered everything the same problem happened, and this time it was much harder to switch out the readers because they were supposed to be tucked away inside the deep pocket. I really want to fix this part and make it work without any weird stops.

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/semi-hi-tech-backpack/feed/ 0
Help I’m Falling Asleep and Can’t Wake Up https://courses.ideate.cmu.edu/60-223/f2018/work/help-im-falling-asleep-and-cant-wake-up/ https://courses.ideate.cmu.edu/60-223/f2018/work/help-im-falling-asleep-and-cant-wake-up/#respond Thu, 25 Oct 2018 18:25:32 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4487 Description

This device wakes me up when it detects that I am falling asleep while doing my work.

Final Product

The device in use: the device makes a sound and lights up when I start falling asleep.

Overall photo: there is a box with an LED, button, and knob on the outside, with a speaker, battery, and Arduino on the inside.

A close-up of the little “hair-clip” that contains the accelerometer.

Close up of some of the box’s exterior: There is a calibration button and a sensitivity adjuster.

Device in use: I am falling asleep and the device will wake me up with a noise.

The Process

The electronic components on a breadboard for testing the wiring. I decided to add a potentiometer to control the sensitivity and a button to calibrate the accelerometer to my initial design.

After soldering everything to the breadboard and Arduino. I also covered the exposed wires with electrical tape. Mesuring the position and size of everything for laser cutting the casing took longer than I thought.

Soldering was a time-consuming process, the wires that I tried to solder to the Arduino kept becoming detached from it. I had to keep soldering the wires back on.

It was a tight fit putting everything into the laser cut box, had to cut out the parts multiple times. You can see one of the wires from the Arduino got detached again.

This was the first time laser cutting anything by myself so there was some trial and error: I forgot to take into account the thickness of the acrylic when doing initial measurements.

Discussion

For me, this project was a test of my own abilities from what I learned in this class so far. I didn’t want to make something overly complicated, but I also did not want to make something too “simple”.  In a way, the principle of this was very simple: you move the accelerometer, the box notifies you when it moves out of range. However, I added some additional features like a calibration button and a sensitivity button to the initial design, after some feedback.

I’m happy with what I did within the limitations of what I was capable of doing, but I regret not asking about things that I didn’t know about, such as a louder speaker, or making the accelerometer wireless. I got some feedback that “maybe the cord should be longer” and that I “could make the sensor wireless,” and if I asked about making the sensor wireless maybe I could have found a solution to that. I wish I had been more creative in the process and curious, not just sticking to what I know would work.

One major problem I encountered was that the speaker was not loud enough. I should have asked about making the speaker louder, but for some reason I didn’t, probably because I was running out of time. I think it was louder when I had it on the solderless breadboard and then I’m not sure why, but the sound was very tiny when I soldered everything to a breadboard. At that point I probably got too lazy to change anything because I had already soldered everything. A feedback I received was to put a vibration as well as a sound, which I thought could be an improvement as well.

As for the aesthetics of my design, most of the feedback from my peers included a note about how they liked the appearance and design of it, how clean and simple it was. People said “very clean design for the interface,” “I like the box to hide the electronics,” “love how well it’s all contained… [and] the aesthetic choices,” and “I think that it’s very polished. Although it was my first time laser cutting by myself, I learned a lot about laser cutting and designing a laser-cut casing through trial and error. All that time I put into the outside seemed to pay off, since I got a lot of positive feedback for it. I should have made it a little more roomy on the inside, but I mistakenly just took my initial measurements of the breadboard and arduino and didn’t add any more room to that, not taking into account the wires and everything I would have to put inside. Fortunately, after cutting a few more times, I got a larger box. However, because I had only bought one sheet of 1×1 acrylic and finished cutting right before class, I was only able to make some parts of the box larger, so it was still a tight fit. Because everything was so tight, it would sometimes mess up the wiring. As painstaking as it is, I would want to make myself a new box if I were to use this regularly, and perhaps make the calibration button bigger.

Schematic

Code

//Help I'm Falling Asleep
//This code turns an LED and speaker on when the accelerometer values
// go out of bounds, set by a potentiometer.

const int XPIN = A0;
const int YPIN = A1;
const int ZPIN = A2;
const int LED2 = 2;
const int BUT = 3;
const int SPKR = 9;
const int POT = A3;
int setX;
int setY;
int setZ;
int bound = 30;

void setup() {
  pinMode(XPIN, INPUT);
  pinMode(YPIN, INPUT);
  pinMode(ZPIN, INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BUT, INPUT_PULLUP);
  pinMode(POT, INPUT);
  Serial.begin(9600);
  setX = analogRead(XPIN);
  setY = analogRead(YPIN);
  setZ = analogRead(ZPIN);
  digitalWrite (LED2, LOW);
}

void loop() {
  int butState = digitalRead(BUT);
  int led2State = digitalRead(LED2);
  int x = analogRead(XPIN);
  int y = analogRead(YPIN);
  int z = analogRead(ZPIN);
  int potVal = analogRead(POT);
  bound = potVal/10;//sets value of bound from potentiometer
  Serial.println(bound);
  if(butState == LOW){//when button is pressed, turn off LED, calibrate current position to the "initial" position.
    setX = x;
    setY = y;
    setZ = z;
    digitalWrite (LED2, LOW);
  }
  
  if(butState == HIGH){//when button is not being pressed
    if(x > (setX + bound) || x < (setX - bound) ||//if accelerometer goes out of bounds, turn LED and speaker on
    y > (setY + bound) || y < (setY - bound) ||
    z > (setZ + bound) || z < (setZ - bound)){
      digitalWrite (LED2, HIGH);
      tone(SPKR,1000);
   }
   else{//turn off LED and speaker if not out of bounds
    digitalWrite (LED2, LOW);
    tone(SPKR, 0);
    }
  }
  //these are to make sure the potentiometer is working
  Serial.print(x);
  Serial.print(" ");    // spaces between values to separate them
  Serial.print(y);
  Serial.print(" ");
  Serial.println(z);     // line break only needed after the final value
  delay(50);
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/help-im-falling-asleep-and-cant-wake-up/feed/ 0
Project 2: Jar of Change https://courses.ideate.cmu.edu/60-223/f2018/work/project-2-jar-of-change/ https://courses.ideate.cmu.edu/60-223/f2018/work/project-2-jar-of-change/#respond Thu, 25 Oct 2018 18:25:10 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4269 Instead of getting stuck in the same cycle every day, Jar of Change is here motivate you into taking the first step out of your comfort zone!

Photos of the Final Project

Jar of Change sequencing through the orange mode

Overall photo for proportion and scale

Overall photo for proportion and scale

The inside of the jar looks empty despite containing the LEDs due to a second layer of mylar on the other side of the LED strip

The Hall Sensor’s wiring is hiding under the mylar film and (hopefully) inconspicuous but close enough to the magnet to be triggered

The LCD display showing different messages, words of encouragement or ideas for change, depending on the time counter

 

 

 

Images of the Jar of Change being used

Process Images and Review

In this project, one major decision point I faced was when I realized that the LED lights on the outside of the jar was too bright. I experimented with a few different configurations and combinations, ultimately deciding  that the best combination was to put them on the inside of the jar. I used mylar film to cover the outside of the jar in an attempt to diffuse them and I’d hoped to create an interesting effect with the mirroring and diffusing of light. I was trying to achieve a something similar to the effect of Yayoi Kusama’s work with infinity mirrors, in a much smaller scale.

Jar of Change with lights on the outside

I’m not sure exactly why this didn’t work out but it was either because the mylar film didn’t exactly work like the one-way mirror effect I was looking for (both sides of the film appeared to reflect evenly versus the inside reflecting while the outside peers in without environmental light disrupting the effect) or the distance between the lights and the film were not enough. I had no experience with one way film, only one way mirrors and there’s not much I can do about increasing the distance between the glass and mylar without compromising the jar’s ability to store stuff so I didn’t bother to venture down that path. The reflectivity of the mylar had a cool effect and it did manage to mute the LEDs a bit which was my main goal, being someone who’s quite sensitive to light.

As a result of my decision to place the lights inside the jar, I had to figure out how to run the current from the outside of the jar where the Arduino and power supply is to the inside of the jar where the lights were when the lid is on. Zach advised I try using copper tape and though I had some frustrating first attempts, the lights were actually quite reliable after a while, as long as the lid wasn’t screwed on too tight.

Testing the copper tape with the mylar partially undone for better access to the wires on the outside

The second big decision point was when I was debating the design of the “box” to hold the Arduino and some other electronic connections. First I estimated the amount of space needed by testing it with some scrap cardboard.

Testing with cardboard to accommodate LCD display, arduino, and other electronic parts

After getting the measurements for that, I made some sketches of the initial design. I wanted to make the based a circle to match the shape of the jar. I had the thought of using the mirrored acrylic to reflect the light and attempt to amplify it’s effects/create interesting, non-standard views. I had the idea of using ripples of water (whether etched or moving outward) to further emphasize the shape of the container.  I planned for the bottom to be made of two parts that could combine to form one piece or come apart in case something messed up with the wiring. I wanted holes to run both the data cable from the computer to the arduino and from the 5V power supply to the LEDs.

Sketch of original arduino container idea

 

I first tried to Rhino model waves that would be made from stacked slices of mirrored acrylic. I was worried after a while about how much it would reflect facing up, how noticeable the wave effect would be, and how much mirrored acrylic I would be buying under the class budget (I didn’t want to waste too much money on something not vital to the functionality).

Then I attempted to try a few different methods of making the wave, the most notable being one with slices that would rotate around the jar with acrylic pieces that laid on it to reflect the light back at the jar.  That method, though it would have been the most clear version of a wave, would have required at least a 2′ x 2′ piece of acrylic and I didn’t want to waste ~$25.

At the time I came to this conclusion, it was very late at night/early in the morning and the only piece that I’d laser cut had been the base (where the LCD display would be embedded and the jar would sit on top of) . I had an idea out of the blue to surround the jar with mirrored acrylic pieces following the rough pattern of the etched ripples on the surface to give a slight field of mirrors effect. The taller pieces would be around the LCD screen since that is the “top” of piece, farthest away from where my vantage point is. I was trying to explore the different views of the LEDs reflecting off the mirrors which was pretty successful on the brightest mode (rainbow lights) but still noticeable with the more subtle modes. Unfortunately I started building the box after I soldered the wires into the 5V power source and jar. I really did not want to have to redo any of those, especially since both are quite finicky so I just covered the wires with grey tape and ran them down the side, to where the Arduino was located. It doesn’t look the best visually but I made the most of it.

Reflections off the mirrored acrylic in the purple portion of the rainbow mode

Reflections off the mirrored acrylic in the white portion of the orange mode

Ultimately I wish I spent less time on this and more on the project itself because maybe then I wouldn’t have overslept and not had the proper time to debug my code. Looking back, if I had more time, I would have made the form underneath (what holds the Arduino and other electronic components) better, I was sleep deprived while doing it. Ultimately it does have a nice angled effect that communicates with the mirrored panels on top, and is rarely seen from most views (shown in the photo below). I also would have like to experiment with different mirror panel height instead of just two. A possible venture of inquiry would have been using normal clear acrylic and covering them to mylar film to see how the effect would turn out. While taking the final photos, I realized it’s quite sad that the mirrored acrylic is opaque, blocking out the views of the lights. With mylar, the lights would be reflected in the back panels while the front panels could still be partially seen through.

Discussion

During the in class discussion, I was given a critique that “maybe a voice recorder that records your voice so the interaction is short and sweet” would make the project function better. I actually thought the critique was great and something that I didn’t even think of while creating this project. Though I don’t know how difficult it would be to deal with a voice recorder/how to store the audio files, the idea of having audio recordings instead of physical objects is quite lovely in my opinion. The only restriction is that the hall sensor is not reliable enough to realize when the jar is opened and closed. Often times it’ll only trigger once in one open and close sequence (versus one when it opens, one when it closes) so the details would need to be flushed out but it would be a wonderful function to explore if I go about tackling this project again.

Another critique that was also interesting was one asking ,”Is there a way to enclose magnets? [So that there is a] streamline lid?” I’d already taken this issue into account prior and cut a piece of zip tie, painted it black, and connected it to the two magnets painted black to give the resulting piece the appearance of headphones/a handle. Unfortunately I didn’t have it during the in class demo because I accidentally left it in my room and had to makeshift hot glue new magnets onto the lid. I originally had the design of the magnets inside the jar and the hall sensor outside but it wouldn’t register through the jar so I had to move the magnets outside and disguise them in some way. Though this probably could have been solved with a different sensor, I didn’t have enough time to troubleshoot the problem.

I would say in terms of this project, my biggest takeaway was relearning the dangerous side effect of dreaming too big. The biggest reason why I didn’t have a functional demo was because I was having problems with a portion of my code that was doing some weird behaviors. I multiplied the millis() by 86400000 because the desired goal is that one second of real time would equal three days to the Arduino (10 real seconds = 1 arduino month) and 3 days x 24 hours x 60 min x 60 sec x 1000ms = 259200. But ultimately the number became too big and would cause problems.

While realistically this would be what happened if I were to make this project actually function over the course of a few months like I planned for, it was more than I needed for the demo. Unfortunately I realized that I should have given up on this pursuit too late. It also would have been an option to make the device go through the modes with 1 month being the most extreme (flashing red) since I would run into problems after around 38 days but I didn’t think about that until it came time to document the process. While I was extremely unhappy with the results of the demo, I am happy with the physical final result of the project.  I think with some small tweaks, this project can become a functional Jar of Change so that it can join my collection of strange light sources inside my bedroom.

As for the next step with this project, I would like to add a real time clock so that the Arduino can keep track of the time, even if there is a power shortage/the system gets turned off. I’d also need to change my code when I do that to get it to work with bigger numbers, probably storing them into some variable like days. It would also be a good idea to hook the Arduino up to a 9V battery at that point so the Jar of Change can work interdependent of my computer. If I feel really ambitious, I may even try to incorporate the voice recording function.

Schematic

Code Submission

/*

   60-223 Project 2 Code
   by Lexi Yan (yany1)
   Due Date: 10/18/18
   
   Code allows arduino to realize the passing of time, activating modes based off the time that changes the light
   patterns of the LEDs as well as the message being displayed on the LCD screen
   Pin 2 is the input for the hall sensor, pin 6 is the output for the LEDs

   Arduino Hall Sensor Code from https://maker.pro/arduino/tutorial/how-to-use-a-hall-effect-sensor-with-arduino
   NeoPixel code from Adafruit Neopixel example, strandtest
   LCD source code augmented from LiquidCrystal I2C library example, Hello World

*/



#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

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

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


#define PIN 6

volatile byte half_revolutions;
unsigned int rpm;
unsigned long timeold;
bool detected;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

// sets default state to rainbow (0), jar last opened time to 0
int state = 0;
unsigned long lastOpened = 0;

void magnet_detect()//This function is called whenever a magnet/interrupt is detected by the arduino
{
  half_revolutions++;
  detected = true;
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

// Warning color
void orange() {
  //Warning Colors
  colorWipe(strip.Color(244, 167, 66), 50); // Orange
  colorWipe(strip.Color(244, 220, 188), 20); // Light Orange
  colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
}

// Danger color
void red() {
  colorWipe(strip.Color(224, 21, 17), 50); // Red
  colorWipe(strip.Color(234, 155, 154), 20); // Pink
  colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
}

// Do something now color
void flash_red() {
  theaterChase(strip.Color(127, 0, 0), 50); // Red
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

void setup() {

  Serial.begin(9600);

  // Neopixels Initiating with all pixels off
  strip.begin();
  strip.show();

  // Hall Sensor Code
  attachInterrupt(0, magnet_detect, RISING);//Initialize the intterrupt pin (Arduino digital pin 2)
  half_revolutions = 0;
  rpm = 0;
  timeold = 0;


  
}

void messageDisplay(){

  // Less than 1 month messages
  if (state == 0){
    if (timeSec > 10){
      lcd.init();                      
      lcd.init();
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("Be confident");
      lcd.setCursor(2, 1);
      lcd.print("and happy Lexi");
    }
    
    else{
      lcd.init();                      
      lcd.init();
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("I beLEAF");
      lcd.setCursor(2, 1);
      lcd.print("    in YOU!");
  }}

  // 1 month messages
  else if (state == 1){
    if (timeSec > 30){
      lcd.init();                      
      lcd.init();
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("Chase your");
      lcd.setCursor(2, 1);
      lcd.print(" happiness");
    }
    
    else{
      lcd.init();                      
      lcd.init();
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("Be brave!");
      lcd.setCursor(2, 1);
      lcd.print("Take risks!");
    }
  }

  // 2 month messages
  else if (state == 2){
    if (timeSec > 50){
       // initialize the lcd
      lcd.init();                      
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("Let's code");
      lcd.setCursor(2, 1);
      lcd.print("  a project!");
    }
    
    else{
      // initialize the lcd
      lcd.init();                      
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("New hobby?");
      lcd.setCursor(2, 1);
      lcd.print("Join a class!");
    }
  }

  // 3+ month messages
  else{
    
    if (timeSec > 70){
      // initialize the lcd
    lcd.init();                      
    lcd.init();
    // Print a message to the LCD.
    lcd.backlight();
    lcd.setCursor(3, 0);
    lcd.print("Music");
    lcd.setCursor(2, 1);
    lcd.print("Festival?");
    }
    
    else if (timeSec > 80){
      // initialize the lcd
    lcd.init();                      
    lcd.init();
    // Print a message to the LCD.
    lcd.backlight();
    lcd.setCursor(3, 0);
    lcd.print("Meet new friends!");
    lcd.setCursor(2, 1);
    lcd.print("Learn a skill!");
    }

    else if (timeSec > 90){
      // initialize the lcd
      lcd.init();                      
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(3, 0);
      lcd.print("Explore a");
      lcd.setCursor(2, 1);
      lcd.print("new place!");
    }
    
    else{
      // initialize the lcd
    lcd.init();                      
    lcd.init();
    // Print a message to the LCD.
    lcd.backlight();
    lcd.setCursor(3, 0);
    lcd.print("Break out the");
    lcd.setCursor(2, 1);
    lcd.print("bucket list!");
    }
 
  }}
  
  

void loop() {

  //Set display message based on time
  messageDisplay();

  timeSec = (millis()/1000) - (lastOpened/1000);
 
  Serial.print(timeSec);
  Serial.println(" seconds");

  //When a minute (3 months) has passed, the red flashing state will be triggered
  if (timeSec >= 60 ){
    state = 3;
  }

  //When 40s (2 months) has passed, the red state will be triggered
  else if (timeSec >= 40 ){
    state = 2;
  }

  //When 20s (1 month) has passed, the orange state will be triggered
  else if (timeSec >= 20 ){
    state = 1;
  }

  //When it is under 20s, the rainbow state is active
  else{
    state = 0;
  }
  
  //If jar is opened: record time, set state to rainbow, turn detected off
  if (detected == true) {
    lastOpened = millis();
    state = 0;
    detected = false;
  }

  //flash light sequence depending on the current state
  if (state == 1) {
    orange();
  }
  else if (state == 2) {
    red();
  }
  else if (state == 3) {
    flash_red();
  }
  else {
    rainbow(20);
  }

  //Measure RPM for Hall Sensor
  if (half_revolutions >= 20) {
    rpm = 30 * 1000 / (millis() - timeold) * half_revolutions;
    timeold = millis();
    half_revolutions = 0;
    //Serial.println(rpm,DEC);
  }
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/project-2-jar-of-change/feed/ 0
Assistive Device: Walk the Walk https://courses.ideate.cmu.edu/60-223/f2018/work/assistive-device-walk-the-walk/ https://courses.ideate.cmu.edu/60-223/f2018/work/assistive-device-walk-the-walk/#respond Thu, 25 Oct 2018 18:21:40 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4194

An overall shot of how the device would be used with the handheld display device, the anklet and the sensors in the shoe.

Narrative

This project uses 7 pressure sensors in strategic locations in a shoe to visually display the pressure distribution someone puts on their feet. The pressure is displayed using corresponding LEDs to map out the color based on the amount of pressure. Also, if the correct pressure distribution is reached, then a green LED lights up.

 

Close up image of the display as pressure is applied at the bottom of the foot.

Close up of all the components when the device is off.

Close up of all the components when the device is on. Note that the lights are all blue because no pressure is applied to the shoe.

Animation of how the display functions as you move pressure from the bottom of the foot to your toes.

Process

Different brainstorming ideas for an assistive device.

I am someone who has very bad walking habits. Ever since I was a kid, I knew I had wrong pressure distribution when walking, which caused my knees to grow at a wrong angle. To fix that, I need to constantly remind myself to fix the way I walk. This device is designed to help me do that. It visually displays the pressure distribution, plus tells me when I am putting the right amount of pressure.

Image result for walking foot pressure

I was inspired by Pedobarography– the science and mapping of foot pressure distribution. This is a healthy pressure distribution example.

Based on extensive research on the topic, I started sketching ideas on different important pressure points, and how to correctly distribute weight on a foot.

Based on the combined reading and diagrams I’ve looked at, I figured these 7 zones are most important places for foot pressure.

After research and ideation, I decided the best way to go about making this it to simultaneously work on two components separately, and then join them once they are complete.  The two components are the inputs, which are the pressure sensors, and the outputs which is their corresponding LEDs.

This sketch is the math I was trying to figure out to properly display RGB values on a 0-1023 range in a color gradient. Basically, as pressure increases, the LED goes from blue to green to red. The final values in the code was based on trial and error  while using the shoe, to figure out the right values that makes the gradient look right.

For the “good job!” light:  This sketch is deciphering the research and mapping out the correct pressure distribution for each zone. Then using the values corresponding the 0-1023 value read of the pressure sensor to help map out the correct corresponding RGB value.

PART 1: Getting the pressure sensors to work and map the right colors on the LEDs

PART 2: transferring the sensors and making the shoe

Because I was using an old shoe, it was very helpful, because I could see where I put pressure on my feet, based on where it’s worn out.

That made transferring the zone diagram easier.

Adding one pressure sensor per zone.

Wiring them up to resisters, power and ground.

Connecting each sensor to its corresponding input pin.

The biggest issues I faced in this part was the fact that I was working with so many sensors and so some of them would shift out of place and disconnect, specifically, the ones higher up in the shoe.

Once the shoe part was working well, it was time to transfer the LEDs to a handheld housing

 

Part 3: building the LED housing

Sketch of the way I visualized the handheld device.

Digitization of sketches, and laser cutting the pieces.

PART 4: making the anklet and combining the LEDs and the pressure sensor

 

Figuring out where the best place to put the connecting housing.

Since this device involves a lot of user movement, I thought an anklet would be the best approach. I wanted to make the anklet as small and least intrusive as possible, so I used a flex soldering board.

Connecting the shoe to the handheld device.

BIG MISTAKE!! The flex board was so flimsy and kept breaking and ripping. I kept having to fix it by soldering and re-soldering the connections on the board. At some point, I realized it would take more times to fix the flex board than to just start over with a new, more rigid board. I figured the anklet can grow a bit bigger if it meant the device worked more reliably. And so, I started over….

Soldering, soldering, and more soldering.

Connecting, connecting, and more connecting.

 

 

 

Making the anklet housing.

Animated GIF - Find & Share on GIPHY

 

Alas! The anklet is complete, rigid, and the device works well.

 

The lights changing based on me moving the pressure I put on my foot.

Discussion

During the final presentation, one of the sensors disconnected and was not working. Moving forward, I want to figure out a way to connect the sensors more securely. Because of its flimsiness and flexibility, and just the fact that it’s placed in a shoe, soldering then taping the wires in place, still wasn’t a strong enough solution to prevent the sensors from disconnecting. The issue is the pins on the sensors are very small and close together, so there’s minimal area to work with. A suggestion given:

“The only electrical wiring that really needed to happen down at the foot level was tying the ground to one side of each of the sensors; the other side could simply take one of the wires up to the main junction board. Centralizing your wiring in this way is usually a good idea! “-RZ (instructor)

I think that is a good idea! I aimed to do that but because the sensors needed more connections than the LEDs (which only needed 2 connections to the arduino), I thought it would be easier to have the ardiuno near the FSRs. But definitely if I were to take the project further I would want to centralize everything one main box, and get rid of the ankle piece. Another suggestion giving during the final crit was:

“The shoe you are using is a Nike Free 4.0 which is very soft and flexible. Maybe you should  use a flatter surface underneath the sensors to help read the pressure better.” -RG (classmate)

That is a very valid suggestion, and if implemented I think the sensors might read a bit better– but I wonder if it would make the shoe less comfortable? I think the bigger issue was not that the sensors were not reading well, but more that because of movement the sensors kept disconnecting. So maybe figuring out how to make the sensors stay in place is the direction to go. Also, this shoe was the only shoe I had to work with at the time.

When reflecting on the project, I find myself wondering if 7 sensors was too much? But also, I can’t see the device working the way it is supposed to if I had used any less sensors, because it is about the distribution of pressure and those 7 zones are distinctly separate.

Adding to that, a small bump I ran into was that when I did the calculation, I needed a 9V battery. That voltage was working at first, but then when I moved the components to their respective housings, the arduino was only getting 3.6V and the LEDs were getting 3.3V. I’m guessing the rest of the voltage was lost to time and/or distance. So I needed to add 6 more volts of batteries. Please refer to the schematic for details. Basically, I had to split the power supply to 9V to the FSRs and 6V to the LEDs. I am still new to circuit building and electronics, but I learned a lot when making this project because of all the troubleshooting that needed to be done.

All in all, I like my new device and have already used it a handful of times when walking around. It has definitely made me more aware of the pressure distribution I put on my feet. I still haven’t been able to get the “Good Job!” light to turn on, but hopefully, one day, my walking will be better and I will be able to get that correct pressure distribution. I can already see and feel my walking getting better.

Schematic

Code

/*
 * Walk the Walk
 * by Ghalya Alsanea (galsanea)
 * 
 * This project uses 7 pressure sensors in strategic locations in a shoe to visually display the pressure distribution someone puts on their feet.
 * The pressure is displayed using coresponding LEDs to map out the color based on the amount of pressure.
 * Also, if the right pressure is reached, then a green LED lights up.
 * 
 * 
 * Parts of this code is adopted from https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-use
 */
 
#include <Adafruit_NeoPixel.h>

int PRESSPIN1 = A0;
int PRESSPIN2 = A1;
int PRESSPIN3 = A2;
int PRESSPIN4 = A3;
int PRESSPIN5 = A4;
int PRESSPIN6 = A5;
int PRESSPIN7 = A6;

int PIN = 10;
int LED = 2;

int raw;
int n;
int red;
int green;
int blue;

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(7, PIN, NEO_RGB + NEO_KHZ800);
    

void setup() {
  Serial.begin (9600);
  strip.begin();
  strip.show();                 // Initialize all pixels to 'off'

}

void loop() {

  // MEASUREMENT
  int pressVal1 = analogRead(PRESSPIN1);
  int pressVal2 = analogRead(PRESSPIN2);
  int pressVal3 = analogRead(PRESSPIN3);
  int pressVal4 = analogRead(PRESSPIN4);
  int pressVal5 = analogRead(PRESSPIN5);
  int pressVal6 = analogRead(PRESSPIN6);
  int pressVal7 = analogRead(PRESSPIN7);

//print sensor values for troubleshooting
Serial.print ("SENSORS: (");
Serial.print (pressVal1);
Serial.print (", ");
Serial.print (pressVal2);
Serial.print (", ");
Serial.print (pressVal3);
Serial.print (", ");
Serial.print (pressVal4);
Serial.print (", ");
Serial.print (pressVal5);
Serial.print (", ");
Serial.print (pressVal6);
Serial.print (", ");
Serial.print (pressVal7);
Serial.println (")");
 
//Set each measurement to it's corresponding LED

  if (pressVal1 > 0){
    raw = pressVal1;
    n = 0;
    COLOR ();
    pressVal1 = 0;        //exit the loop
  }

  if (pressVal2 > 0){
    raw = pressVal2;
    n = 1;
    COLOR ();
    pressVal2 = 0;        //exit the loop
  }

  if (pressVal3 > 0){
    raw = pressVal3;
    n = 2;
    COLOR ();
    pressVal3 = 0;       //exit the loop
  }

  if (pressVal4 > 0){
    raw = pressVal4;
    n = 3;
    COLOR ();
    pressVal4 = 0;       //exit the loop
  }

  if (pressVal5 > 0){
    raw = pressVal5;
    n = 4;
    COLOR ();
    pressVal5 = 0;       //exit the loop
  }

  if (pressVal6 > 0){
    raw = pressVal6;
    n = 5;
    COLOR ();
    pressVal6 = 0;       //exit the loop
  }  

  if (pressVal7 > 0){
    raw = pressVal7;
    n = 6;
    COLOR ();
    pressVal7 = 0;       //exit the loop
  } 

  //if you're putting the right amount of pressure, a green light comes on.
  //pressure values are estimates based on healthy pedobarography scans studies.

  if (200<pressVal1<700  &&  400<pressVal2<600  &&  pressVal3>800  &&  200<pressVal4<400  &&  pressVal5<100  &&  100<pressVal6<300  &&  pressVal7>700){
    digitalWrite(LED, HIGH);
  }
    
}


void COLOR(){
  //This function is to calculate which RGB values to use, based on the pressure sensors.
  //The gradient range is from blue to green to red, with red being the most pressure.

  
  // 20 is most blue, 600 is no blue anymore
  int blue = map(raw, 20, 600, 255,  0);     // note the mapping is reversed because blue decreases as pressure increases
  blue = constrain(blue, 0, 255);            // keep the values within limits, just in case the math is wrong

  // green is max at 800 and less in both directions 
  int green =  255 - abs(raw - 800);        
  green  = constrain(green,  0, 255);       // keep the values within limits

  // red increases from 950 to max.
  int red = map(raw, 950, 1023, 0, 255);
  red = constrain(red, 0, 255);             // keep the values within limits
    
  
  strip.setPixelColor(n, red, green, blue); //set the color
  strip.show ();                            //display that color

//print RGB value
  Serial.print ("RGB = ");
  Serial.print (red);
  Serial.print (", ");
  Serial.print (green);
  Serial.print (", ");
  Serial.println (blue);

}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/assistive-device-walk-the-walk/feed/ 0
Interactive Memory Box https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/ https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/#respond Thu, 25 Oct 2018 18:20:43 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4293 Interactive Memory Box is a tool relying on neuroscientific findings used to strengthen the engraving of long term memories right before sleep.

 

 

This project is a concept work which draws upon neuroscientific findings regarding the lasting  effects of memory books on progressive memory loss. It works by systematically reminding you of certain memories by physically printing them on paper right before going to sleep, which causes a strengthening of neural pathways. This is thought to improve memory and protect it from potential neural damage.

 

 

 

 

 

 

 

Process

I started by working with the thermal printer, and getting it to print the content I wanted in a specific format. This meant creating a long and thorough string, my memories. Over the course of a week, I documented past memories which had been pivotal in my life in one way or another, and hardcoded the list of 100+ memories as a string. One of the things I struggled with in the programming section was getting the text to print upside down, so that it would appear right side up while coming out of the box. Unfortunately after many hours of troubleshooting I found that arduino had discontinued that command and it couldn’t be achieved without hacking into the printer.

 

First successful trials with the Adafruit thermal printer

 

One of the main qualms I have with physical computing is often the lack of craft which goes into the physical part of the work. I felt that a piece which relies so heavily on humanity,  tactility and poetry could not be 3D printed or laser cut. I therefore opted to make a hardwood box and spent a significant part of the project time in the woodshop. I purchased some nice Pennsylvania maple a bit outside of town and started the making process.

 

Rockler hardwood section

 

Preparing the maple

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Grooves and miter joints

 

The hardest part of this project was probably the execution of somewhat dangerous cuts on the tablesaw and bandsaw. Measurements and cuts needed to be precise and there was no room for mess ups in this short time frame. The box only fit together after 4 or so hours of fine tuning.

 

 

 

 

 

 

Fine tuning of the miter joints and grooves

 

 

 

 

 

 

Fitting of the hardwood box

 

I finally drilled in holes for the power wires and the side button, assembled the box, added brass hinges, did the sanding and finished the box with tung oil.

 

Finishing of the box and adding the hinges

 

Discussion

During my critique, Claire made a really nice point which made me wish I had thought of it first. She mentioned that the button on the side of the box, although discretely located, did not really respect the object’s physical language. She suggested I used a trigger which upholds the magical aspect of the box, such as an IR sensor. Another very valuable critique I got, was that the receipt printer seemed too removed from the concept. How could I make that interaction more special? Maybe I could build my own plotter, which would ‘hand’ write the notes. Finally, Joey mentioned that a more intuitive UI for the adding of memories to the string should be included, every time my laptop is opened for instance.

I am satisfied with the way this project turned out, as it is relevant to the big picture of my work and has giving me an excuse to  exceed my fabrication qualifications. The concept is strong and loosely based on actual scientific evidence, which I find meaningful when making  something “useful.” I did run into some issues however, such as the arduino’s storage space for my very VERY long string of memories. The genuino uno seemed to only be able to contain, 5 or 6 long sentences, which adds many complications if this project were to actually be used.

Through this project I have gained significant knowledge in the consideration of form and intent, as well as practical skills to execute these theories correctly. I found that mixing the physical and the digital gracefully is a really daunting task, and one that I might have only partially succeeded at. If I were to recreate this project, I would add more magic to the interaction, by replacing the button with an IR sensor. This would be more in line with the product language and would give it more of its own presence. Additionally, my minimal experience in the woodshop made the building process a much slower and tedious one, which would not be the case if I were to attempt to create something out of wood again.

 

Schematic 

 

 

/* Project 02 : Interactive Memory Box
 * By Chloe Desaulles, andrew ID: cdesaull 
 * Made with the Adafruit Thermal Printer Library for Arduino
 * 
 * This code tells a thermal printer to print a memory at random
 * from a string every time the button is pressed.
 * The button is meant to be pressed each night before bed, i.E.
 * before long term memory encoding, which is meant to help with
 * slowing down memory loss processes as well as with memory 
 * recall.
*/


//---------------PRINTER NONSENSE--------------------


#include "Adafruit_Thermal.h"
#include "adalogo.h"
#include "adaqrcode.h"

// Here's the new syntax when using SoftwareSerial (e.g. Arduino Uno) ----
// If using hardware serial instead, comment out or remove these lines:

#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor
// Then see setup() function regarding serial & printer begin() calls.

//--------------------- CONTENT NONSENSE -------------------

int seed;

String myStrings[] {"This is memory 1", "This is memory 2", "This is memory 3",
  "This is memory 4", "This is memory 5", "This is memory 6", 
  "This is memory 7", "This is memory 8"
};



int BUTTONPIN1 = 2;


void setup() {

  //----------------- PRINTER SETUP ----------------

  // This line is for compatibility with the Adafruit IotP project pack,
  // which uses pin 7 as a spare grounding point.  You only need this if
  // wired up the same way (w/3-pin header into pins 5/6/7):
  pinMode(7, OUTPUT); digitalWrite(7, LOW);


  //mySerial.begin(19200);  // Initialize SoftwareSerial - I added it later
  //Serial1.begin(19200); // Use this instead if using hardware serial
  printer.begin();        // Init printer (same regardless of serial type)


  //------------------- LIGHTS -----------------------

  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);

  //------------------- CONTENT SETUP ----------------------

  seed = analogRead(A0); // so long as A0 isn't actually plugged into something
  randomSeed(seed);

  pinMode(BUTTONPIN1, INPUT_PULLUP);
  mySerial.begin(19200);
  Serial.begin(19200);

}

void loop() {

  //----------------- !!!! PRINTING !!!! -------------------

  int buttonVal1;
  buttonVal1 = digitalRead(BUTTONPIN1);

  // If button one is pressed, print a memory at random from array 1
  if (buttonVal1 == LOW) {

    
  //printer.upsideDownOn(); //Tried to print upside down, but isn't supported anymore


    /*digitalWrite(11, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
    delay(2000);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    delay(1000);*/

    printer.setLineHeight(100);
    //Set text right justification (accepts 'L', 'C', 'R')
    printer.justify('R');
    printer.println(F("12:24, 25 October 2018"));
    printer.setLineHeight(50);

    printer.justify('L');
    //printer.println(F("Kind of memory or whatever"));
    //printer.println(F(myStrings[random(0,6)]));

    String printedMaterial = myStrings[random(0,7)];
    
    printer.println(printedMaterial);
    Serial.println(printedMaterial);

    printer.sleep();      // Tell printer to sleep
    delay(3000L);         // Sleep for 3 seconds
    printer.wake();       // MUST wake() before printing again, even if reset
    printer.setDefault(); // Restore printer to defaults
  }
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/feed/ 0
Survival Hugging T-Shirt https://courses.ideate.cmu.edu/60-223/f2018/work/survival-hugging-t-shirt/ https://courses.ideate.cmu.edu/60-223/f2018/work/survival-hugging-t-shirt/#respond Thu, 25 Oct 2018 18:14:01 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4575

Overall:

There is a saying by Virginia Satir, a respected family therapist, “We need four hugs a day for survival. We need eight hugs a day for maintenance. We need twelve hugs a day for growth.” The T-shirt can provide attention through lights in different colours. It is able to count the hugs from 0 hugs to 4 hugs throughout the IR proximity sensor.

.

Product Images:

Hugging Process

Overall Photo

Lighting Aesthetics

Close Shot

Process Images and Review

Decision Moment 1: aesthetics

I put the LED strips vertically on the T-shirt and I changed my original lighting design idea.

After I decided using LED strips to be my lighting component, I was playing with the strips and trying to find a way to design with the T-shirt but not looking cheap. The original idea was bending the strips horizontally and input the lights to the back of the T-shirt. However, that made the graphic of heart looking not continuous by the individual lights. It would also be very difficult to bend that way to be a heart shape. While I was testing the LED strips colour and I put the LED strips vertically on the T-shirt. I actually liked the way how the lights formed the heart and it was much easier to bend this way. Then, I decided to put the LED strips in the front of the shirt and decorated them with different colour felts matching to the individual strips lighting colours.

Decision Moment 2: colour coding

Found the code could test and control the individual strip lighting colour with the colour chart behind the codes.

I was having a hard time to find a simple individual colour changing code on the Internet. There are more LED strip users are using it with three transistors or doing some fancy rainbow lighting effects. Zac helped me to find the better code from the Arduino library so I could control the colour from the chart with the numbers for the individual strip. This code helped me to maintain the original idea of how I would like the lighting strips performing on the shirt.

Other Process Photos

Early Stage Design Rough Sketch

Using the yarns to place the design on the shirt to get the individual LED strips rough measurements.

Covering the strips with the felts and placing on the shirt before sewing them on.

Transferring the wires from the breadboard to the plastic connecting board.

Discussion

I got some positive comments like:

“The concept inspiration is super cool and cute. I really like how the colours came together on the shirt – nice aesthetics.”

“Amazing aesthetics! A very interpersonal approach to an “assistive device”

I was a little bit surprised a lot of people very liked and appreciated this idea. I was concerned this device did not match the prompt as a functional product but I did feel the concept was very interesting and it linked to quote and bring another definition of “function” than the practical meaning. I think it is a successful balance between my personal preference and the project requirement. From the aesthetics aspect, I knew it was easy for me to reach the good artist vision if I thought through from the beginning. I am glad it did not look cheap like a lot of wearable device with LED and it also brought a positive atmosphere from the visual to match the initial idea.

There are few negative comments like:

“All the electronic components were still visible and wasn’t very aesthetically pleasing, so it would have been nice with a box or something”

“It is a bit too bright.”

I have calculated and left long wires for all sections so I could hide the wiring board and Arduino inside my pocket when I demonstrated the device. However, the wires were too fragile than I expected. It could disconnect the parts and made shortcuts if I squeezed inside my pocket. The way to improve is finding a box or sewing another independent pocket to store those components.
Some classmates suggested me to input the lights underneath the T-Shirt so it will not be that bright. I actually like the current outside revealing version more. What I can do is find the code that could allow me to change the brightness. It will still maintain my
artistic version and solve the problem.

During the process, I knew I only had a little time for this project because I was in the middle of my production. I am glad I made this project at this level. However, the wiring took me much longer time than I thought. (like most of the costume craft works) In the end, the product turned out quite nice with the design. I was surprised there was a disconnection when I presented the product. I think the wearable device needed a longer time to test because the movements could easily destroy the connections. However, I embraced the fact and I will try to use more protections to reduce the risk next time.

For my background, coding is the most difficult part for me. During the process, I learnt the process of setting up small goals, making each step worked and accumulated to be one big project. I also practised the research and problem-solving skill. Even though I had a lot of costume and craft making experiences but the way to develop things in electricity and the making resources are different. What I would like to do differently next time is I will leave some time for the failure. I think there are so many unexpectedly wiring problems that I needed to find out during the process. When I make my plan of the action, I should leave more time for that and be careful to approach to every step.

In conclusion, I think this work is more like a philosophical conceptual project. I think it could possibly extend to be a bigger art piece. I would like to realise the quote of 12 hugs display on the T-shirt and make the clear effects when it reaches 4 hugs for survival and 8 hugs for maintenance. Maybe the shirt eventually links with an organization to practice and really express the idea through the device I make.

Schematic

Code

/*
   Project Title: Survival Hugging T-Shirt
   Name: Meng-Han Yeh
   Description: Control the 4 LED strips with the IR proximity sensor.

   Pin Mapping:
   Digital Pin 12 is connecting to Red Strip and controlling the Blue light;
   Digital Pin 11 is connecting to Blue Strip and controlling the Yellow light;
   Digital Pin 10 is connecting to Yellow Strip and controlling the Purple light;
   Digital Pin 8 is connecting to Purple Strip and controlling the Red light;
   Analog Input 0 (A0) is reading the IR proximity sensor.
   Coding Credit: LedStripColorTester - for LED strips colour changing

*/


int photocell = A0; // A0 is reading the IR proximity sensor
bool everHugged = false;
unsigned long timer = 0; // set up the timer

int hugCount = 0;

#include <PololuLedStrip.h>

/* Create names for each of the LED strips and set up the digital pins:
   Digital Pin 12 = ledStrip (the outer LED strip) is connecting to Red Strip and controlling the Blue light;
   Digital Pin 11 = ledStrip2 (the second LED strip from outside) is connecting to Blue Strip and controlling the Yellow light;
   Digital Pin 10 = ledStrip3 (the third LED strip from outside) is connecting to Yellow Strip and controlling the Purple light;
   Digital Pin 8 = ledStrip4 (the forth LED strip from outside, the central inside heart) is connecting to Purple Strip and controlling the Red light
*/

PololuLedStrip<12> ledStrip; // the biggest heart
PololuLedStrip<11> ledStrip2;
PololuLedStrip<10> ledStrip3;
PololuLedStrip<8> ledStrip4; // the smallest heart

// set up how many LEDs on the strip you would like to control
#define LED_COUNT 60
rgb_color colors[LED_COUNT];

void setup()
{
  pinMode(photocell, INPUT); // set up the IR proximity sensor
  Serial.begin(115200); // set up the Serial Monitor

}

void loop() {

  int readVal; // initialize a new integer to store the photocell value
  readVal = analogRead(photocell); // do the analog read and store the value


  rgb_color color;

  // if (it has been at least 10 seconds since the last hug)
  if (millis() >= 10000 + timer) {
    if (readVal > 500) { // if the sensor detects the volumne above 500
      timer = millis();
      hugCount++; // the hugCount will plus one when the sensor detects the volumn above 500
      Serial.println (hugCount); // Showing the hugCount in Serial Monitor

    }
  }
  
// if (hugCount == 0) => the beginning setting
  if (hugCount == 0) {

// ledStrip => blue light
    color.red = 51;
    color.green = 255;
    color.blue = 255;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip.write(colors, LED_COUNT);

// ledStrip2 => yellow light
    color.red = 255;
    color.green = 255;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip2.write(colors, LED_COUNT);

// ledStrip3 => purple light
    color.red = 255;
    color.green = 0;
    color.blue = 204;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip3.write(colors, LED_COUNT);

// ledStrip4 => red light
    color.red = 255;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip4.write(colors, LED_COUNT);

  }

// if (hugCount == 1) => first hug
  else if (hugCount == 1) {

// ledStrip => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip.write(colors, LED_COUNT);

// ledStrip2 => yellow light
    color.red = 255;
    color.green = 255;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip2.write(colors, LED_COUNT);

// ledStrip3 => purple light
    color.red = 255;
    color.green = 0;
    color.blue = 204;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip3.write(colors, LED_COUNT);

// ledStrip4 => red light
    color.red = 255;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip4.write(colors, LED_COUNT);

  }

// if (hugCount == 2) => second hug
  else if (hugCount == 2) {

// ledStrip => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip.write(colors, LED_COUNT);

// ledStrip2 => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip2.write(colors, LED_COUNT);

// ledStrip3 => purple light
    color.red = 255;
    color.green = 0;
    color.blue = 204;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip3.write(colors, LED_COUNT);

// ledStrip4 => red light
    color.red = 255;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip4.write(colors, LED_COUNT);


  }


// if (hugCount == 3) => third hug
  else if (hugCount == 3) {

// ledStrip => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip.write(colors, LED_COUNT);

// ledStrip2 => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip2.write(colors, LED_COUNT);

// ledStrip3 => turns off
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip3.write(colors, LED_COUNT);

// ledStrip4 => red light
    color.red = 255;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip4.write(colors, LED_COUNT);

  }

// if (the sensor detects more than 3 hugs), all lights turn off
  else  {

    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip.write(colors, LED_COUNT);

    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip2.write(colors, LED_COUNT);

    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip3.write(colors, LED_COUNT);

    color.red = 0;
    color.green = 0;
    color.blue = 0;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = color;
    }
    ledStrip4.write(colors, LED_COUNT);

  }


 // Update the colors buffer
  for (uint16_t i = 0; i < LED_COUNT; i++)
  {
    colors[i] = color;
  }


}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/survival-hugging-t-shirt/feed/ 0
Walk the Plant https://courses.ideate.cmu.edu/60-223/f2018/work/walk-the-plant/ https://courses.ideate.cmu.edu/60-223/f2018/work/walk-the-plant/#respond Thu, 25 Oct 2018 18:13:33 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4351 -Overview

This is a device that helps me taking care of my plant especially when I’m not at home.

 

-Process

sketch for some other ideas

Earlier in the process I had several ideas like detecting the pressure on my feet so  it could help me walking more ‘correctly’ or have something reminding me for not look at the computer screen for too long and later I realized assistive device is to help me but not necessary involving with my body. After ‘observe’ my daily life, one thing I realize I’m doing bad is taking care of my plant.

I have idea that build a automatic watering machine initially, but many people have done similiar thing and I’ll need something that suits my need particularly. My plant is always sitting on my window sill, it’s getting some sunlight through window but not water, so I had the idea that possibly could help it get some rain water without me watering it.

Moving is the most important thing for this device, so I start working with stepper motor which is better than other motor like DC motor and servo motor in moving heavy things

soil moisture is the next thing I tested and it turned out pretty easy to work with

keypad is a little bit ‘tricky’ beacuse of the amount of pins it needs(8 of them, each for a row or column), there are always some keys that is not functional or responding with delay

prototype sketch to show what it looks like (I thought I’ll need 2 motors to get it moving initilly but it turned out that I will need only one motor with an anchor point and a belt)

After all parts are functional I made a little box trying to hide all the wires inside but I underestimated the volume of whole thing

soldering

ta-da!

-Discussion

I get many helpful feedbacks from crit.

“Why not have 2 moisture sensors, one to sense soil moisture and one to sense rain which could automate the machine?”

I really like this idea and this would free me from checking the weather and push the keypad.  Sensitiveness of moisture sensor to rain drops need to be tested.  And also there might be some restrictions applied to it such as, shut down during night because it might make noise etc. The other general concern about this device is how practical it is in reality since windows are usually closed during winter.

“I think the machanic design can be modified to tailor the behind window need so that you can still close the window and e.t.c”.

I don’t have a good answer for that yet, becuase all this things needs physical connection and how that would go through the window will be a problem so probably a special kind of window would need to be designed along with it. A more practical solution to it is instead of getting rainwater, it would follow the sun and get enough light, watering part would need to be done by other way such as collecting rain water.

Generally, I’m happy with the outcome of this project I learned a lot and with this many parts of it I made them all function. One thing I would encounter from the beginning if I can start over is to the physical moving part, I always assume that moving physically thing will be easy as long as I get the motor working and I was wrong.

If I get the chance to build the other iteration I would definitely have 2 moisture sensors and I would probably design a simple protytpe for that window that would tailor the need  of this machine.

Technical information

Breadboard connection

//Project: Walk the plant
//Yingyang Zhou
//This project is for helping me taking care of my plant by telling me soil moisture and get rainwater as the time I set. It has 3 main part: soil moisture sensor, keypad and stepper motor.


//soil mositure
int greenLEDPin = 9; // healthy status
int redLEDPin = 10; // dry status
int val = 0;
int soilPin = A0; 
int soilPower = 8;// using analogue pin instead of 5 volts to prevent corrosion


//keypad
#include <Keypad.h>
const byte ROWS = 4; 
const byte COLS = 4; 
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {7, 6, 5, 4}; 
byte colPins[COLS] = {3, 2, 1, 0}; 
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

//motor
#include <AccelStepper.h>
const int STEP_PIN = A2; 
const int DIR_PIN = A1;
AccelStepper myMotor(1, STEP_PIN, DIR_PIN);
int pos = 800;
int place = 0;


void setup() {
  Serial.begin(9600);
  
  pinMode(greenLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  pinMode(soilPower, OUTPUT);
  digitalWrite(soilPower, LOW);

  myMotor.setMaxSpeed(200);
  myMotor.setAcceleration(800);
}


int readSoil(){

    digitalWrite(soilPower, HIGH);
    delay(10);
    val = analogRead(soilPin);
    digitalWrite(soilPower, LOW);
    return val;
}

void loop() {

  
  //keypad
  
  int hourNow = 2; // because I can't get a real time clock, I'll fake the time in this project.
  
  int customKey = customKeypad.getKey();
  int customKeyInt = customKey-48; //translating char to int number
//  Serial.print(char* monthStr(byte month));
  
  if (customKey){
    Serial.println(customKeyInt);
  }
  
  val= readSoil();
//  Serial.print("Soil Moisture = "); Serial.println(val);

  if (val < 100){
    digitalWrite(redLEDPin, HIGH);
  }
  else {
    digitalWrite(redLEDPin, LOW);
    digitalWrite(greenLEDPin, HIGH);
  }
  if (customKeyInt == hourNow){
    place += 1000;
    myMotor.moveTo(place);
    while (myMotor.distanceToGo() != 0) {
    myMotor.run(); //to make sure motor is running all the time before get to the destination
    }
  }
  if (hourNow == customKeyInt+1){ // hourNow will ideally change to 3 in reality but because it stays at 2 in this project I'll need to press 1 on keypad to retract the plant
    place -= 1000;
    myMotor.moveTo(place);
    while (myMotor.distanceToGo()!=0){
      myMotor.run();
    }
  }
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/walk-the-plant/feed/ 0