The 67oz

Made by Lin Xu, Haokun Wang and Jiangtao Yan

Found in DIoT - Augmented Objects

Our goal is to encourage people to drink 67oz water every day and stay with a healthier lifestyle.

0

Problem Statement

Sophia is a busy people who care a lot about health and want to avoid dehydration. She knows that she has drink 67oz water every day but she always forgets how much water she drinks. Thus, she wants to have a smart bottle as an ambient device to reveal the water consumption amount, which can be solved by 67oz.

0

Principle

Our smart bottle can track how much water a user drink every day and use the length of the LED light strip to reveal the volume of water consumption.

Each adult should drink 67oz (2000ml) water every day. We designed the bottle volume is 500ml. So, people need to drink above 4 bottles that can meet the standards. When they finish 500ml, the stripe will light one LED. All of the light will light when people drink 4 bottles at least.

0

Sketch & Use case

0

Stakeholder Map

0

Approach

Based on our concept which is to design a smart bottle to help people know how much water they drink already, to conduct an implementation way for it. We considered several methods to achieve it, for example, by using Load Cell Weight Sensor, but after discussing with the professor, we decided to DIY a water level sensor based on the references as a part of our project.
0

Process

For this project, our team has several challenges:

  1. How to detect the water level?

  2. How to detect the volume of people's drinking and refilling?

  3. How to make it ambient and unobtrusive?

When we decided using a DIY water level sensor, we began to follow the reference to make the product. We finished the circuit, but it was really hard to complete the code part. Jiangtao made a heavy contribution in that part by asking for professor's and classmates' help. The code also needs to be iterated in different versions. For instance, we tried several times to define the baseline of water level detection, 2270, 2300, ......

After a series of iterations, we made a successful outcome for our project.

  • We tried several circuits with different components.
0
Water level sensor DIY with different resistors.
Img 4570 2
0
  • We used a different baseline to test our code. 
0

Technical Documentation

List of Parts

  • 1 x LED Strip 
  • 1 x Button
  • 3 x Resistor 100 k Ohm 
  • 5 x Resistor 330 k Ohm 
  • 1 x Capacitor 104 nF 
  • 1 x PCB Board 
  • 1 x Breadboard 
  • 1 x Argon 
  • Several jumper wires


0
#include <neopixel.h>

#define PIXEL_PIN D2
#define PIXEL_COUNT 5
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

uint32_t colorOn = strip.Color(255, 255, 255);
uint32_t colorOff = strip.Color(0 , 0 , 0);

int switchPin = D3;
int resetbuttonPin = D4;
const int output27 = D5;                        // pin 27 sends a "0"  or "1" (0 -3.3 V) to the waterlevel measurement circuit
const int LevelSensorPin = A4;  
int flag = 0;

                                                // 12 bits ADC pin 34 senses the voltage level of the waterlevel sensor (values 0 - 4095)
int WaterLevelValue = 0;                        // Variable to store the value of the Waterlevel sensor
int level = 0;                                  // Variable of the WaterLevel
int fadeCycle = 0;

int previousAmount = 0;
int startAmount = 0;
int totalConsumed = 0;
int change = 0;
int currentAmount = 0;
//                      0    1    2    3    4    5
int LEVELarray [6] = {2100,2600,3300,3750,4000} ;    // Array with the level reference values to determine the waterlevel
                                                          // the "0" level is applicable when there is no water in the reservoir
                                                          // the "5" level is applicable when the reservoir is full 
unsigned long elapsed = 0;
unsigned long now = 0;
unsigned long starttime = 0;
int running = 0;

int start (String e){
    Particle.publish( "running", String(running));
    starttime = millis();
    running = 1;
    return running;
}
int r = 255;
int g = 20;
int b = 147;

uint32_t colorPink = strip.Color(255, 20, 147);

int displayTimeFor = 10000;
int displayTimeFadeOut = 5000;
unsigned long startedDisplayAt= -1;

// this will be triggered when 
// there is a change in consumption
// or if the button has been pressed.
bool shouldShowDisplay = false;


void setup() {
    
    Serial.begin(115200);                   
 
    pinMode(output27, OUTPUT);                      // Initializes the power output pin (3.3 V) for the WaterLevel Sensor circuit
    digitalWrite(output27, LOW);                    // Set output27 to LOW; this will send 0 V to the measuring circuit
    pinMode(LevelSensorPin, INPUT);                 // Initializes the water level sensorpin
    pinMode(PIXEL_PIN, OUTPUT);                     // Initializes the output pin for the WaterLevel Indicator
  
    pinMode(switchPin, INPUT_PULLUP);
    pinMode(resetbuttonPin, INPUT_PULLUP);
    
    Particle.variable( "change", change );
    Particle.variable( "totalConsumed", totalConsumed );
    Particle.variable( "previousAmount", previousAmount );
    Particle.variable( "currentAmount", currentAmount );
    Particle.variable("elapsed", elapsed);
    Particle.variable("starttime", starttime);
    Particle.variable("Fading", fadeCycle);
    
    
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'
               
}
void loop(){
    
    
    int buttonState = digitalRead( switchPin );
    int resetState = digitalRead( resetbuttonPin );
    // press the button
    if( resetState == LOW ){
        
        if (flag==0) {
            starttime = millis(); //mark the startime
            flag = 1;
        }
        elapsed = millis() - starttime; //caculate elapsed
    } 
     // Handle the button push
    if (flag ==1 && elapsed > 2500){ // or add another button
        // turn the LED On nd off one by one
        Initialization();
        flag= 0;
        
    } 
    
    
    
    
    if ( buttonState == LOW ) {
         // the LED display should be turned on
         
         shouldShowDisplay = true;
         
    }
     
     // measure the current water level 
    measureWaterlevel();

    
    if( shouldShowDisplay ){
        startedDisplayAt = millis(); //mark startdisplay
     
        // set the color to pink
        r = 0;
        g = 0;
        b = 0;
         
        // mark the display as hidden
        shouldShowDisplay = false;
        
     }
     
     // now we can use startedDisplayAt
     // to find if the display is on 
    else if( startedDisplayAt == -1 ){
         // set all the LEDs off
        r = 0;
        g = 0;
        b = 0;
         
     }
     
    else{
         // the timer is running.... 
        int displayElapsed = millis() - startedDisplayAt;
        
        if( displayElapsed > displayTimeFor ){
            // the display time has elapsed.
            // turn the display off
            startedDisplayAt = -1 ;
        }
        else if( displayElapsed < displayTimeFor - displayTimeFadeOut ){
            
            // display it as a solid color during the middle 5 seconds
            r = 255;
            g = 20;
            b = 147;
            
        }else {
        
            int last5Sec = displayElapsed - (displayTimeFor - displayTimeFadeOut); 
            // fade it out over 5 seconds
            r = 255 - map( last5Sec, 0, displayTimeFadeOut, 0, 255);
            g = 20 - map( last5Sec, 0, displayTimeFadeOut, 0, 20);
            b = 147 - map( last5Sec, 0, displayTimeFadeOut, 0, 147);
            
        }
        
     }

    
        indicateAmount();
        delay(50);
    
}
    
  
    // Check for new value every 1 sec;
    //this value is just for demonstration purposes and will in a practical application be far less frequent
void measureWaterlevel()  {
    
    digitalWrite(output27, HIGH);           // make pin 27 HIGH
    delay(100);                             // allow the circuit to stabilize
    WaterLevelValue = analogRead(LevelSensorPin);  //Read data from analog pin and store it to WaterLevelvalue variable
    for (int i = 0; i < 5 ; i++){
        
        if ((WaterLevelValue > (LEVELarray[i] * 0.94)) && (WaterLevelValue < (LEVELarray[i] * 1.06))){
        level = i;
        }  
        digitalWrite(output27, LOW);           // make pin 27 LOW
        Serial.print(" LEVELarray: "); 
        Serial.print(level); 
        Serial.print(" = "); 
        Serial.print(LEVELarray[level]);
        Serial.print("   -: ");
        Serial.print( i );
        Serial.print("   -: ");
        Serial.print("   WaterLevelValue: ");
        Serial.print(WaterLevelValue);
        Serial.print("  Level: "); 
        Serial.println(level);
        }
  }
    
void indicateAmount(){
    
    if ( level == 0 ){ currentAmount = 0;
    }
    
    if ( level == 1 ){ currentAmount = 100;
    }

    if ( level == 2 ){ currentAmount = 250;
    }

    if ( level == 4 ){ currentAmount = 400;
    }

    if ( level == 5 ){ currentAmount = 500;
    }
    
    // after define the currentamount, then do the caculation
    accumulateAmount();
    
        // 0 led
    if (totalConsumed < 300){
        
        for(int t=0; t<5; t++){
        strip.setPixelColor(t, 0, 0, 0);    
        strip.show();
        }
    }
    // 1 led
    if (totalConsumed >= 300 && totalConsumed < 800){
        
        for(int t=0; t<1; t++){
            strip.setPixelColor(t, r, g, b);           
            strip.show();
        }
    }
    // 2 led
    if (totalConsumed >= 800 && totalConsumed < 1200){
        
        for(int t=0; t<2; t++){
            strip.setPixelColor(t, r, g, b);           
            strip.show();
        }
    }
    // 3 led
    if (totalConsumed >= 1200 && totalConsumed < 1600){
        for(int t=0; t<3; t++){
            strip.setPixelColor(t, r, g, b);           
            strip.show();
        }
    }
    // 4 led
    if (totalConsumed >= 1600 && totalConsumed < 2000){
        
        for(int t=0; t<4; t++){
            strip.setPixelColor(t, r, g, b);           
            strip.show();
        }
    }
    // 5 led
    if (totalConsumed >= 2000){
        
        for(int t=0; t<5; t++){
            strip.setPixelColor(t, r, g, b);           
            strip.show();
        }
    }
}

void accumulateAmount(){
    
     int consumedAmount = startAmount - currentAmount;
     change = currentAmount - previousAmount;
     
     if ( previousAmount < currentAmount ){
          // the amount has changed by refilling
        startAmount = currentAmount;
        
        // trigger the display to light up
        shouldShowDisplay = false;  //change made
        
      } else if ( previousAmount > currentAmount ){
          // the amount has changed by drinking
          totalConsumed = totalConsumed + abs(change);
          // trigger the display to light up
          shouldShowDisplay = true;
      }
      previousAmount = currentAmount;
}

void Initialization(){
    
    //individually lightup
    for(int i=0; i < 5; i++) {
        strip.setPixelColor(i, colorOn );
        strip.show();  //update pc
        delay(200);
    }
    
    delay(1000);
    
    for (int k = 4; k > -1 ; k--) {
        strip.setPixelColor(k, colorOff);       
        strip.show();
        delay (200);
    }
    delay(200);
    for(int i=0; i < 5; i++) {
        strip.setPixelColor(i, colorOff );
		strip.show();  
		delay(200);
    }
    
    totalConsumed = 0;
}
Click to Expand
0
Making water level sensor.
Ham
0
v1 Prototype.
Prototype1
0

Video

0
67 oz
Harper Wang - https://youtu.be/PaW6vXHZKZE
0

Reflection

1. There are multiple ways to visualize information other than using UIs.

2. A better understanding of the sensors:  the things happen behind the sensors are certain physical laws, for instance, using the conductivity of water to reveal the water level.

3. The structure of code is very important: a clean and structured code could fast the processing speed and enhance the stability, efficiency, easy of debugging of a system.

4. Physical limitations should be considered when making a product, some ideas should yield to the current technology.

5. The structure of a team should be given much attention because people would do a better job if they were assigned to sth that they are familiar with or at least is related to their previous background.

0

Next Step

1. Adding a function that a certain group of users can send messages to each other to remind them to drink water when they think it is necessary.

2. Making a high-fidelity prototype that integrates a microcontroller and circuits within a structured product.

x
Share this Project

Courses

49713 Designing for the Internet of Things

· 16 members

A hands-on introductory course exploring the Internet of Things and connected product experiences.


Focused on
Skills
Tools
About

Our goal is to encourage people to drink 67oz water every day and stay with a healthier lifestyle.

Created

November 21st, 2019