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