Introduction:

We are Team MARYa, (Mohan, Andrea, Roly, Yingyang) a group of four Carnegie Mellon University students taking an Introduction to Physical Computing course. For our final project, we were given the task of pairing up with an older person, Maria and creating a useful device for her that implements an Arduino and other physical computing elements. At our initial meeting, we discovered Maria had a habit of throwing papers on the floor instead of organizing them. Keeping this in mind, we created a prototype  for a shelf that would sort your papers for you. Be warned, our prototype is very different from our final product which is documented here. Due to some constraints, we had to take our project in a different direction.

What We Built:

This shelf is helping Maria to easily organise her documents in her home working space. Each section on the shelf has a category with a number and match to the button. The shelf section will be blink by pressing the button. It will be stopped blinking by receiving the document in the right shelf section.

 

Overall

 

Botton Layouts

 

Shelf Construction

 

OLYMPUS DIGITAL CAMERA

 

Maria is busy working in her home office. She wants to quickly organise her documents on her messy desk. After reading her latest bank invoice, she presses the button “3”, which identifies as “Finance” section. She saw the section 3 on the shelf starts to blink so she put the letter into the right section. All the action takes Maria less than 2 secs. Maria is so happy that she can quickly organise her document without thinking where is the “Finance” section. Maria starts to like to organise her documents and she can finally find her documents in the right category in her shelf!

 

How We Got Here:

As was previously mentioned, our project took a sudden turn near the end of the process. We realized that the mechanical aspects of our filing cabinet (including a small elevator to place papers in shelves) were proving far too finicky to finish on time.

Roly here is removing the old supports for the elevator mechanism after trying to solve mechanical issues.

Due to the nature of timing belts and how precise they need to be to produce the motion desired, the elevator was experiencing problems with keeping the belts tensioned enough. These belts were essential to the elevator’s movement since they provided the force that spun the lead screws, which in turn lifted or lowered the tray.

With this big change, the team needed to decide on an alternative option that kept the spirit of the idea. The first idea came almost right away. We wanted to help Maria make sure her papers got filed, but we opted to make it a device to help modify behavior rather than perform the task itself.

This was taken moments after we decided that we had to change our idea. Written on the table were some notes on the logistics of the new idea.

These LED’s became a central part of our new idea.

This is a sensor similar to the one we used to detect when paper was placed in a shelf. The clear bulb emits infrared light, and when an object bounces it back to the black bulb, the sensor knows how far the object is.

Our device was changed slightly to include LED lights on the side of the shelves. These lights would illuminate the shelf where Maria was supposed to put a piece of paper (she would first pick the filing category with a button). Inside of the shelf, some device would sense that she put the paper there and turn off the light. This version of the device was now more focused on reinforcing good habits of paper filing. By having Maria file her papers immediately, we were trying to break the habit of simply leaving it for later. But one problem was left: how to incentivize this.

This was our inspiration for an incentive: a gumball machine. Maria had wanted some sort of candy dispenser before, so we figured we could bring it back in a similar form to this.

Based on one of our first meetings with Maria, we decided to use candy as the incentive for filing. Maria had initially proposed that we make her an automatic candy dispenser, but we decided upon our current project since it seemed more useful to her. By bringing back the candy idea, we added a little inside humor between us and created a reward system for filing.

First test of the lighting and paper detection!

Once we got the shelf lighting and paper detection system working, we began designing the reward system. It was going to be a simple box on top of the shelf that contained a mechanism to dispense candy. Unfortunately, when we were going to laser cut the box, the USB that its file was on got corrupted and we lost it permanently.

In the end, we were only able to get the lighting and paper detection system working, and it was very finicky. We were slightly disappointed to the project turn out like this, but we simply did not have time to fix our ranging technical issues by the day of the presentation.

The final circuit board for the shelving unit. It was somewhat cramped, but it worked (mostly).

Throughout this process, we learned a lot about working on teams with vastly different skill sets. One of our members was an architect, one was a costume designer, and the other two were Information Systems students. We had to be very thorough in our meetings to ensure that this very widespread team was always on the same page. We also had to learn to keep frustrations in check, seeing as we were working hard and late up until the last minute.

Patience was key throughout this whole process. We were working very hard and had to make sure not to clash heads.

Overall, this project was a semi-success in that we were able to finish something for Maria. We would have been disappointed to not have anything at all to present to her or the class. However, through diligence and taking responsibility for our own sections of work, we pushed through to the end.

Conclusions and Lessons Learned:

Assemble process

From the problems we as a team encountered at final assblem stage, we learn a important lesson that for the problem we never worked before, there should be enough time set aside for it, different parts could be delivered late, for example the belt we had at last minute won’t fit the mechanism we already had. Also building a quick prototype from what we have might be a good idea to identify problems need to be resolved. If time constrain is a issue, different scenarios could be developed in advance.

Final Presentation feedback

We get a lot of useful feedback during crit that would help us identify problems and know better about outside opinion, overall people like the project. Although we change our idea at last minute, it is actually from the rewarding system idea we had long time ago. In terms of helping Maria on her habit, reminding system would potentially help her more on change her habbits, as she wrote in comment, it’s more a human/motivation issue than a mechanical issue, how we address it is very interesting, and how the client would use it is a very important post-evaluation part too. There are advice from students suggesting that visual reminder(blinking LED)might be substitued by audio which is more “annoying” and some people feel like bliking LED is not very comfortable to them, therefore this is a debating point which might need to discuss with our “client”. Right now the shelf is not painted and LED stripe is exposed, both need to be worked on in future.

Overall, our team learned a lot from this project. We worked closely with Maria trying to identify her needs in daily life that herself might even not aware of. We tried to start from the point of “organizing paper work” and develop a system/mechanism that would work to help her better on it. We stumbled on some issues and succeed on other issues, both are good lessons we learned.

 

Technical Details:

/*
 * Lighted Paper Shelf by Andrea Chung
 * 
 * When a button is pushed, its corresponding shelf section will
 * light up and blink until a photocell sensor reads that something 
 * has been inserted into that shelf.
 * 
 * The circuit:
 *  - 6 photocell sensors attached to pins A0-A5
 *  - 6 corresponding buttons attached to pins 2-7
 *  - LED strip attached to pin 8
 */

//photocell sensor pins
int sensor1 = A0; 
int sensor2 = A1;
int sensor3 = A2;
int sensor4 = A3;
int sensor5 = A4;
int sensor6 = A5;
//button pins
const int BUT1 = 2;
const int BUT2 = 3;
const int BUT3 = 4;
const int BUT4 = 5;
const int BUT5 = 6;
const int BUT6 = 7;
//filtering values for the sensor readings
float avgVal = 0;  // this variable, of type float (decimal), holds the filtered sensor value
const float PREV_WEIGHT = 0.8; // this variable, of type float (decimal), determines the previously filtered value's weight.
const float CUR_WEIGHT = 1 - PREV_WEIGHT; 
const float threshold = 5.0;
//timer setup for blinking LEDs
unsigned long previousMillis = 0;
const long interval = 1000;
//indicattors for light on or off
bool on1 = false;
bool on2 = false;
bool on3 = false;
bool on4 = false;
bool on5 = false;
bool on6 = false;

//LED strip setup
#include <PololuLedStrip.h>

PololuLedStrip<8> ledStrip; 
// set up how many LEDs on the strip you would like to control
#define LED_COUNT 48
rgb_color colors[LED_COUNT];

void setup() {
  //setup sensor pins as input
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
  pinMode(sensor5, INPUT);
  pinMode(sensor6, INPUT);
  //setup button pins as pullup 
  pinMode(BUT1, INPUT_PULLUP);
  pinMode(BUT2, INPUT_PULLUP);
  pinMode(BUT3, INPUT_PULLUP);
  pinMode(BUT4, INPUT_PULLUP);
  pinMode(BUT5, INPUT_PULLUP);
  pinMode(BUT6, INPUT_PULLUP);
  Serial.begin(9600); // starts serial communication at 9,600 baud (the rate)
}

void loop() {
  //read button values
  int but1Val = digitalRead(BUT1);
  int but2Val = digitalRead(BUT2);
  int but3Val = digitalRead(BUT3);
  int but4Val = digitalRead(BUT4);
  int but5Val = digitalRead(BUT5);
  int but6Val = digitalRead(BUT6);

  rgb_color color;

  //current time passed
  unsigned long currentMillis = millis();

  //if button 1 pressed set as on and read sensor value
  if (but1Val == LOW) {
    on1 = true;
    avgVal = (float)analogRead(sensor1);
    Serial.println("button1");
  }

  //if LED is set as on make light blink until the sensor
  //reading average changes suddenly
  if (on1 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.red > 0) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 255;
        color.green = 0;
        color.blue = 0;
      }
      for (uint16_t i = 0; i < 8; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    //equations taken from Phys Comp course website credit to Joseph Paetz
    float cur_reading = (float)analogRead(sensor1);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading);
    //turn LED off and set as off if the reading changes over a set threshold
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 0; i < 8; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on1 = false;
    }
  }

  //if button 2 pressed set as on and read sensor value
  if (but2Val == LOW) {
    on2 = true;
    avgVal = analogRead(sensor2);
    Serial.println("button2");
  }
  
  if (on2 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.red == 255) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 255;
        color.green = 255;
        color.blue = 0;
      }
      for (uint16_t i = 8; i < 16; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    float cur_reading = (float)analogRead(sensor2);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading);
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 8; i < 16; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on2 = false;
    }
  }

  //if button 3 pressed set as on and read sensor value
  if (but3Val == LOW) {
    on3 = true;
    avgVal = analogRead(sensor3);
    Serial.println("button3");
  }

  if (on3 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.red == 255) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 255;
        color.green = 255;
        color.blue = 0;
      }
      for (uint16_t i = 16; i < 24; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    float cur_reading = (float)analogRead(sensor3);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading*10);
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 16; i < 24; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on3 = false;
    }
  }

  //if button 4 pressed set as on and read sensor value
  if (but4Val == LOW) {
    on4 = true;
    avgVal = analogRead(sensor4);
    Serial.println("button4");
  }

  if (on4 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.blue == 255) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 0;
        color.green = 0;
        color.blue = 255;
      }
      for (uint16_t i = 24; i < 32; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    float cur_reading = (float)analogRead(sensor4);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading);
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 24; i < 32; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on4 = false;
    }
  }

  //if button 5 pressed set as on and read sensor value
  if (but5Val == LOW) {
    on5 = true;
    avgVal = analogRead(sensor5);
    Serial.println("button5");
  }

  if (on5 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.blue == 255) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 0;
        color.green = 0;
        color.blue = 255;
      }
      for (uint16_t i = 32; i < 40; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    float cur_reading = (float)analogRead(sensor5);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading);
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 32; i < 40; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on5 = false;
    }
  }

  //if button 6 pressed set as on and read sensor value
  if(but6Val == LOW) {
    on6 = true;
    avgVal = analogRead(sensor6);
    Serial.println("button6");
  }
  
  if (on6 == true){
    //make led blink
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
  
      // if the LED is off turn it on and vice-versa:
      if (color.blue == 255) {
        color.red = 0;
        color.green = 0;
        color.blue = 0;
      } 
      else {
        color.red = 0;
        color.green = 0;
        color.blue = 255;
      }
      for (uint16_t i = 40; i < 48; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
    }
    float cur_reading = (float)analogRead(sensor6);
    avgVal = avgVal * PREV_WEIGHT + cur_reading * CUR_WEIGHT;
    Serial.println(cur_reading);
    if (abs(avgVal - cur_reading) > threshold){
      color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 40; i < 48  ; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
      on6 = false;
    }
  }
  else{
    color.red = 0;
      color.green = 0;
      color.blue = 0;
      for (uint16_t i = 40; i < 48  ; i++)
      {
        colors[i] = color;
      }
      ledStrip.write(colors, LED_COUNT);
  }
}

 

Schematic