Food Alert Campus Map

Made by Shawn Koid, Harshika Jain and Tejas Kashyap

Found in Diot 2019: Social Objects - Part 3

An ambient map, placed at major buildings on Carnegie Mellon University campus to subtly provide information about free food on campus and CMU food pantry status.

0

Inspiration 

While it may not be obvious, about 19% of the CMU student community is food insecure. Having to choose between eating and rent, tuition, amongst other expenditures, is a difficult situation to endure. Feeling hungry affects students’ moods and behaviours, health, well-being, social lives, and academic concentration. Unfortunately, there is also a stigma around food insecurity–making it even more troublesome for food insecure students. CMU officially launched a food pantry last fall, where all CMU students are able to get food staples for free (twice a month). Despite the CMU pantry being a step forward, we felt inspired to create a product that could help better connect students to the CMU pantry and other food opportunities on campus. 

for more info- GAO report: Food Insecurity on College Campuses  https://www.gao.gov/assets/700/696254.pdf


How Food Alert Campus Map Works

With this goal in mind, our team designed and created ambient campus maps that subtly informs students of free food opportunities and when the food pantry is operating. These maps are placed at main buildings on campus (i.e. Tepper School of Business and Cohon University Center), where most free food opportunities have been. 

When there is an opportunity for free food, people can press a button on the Food Alert Campus Map. A cyan light on the map will glow to indicate the specific building where the free food is. In our experience, free food on campus generally lasts a maximum of 30 minutes; using this timeframe, the cyan light will gradually dim within 30 minutes to share it if is worthwhile to seek out the food. This way, if students see that the light is pretty dim, they may not want to waste their time walking over to another building. When the button is pressed, a message is also sent out on Slack to share the exact floor of the free food opportunity. People can join the Slack channel to opt-in for the notifications.

Additionally, a yellow light automatically turns on to indicate that the food pantry is open and remains off when the pantry is closed. 

0

1. Initial Concepts & Ideas

As our team discussed new ambient device concepts, our ideas varied from stress indicators/reducers to direction devices for runners; however, a common theme we kept thinking about was design for social good. A few of us in our group were also part of the Integrated Design Innovation (IDI) challenge this year, where we were researching food insecurity on college/university campuses for our client, Feeding America. After being exposed to the reality of food insecurity on our campus, we felt that there was a problem space to design for. 

Our initial idea was an ambient keychain that lit up and vibrated when there were free food opportunities on campus, as well as when the food pantry was opening/closing. 

0
Initial Concept Sketch
Initial sketch copy
0

2. Feedback and Iteration

After receiving our first round of feedback in class, we re-visited our initial concept. We questioned the social complications of students carrying around the ambient keychain which could reveal if they were food insecure. Additionally, we had to consider the cost to manufacture multiple units of this product, which could be expensive to produce a keychain for each student. 

From here, we decided to shift our concept from individual product to a product that can be shared publically–which led us to the food campus map concept. As we thought through this, we wanted to be mindful of designing the map to be ambient–discrete yet informative; and to ensure that food insecure students were not singled out, as events shared on the food alert campus map would be open to everyone.

0

3. Prototype I: Connecting Devices

Our first step to designing our product was to make sure our devices could speak to each other. While we had developed these skills using various components (solenoid, piezo, and neopixel) during our Skills Dev in class, we wanted to get one of the devices to publish an event (i.e. "food is available") and for the second device to respond by illuminating a neopixel. 

Additionally, once both neopixels were lit up, we programmed a dimming effect to indicate how much time was remaining to go and get free food (i.e. 30 mins = 10 secs).

0
Paired Devices
Prototype 1
0

4. Prototype II: Sending Messages

Once we paired our devices to publish and subscribe to events from one another, we wanted to add a messaging component to our food campus map. While there are free food email chains currently out there, we have heard that by the time students read it and show up to the location, the free food is gone–causing students to feel that it was a waste of time and effort. 

Knowing that we wanted to have more instant messaging, we set up our particle with an IFTTT account and tried the SMS applet. While we successfully received a text message when we push our device's buttons, the message could only be sent to one phone number at a time during a button press. As a second attempt, we integrated the Slack applet, which could connect and send out messages from all device buttons. 

0
IFTTT Setup Process (Attempt 1 with SMS)
Sms integration
0
IFTTT Setup Process (Attempt 2 with Slack)
Slack integration
0

5. Prototype III: Putting It All Together

Our 3rd prototyping phase was focused on combining all of our components and features into one product. To start, we built our neopixel network by wiring and soldering 3 individual neopixels. Note that for the pilot demo, we are using 3 neopixels per map (representing the food pantry, Tepper School of Business, and Cohon University Center). While building the neopixel network, we measured the distance of the neopixels on various map sizes (A4, A3) but ultimately chose to produce a square map (12in x 12in). 

The neopixels representing at Tepper School of Business and Cohon University Center are triggered by their respective button presses, but the neopixel representing the food pantry is triggered by the pantry hour times. Instead of adding a button, we programmed our devices to light up the food pantry neopixel only during operating hours. (Note that we have altered the food pantry's operating hours for the purposes of the demo on Tuesday)

0
Combining Components
Prototype 3
0

6. Final Attempt & Failure (Testing)

After finalizing all parts of the map, we laser printed a modified version of CMU's campus map. We included holes on the map for the neopixels and the button/dial we created (potentiometer attached to a button). While the neopixels fitted well on the maps, the button/dial was a bit hard to use during testing. To make it easier for the people to try our product during the demo, the button/dial will not be attached to the map. 

0

7. Final Product

The experiments and constructive trials and errors led us to build the prototype as shown below which works as we have intended it to. Turning the potentiometer and clicking the button leads to:

1. A neopixel embedded in the map to light up.

2. A message indicating floor and building on a Slack channel.  

0
Food Alert – Ambient Campus Map
Shawn Koid - https://youtu.be/pc8vypwgf9U
0
Final Process
Finals
0
Circuit Diagram
Screen shot 2019 02 17 at 11.49.35 pm
0

8. Bill of Materials 

1) Particle ARGON (x2)

2) Potentiometer P103 520B (x2)

3) Push Button (x2)

4) Breadboard (x2)

5) Neopixel Adafruit WS2812 (x2)

6) Laser-cutted Balsa Wood Map(x2)

7) Electric wires (5 meters)

8) Power Cable (x2)

9) Power source (x2, 5v )

0
// Campus Food Alert Map - Tejas Kashyap, Harshika Jain, Shawn Koid


// Library statements
#include <neopixel.h>
#include <neopixel.h>

// Time, pixel value and misc. initializations
int now = 0;
unsigned long tStartedAt =0;
int hour =0;
int currentTime =0;
int weekday =0;
int local =0;
int minute =0;
bool tRunning = FALSE;
int duration = 15*1000;
int x=12;
int y=224;
int z=187;
int loc=0;

uint32_t f;
uint32_t k;
int buttonPin = D3;
long lastPublishedAt = 0; // This value will store the last time we published an event
int publishAfter = 1000; // this is the time delay before we should publish a new event from this device

//Potentiometer initialization for floor determination
int potPin = A4;
int potReading = 0;
int flr = D2;
int flrnumber = 0;
  


// NEOPIXEL DEFINITIONS
#define PIXEL_COUNT 3
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);



void setup() 

   {
     Particle.subscribe(  "diot/2019/paired/sthfoodout/" , handleSharedEvent );
     pinMode( buttonPin , INPUT_PULLUP); // sets pin as input
     strip.begin();
     strip.show(); // Initialize all pixels to 'off'
  //  Particle.variable("time", &currentTime, INT);
     Particle.variable("HOUR", &hour, INT);
     Particle.variable("MINUTE", &minute, INT);
     Particle.variable("WEEKDAY", &weekday, INT);
     Time.zone(-5);
     pinMode(flr, OUTPUT);
   }
 


void loop() { 
    
        uint32_t c = strip.Color(x,y,z);    // Neopixel color function initialized

//Initializing and calling inbuilt time functions to check for pantry hours in the next step

        hour = Time.hour(Time.now());
        minute = Time.minute();
        weekday = Time.weekday();



//PANTRY OPERATION - Hours specified, and pantry light function called 

//THURSDAY 4-6PM
if ( weekday==5 && hour>=16 && hour<18)
        { 
            pantry(f);
           }
           
//PANTRY HOURS _ SATURDAY 2-4PM           
else if ( weekday==7 && hour>=14 && hour<16 )
          {
              pantry(f);
          }
//FOR CLASS DEMO - TUESDAY 2-5PM          
else if ( weekday==3 && hour>=14 && hour<17 )
          {
              pantry(f);
          }


    int buttonState = digitalRead( buttonPin );
    

// Setting neopixel colors, diming action through if loops 

    if( buttonState == LOW ){  // turn the LED ON
    tStartedAt = millis();
    tRunning = TRUE;
    publishMyEvent();
    rainbow(c);
    delay(100); // delay for a bit
    }
    
    int now = millis();
    int j=now-tStartedAt;
    
    if (loc==0) {
        
        if(tRunning && j%1000<100) {
            x=x-12/15;
            y=y-224/15;
            z=z-187/15;
            
            k = strip.Color(x, y, z);
            rainbow(k);
        }
    
        if (j>duration) {
            k = strip.Color(0,0,0);
            rainbow(k);
            tRunning=FALSE;
            x=12;
            y=224;
            z=187;
        }
    } else {
        if(tRunning && j%1000<100) {
            x=x-12/15;
            y=y-224/15;
            z=z-187/15;
            
            k = strip.Color(x, y, z);
            rainbow2(k);
        }
    
        if (j>duration) {
            k = strip.Color(0,0,0);
            rainbow2(k);
            tRunning=FALSE;
            
            x=12;
            y=224;
            z=187;
        }
    }
        
        
// Mapping potentiometer readings to five possible floors on buildings through if-else statements 

      potReading = analogRead(potPin);
      Particle.variable("POT", &potReading, INT);
    
    if (potReading<=819 && potReading >=0)
       {
          flr=1;
         }
    else if(potReading>819 && potReading <=1638)
       { 
          flr=2;
       }
    else if(potReading>1638 && potReading <=2457)
       { 
          flr=3;
       }
    else if(potReading>2457 && potReading <=3276)
       { 
          flr=4;
       }
    else if(potReading>3276 && potReading <=4095)
       { 
          flr=5;
       }

    Particle.variable("FLOOR", &flr, INT);
    
    
}



//Publishing events specific to floor, value of which obtained from potentiometer 

void publishMyEvent(){
     if( lastPublishedAt + publishAfter < millis() ) {
         String eventName = "diot/2019/paired/sthfoodout/" + System.deviceID();
         if (flr==1)
         {
         Particle.publish( eventName, "Food is available at Tepper School of Business, first floor" );
         }
         else if (flr==2)
         {
         Particle.publish( eventName, "Food is available at Tepper School of Business, second floor" );
         }
         else if (flr==3)
         {
         Particle.publish( eventName, "Food is available at Tepper School of Business, third floor" );
         }
         else if (flr==4)
         {
         Particle.publish( eventName, "Food is available at Tepper School of Business, fourth floor" );
         }
         else if (flr==5)
         {
         Particle.publish( eventName, "Food is available at Tepper School of Business, fifth floor" );
         }
         lastPublishedAt = millis();
         }
    }


// Checking if event is raised by own device or other, and performing functions accordingly

void handleSharedEvent(const char *event, const char *data) 
  {
         String eventName = String( event ); // convert to a string object
         String deviceID = System.deviceID();
         uint32_t c = strip.Color(x,y,z);
    
         if( eventName.indexOf( deviceID ) != -1 )   // matching event and device ID, light up when event published from other device
          {    
            rainbow(c);
            loc=0;
            return;
          } 
           else 
                {
                  tStartedAt = millis();
                  tRunning = TRUE;
                  rainbow2(c);
                  loc=1;
    }
    

}


//Function to light up own device neopixel
void rainbow(uint32_t c)
  {
     {   strip.setPixelColor(1, c); // i= which led to light up, c= set a color 
         strip.show();
       }
         delay( 100 );
   }


//Function to light up other device's neopixel
void rainbow2(uint32_t c)
  {
     {   strip.setPixelColor(0, c); // i= which led to light up, c= set a color 
         strip.show();
       }
         delay( 100 );
   }

//Function to light up the pantry neopixel    
void pantry(uint32_t f)
   {
         f = strip.Color(180, 200, 0);
         strip.setPixelColor(2,f);
         strip.show();
    }
    
// This code can be reproduced for other locations by changing the name of the building in published event, 
//and changing the corresponding pixel position value in rainbow functions
Click to Expand
0

Business Model 

At Carnegie Mellon University, approximately 6 events are held every month that offer free food. In addition to that, around 40% of food goes uneaten in the U.S. Approximately $165 billion worth of food is wasted every year, according to Harvard Law School’s Food Law and Policy Clinic and the Natural Resources Defense Council, or NRDC, a nonprofit environmental action group.

Considering most CMU events fits approximately 80 people, with an average meal value of $7/student, each event wastes approximately $224 worth of food. That adds up to $1,344 per month and $16,128 per annum. 

After the pilot phase, the goal is to install 6 maps across the following locations at the CMU campus:

1) Tepper School of Business (part of pilot)

2) Cohon University Center (part of pilot)

3) Wean Hall 

4) Hamerschlag Hall 

5) Heinz College

6) Gates Building 


Cost Estimates

Cost of goods for 6 maps is $1,512 ( ~$42 for one, indicated below). Accounting for labor costs  ($15/hr - students) which comes up to $180, for a total 15 hrs of installation work. 

Therefore, the total cost of production and installation is $1,692 which will be recovered in 1 month and 8 days. 

$14,436 plus satisfied students will be the total return on investment in a year. 


Consumer Trust

Since we iterated our product from individual keychain to public campus map, our product does not draw personal data from students (especially ones that are food insecure). The information displayed on the map is open for everyone to view and utilize. Even if someone does not use the map for food-seeking purposes, our hope is that it will instill some wonder to those who see it and act as a helpful resource to those who may need some direction.  

0

Future Iterations:

Throughout our project, we have believed in the importance of iteration. Future iterations of the Food Alert Campus Map, we will explore the following possibilities:

1) A gate-keeper element that does not completely restrict open interaction but prevents foul-play.

2) Sending out text alerts in addition to slack messages to expand the reach of the product.

3) Replace the current button/dial with a larger knob to increase ease of use. 

0

Reflections

This project brought three team members with different backgrounds and various IoT skill levels to work on designing an IoT product. We were motivated to work on something that has the potential to be scaled, but most importantly could help the student community around us. This project has been a roller-coaster ride with its ups and downs, many attempts (and failures), but it has led us to better understand our own skills, time management (while being mindful of constraints). Initially, all of us tried to do everything, but towards the end, the division of roles and responsibilities made the process more efficient, which meant that although we were exposed to different parts of the process, there was an understanding that our respective parts would be consistent and culminate to result in our end product/vision. 

Post-Demo Reflections

Despite having some Argon trouble (thank you Particle for releasing an update), we felt positive about demo-ing our product. The three of us are proud that we tackled a different aspect of social interactions, particularly one that we would love to see come to life on campus. During one of our demos, our neopixels went slightly rogue but quickly reset back to normal functionality after (we finished the demo by showing our video). We received positive feedback regarding the product and discussed various implications/things to think about if this product goes beyond pilot phase. 

x
Share this Project

Courses

49713 Designing for the Internet of Things

· 18 members

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


Focused on
Skills
About

An ambient map, placed at major buildings on Carnegie Mellon University campus to subtly provide information about free food on campus and CMU food pantry status.

Created

February 16th, 2019