Gene Lu

The Innards of MindFULL
Saturday, 19 December 2009

First and foremost, I would like to say that it was a pleasure working with the following people in my group: Colleen Miller, Stephanie Aaron, and Beatriz Vizcaino.

What is MindFULL?
MindFULL is a fork-rest device that serves as a digital reminder for users to put their utensils down after a certain amount of time (10–12 seconds).

What I did
My contributions to the MindFULL project included coding the programs in Arduino and assisting in the various builds of the prototypes.

First Prototype
For this prototype, our input was a lever switch that detected whether or not a utensil was placed onto the stand. Outputs (feedback) included a) the light turning off when the switch was pressed and b) the light blinking after 10 seconds of the switch being unpressed. This second output served as a signal to users to put their fork down. 

Mindfull form sketches
Mindfull form sketches

1st prototype - fork on lever
1st prototype - fork on lever

Here's the code for the initial prototype:

/*
* ********* MindFULL Version 1.0 ********
* Increment the brightness of the LED when the fork is off the stand.
* After ten seconds, the light will blink. Light turns off once the fork
* is placed back onto the lever.
* by Gene Lu http://gene.lu
*/

#define LEDPIN 9
#define BUTTON 7

// this program does not use a while loop

int LEDbrightness=0;
unsigned long timelifted=0;
int buttonState=0;//set to off
boolean  timeLiftedChecked  = false;

void setup(){
  pinMode(LEDPIN, OUTPUT);
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);
}

void loop(){
  buttonState = digitalRead(BUTTON);
 
  // While the button is unpressed
  if(buttonState==false){
  
    // if the time has not been checked
    if(timeLiftedChecked==false){
      timelifted = millis();
      timeLiftedChecked = true;
    }
  
    LEDbrightness= LEDbrightness+25;
    analogWrite (LEDPIN, LEDbrightness);
    delay (1000);
   
    if(checkForTen(timelifted)){
      blinkLight();
    }
  } 
 
  // else if button is pressed
  else{
    analogWrite (LEDPIN, 0);
    LEDbrightness=0;
    timelifted = 0;
    timeLiftedChecked = false;
  }
}

boolean checkForTen(int timelifted){
  if((millis()-timelifted)>10000) {
    return true;
  }
  else {
    return false;
  } 
}

void blinkLight(){
    analogWrite(LEDPIN, 0); // Turns the LED off
    delay(500); // Waits for 1 second (1000ms);  
    analogWrite(LEDPIN, 255); // Turns the LED on
    delay(500); // Waits for 1 second (1000ms);   
}

Utensil device stored in a container and hooked up to a 9V
Utensil device stored in a container and hooked up to a 9V

After building and testing the prototype, users informed us that the output caused them anxiety while others simply ignored the stand. We then took this data and moved onto our second prototype.

Second Prototype
In the second prototype, we experimented with a bi-colored LED that changed from green to orange in a 10 second interval while the lever was unpressed. The only difference in this hardware setup from the first was the LED being used. 

After uploading the new program to the board and switching out the LED, most users found the feedback to be a little too subtle.

/*
* ********* MindFULL Version 1.1 ********
* Fade the color of the LED from green to orange when the fork is off the stand.
* After ten seconds, the light will NOT blink. Light turns off once the fork
* is placed back onto the lever.
* by Gene Lu http://gene.lu
*/ 

#define BUTTON 7

int LEDPIN=9; // This pin is hooked to the Green portion of LED
int buttonState = 0;

int greenPinBrightness = 0;
int redPinBrightness = 0;

unsigned long time = 0;
unsigned long timeLifted = 0;      // The time the fork is lifted.
boolean  timeLiftedCheck = false;  // Check to see if we tested for timeLifted.

void setup(){
  pinMode(LEDPIN, OUTPUT);
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);
}

void loop(){
 
  buttonState = digitalRead(BUTTON);
 
  // While the button is unpressed
  if(buttonState==false){
    // If the time has not been checked, store the time
    if(timeLiftedCheck == false){
       timeLifted = millis();
       timeLiftedCheck = true;
    }
    
    incrementBrightness();
    
  } else {
      // Set all input pins to 0 so that the LED shuts off
      analogWrite (9, 0);
      analogWrite (10, 0);
      greenPinBrightness = 0;
      redPinBrightness = 0;
      timeLifted = 0;
      timeLiftedCheck = false;
  }
}

void incrementBrightness(){
  if(greenPinBrightness < 254 && redPinBrightness == 0){
      greenPinBrightness = greenPinBrightness + 2;
      analogWrite (9, greenPinBrightness);
      delay(78);
  } else {
    if(redPinBrightness < 254){
      greenPinBrightness = greenPinBrightness - 2;
      redPinBrightness = redPinBrightness + 2;
      analogWrite (10, redPinBrightness);
      delay(78);
    } // else { blinkLight(); }
  }
}

boolean checkForTen(unsigned long timeLifted){
  if((millis()-timeLifted)>10000) return true;
  else return false;  
}

void blinkLight(){
    analogWrite(LEDPIN, 0); // Turns the LED off
    delay(500); // Waits for 1 second (1000ms);   
    analogWrite(LEDPIN, 255); // Turns the LED on
    delay(500); // Waits for 1 second (1000ms);    
}

Third Prototype
In this prototype, we were looking to minimize the size of the device in order to perform user testing outside of the studio, e.g. in a restaurant. We made sketches of the parts that we needed, but our parts never came in. Parts included a mini-Arduino, small cell batteries, and silicon buttons.

Sketches for the Final Prototype
Sketches for the Final Prototype

With ordered parts lost somewhere in mail land, our only choice was to use what we had in the studio. Fortunately, one of our classmates had a small breadboard that he lent to us (thanks Jeff), which helped to reduce the size of the device immensely. Wires were also replaced with thinner ribbon cable, which allowed the utensil stand to flex in all directions with respect to the Arduino board.

Other additions included a straw, which was placed into the stand and around the LED. This helped to create a more distributed glow from the LED and also served as a support mechanism for the entire utensil holder itself.

Straw with LED placed inside for a more distributed glow
Straw with LED placed inside for a more distributed glow

3rd prototype reduced in size for portability
3rd prototype reduced in size for portability

Curious as to how the testing went? Check out the video below.

Fourth and Last Prototype
In this prototype, we addressed the issue of the on and off blinking that most of our testers commented on. We also decided not to go with the bi-color LED. Instead, we installed a control knob that allowed users to change the subtlety of the blinking.

MindFULL Knob - at a glance
MindFULL Knob - at a glance
Inside the MindFULL box
Inside the MindFULL box

And last but not least, the code. The code below was broken up into individual functions in order to facilitate whatever changes and updates needed to be done later down the road with future prototypes.

/*
* ********* MindFULL Version 2.0 ********
* Fade the color of the LED from green to orange when the fork is off the stand.
* After ten seconds, the light will NOT blink. Light turns off once the fork
* is placed back onto the lever.
* by Gene Lu http://gene.lu
*/

#define LEDPIN 9
#define BUTTON 7

int LEDbrightness = 0;
int buttonState = 0;
int i = 0;

unsigned long time = 0;
unsigned long timeLifted = 0;      // The time the fork is lifted.
boolean  timeLiftedCheck = false;  // Check to see if we tested for timeLifted.

int analogPin = 0;   // potentiometer connected to analog pin 0
int pulseSpeed = 0;  

void setup(){
  pinMode(LEDPIN, OUTPUT);
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);
}

void loop(){
  buttonState = digitalRead(BUTTON);
 
  // While the button is unpressed
  if(buttonState==false){
    // If the time has not been checked, store the time
    if(timeLiftedCheck == false){
       timeLifted = millis();
       timeLiftedCheck = true;
    }
   
    // If it's over ten seconds, blink the light
    if(checkForTen(timeLifted)){
      i = 255; // setting i (brightness) to 255 before entering the loop.
      while(buttonState == false){
        pulse();
      }
    } else incrementLight();
   
  } else {
      analogWrite (LEDPIN, 0);
      LEDbrightness=0;
      timeLifted = 0;
      timeLiftedCheck = false;
  }
}

boolean checkForTen(unsigned long timeLifted){
  if((millis()-timeLifted)>10000) return true;
  else return false; 
}

void pulse(){
      fadeDown();
      fadeUp(); // pass this a time var to fade up
       
}

void fadeDown(){ 
      while(i>0 && buttonState != true){
        int pulseSpeed = analogRead(analogPin)/25; // Dividing by 25 reduces the amount of change when turning the knob on the potentiometer.
        buttonState = digitalRead(BUTTON);
        analogWrite(LEDPIN, i);
        i-=5;
        delay(pulseSpeed);
      }
}

void fadeUp(){
      while(i<200 && buttonState != true){
        int pulseSpeed = analogRead(analogPin)/25;
        buttonState = digitalRead(BUTTON);
        analogWrite(LEDPIN, i);
        i+=10;
        delay(pulseSpeed);
      }
}

void incrementLight(){
    LEDbrightness = LEDbrightness + 1;
    analogWrite (LEDPIN, LEDbrightness);
    delay(39);
}

So that's basically it for the technical side of MindFULL. I'll keep you posted as the rest of the team members compile their respective sections.

Post a Note
Name:
Website:
Title:
 
Security Image

Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved.

 
Next Post > Lab Wireless