Found in DioT 2019: Connected Communities
A project that nudges the human behaviour to reduce the paper-cup usage; bringing about an environmental change
Big idea
In our research, we found that 8000 paper cups were being used at Starbucks every minute. Even though paper cups are perceived as eco-friendly, the plastic lining inside it makes it extremely difficult to recycle it. Although Starbucks is doing its part in conserving the environment by focussing on product innovation - we wanted to approach this from a different lens.
Goals
To understand and build a solution, we considered the Starbucks at Forbes Avenue. The goal of the project was to motivate and make the users able to use their reusable cups through triggers like reminders and alerts. Based on the Fogg behavior model prescribed by BJ Fogg, this approach was intended to create a behavior change among the customers by reducing paper cup usage.
Why did you make it -
We believe that our solution can be extended to other environments as well where the use of plastic is prevalent. We also believe that every action taken towards conserving the environment will lead to a cleaner and greener future.
What are your motivations -
The biggest motivation was to bring about change in consumer behavior by making them aware of their actions - which would ultimately help us conserve the environment and create a better future.
The project is designed for coffee addicts- the regular coffee drinkers at Starbucks. We targeted this community particularly because of the criticality of the single-use paper cups which has the polyurethane lining, making the cup difficult to recycle.
The needs identified for the community are the daily requirement of coffee and the environmental need to cut down on the paper cup usage. For most of the reusable cup users, our user research shows that the two major fallbacks include: forgetting the cup and washing the cup. These are the two issues that we have tried to handle in our solution.
A lot of solutions are already being explored in this area, with Starbucks giving discounts to the order of 10-25 cents to people who bring their own reusable cups.
Starbucks is also trying to reconstruct the cup to replace the lining to make them recyclable. Starbucks also sells its line of ceramic and reusable cups to reduce paper cup usage.
On another front, cups are being used as service by companies (not Starbucks), where reusable cups are rented for a fee and then returned back to any store in the network to get your money back.
While the solutions stand tall in their own way, they are not able to bring about an impact that is needed. It is clear that people are trying to be motivated to reduce paper cup usage however it is not enough to influence their behavior. Thus, the problem seems deep-rooted and understanding the user becomes of prime importance in order to bring about the change.
The design ideation initiated by the concept of creating a social impact, and peer pressure through the solution. It further developed on including the positive reinforcement as part of the process and targeting motivation, ability, and triggers of the users.
The design is now a two-pronged approach:
a) social initiative to reduce paper cup usage.We researched regular Starbucks goers, questioning them about paper cups and why do they do/don’t bring the reusable cups along with them. A few of the main insights include convenience, bystander effect, forgetting cups and washing cups.
Major challenges encountered:
- We focussed narrowly on the social aspect of the problem, that is, bar graph visualization
- Balancing the two-pronged approach and integrating it with the prototype
- The technical challenge of making the idea work
After ideation, we created a physical bar graph that shows the paper usage at the Starbucks store every day for the past 7 business days. The graph showing the usage stat for the day will be dynamic and each customer buying coffee with a paper cup will increase the height of the paper cup. There is a maximum level set by the store to
We created a two-part solution -
1. A socially visible structure represented by a bar graph that shows the consumption of paper cups on a daily basis for the week. The last bar in the graph is mechanically controlled by a stepper motor that shows real-time data for ‘today’. We also have a maximum level, that Starbucks can define, to challenge the community to stay under in order to receive a reward.
2. A personal motivator in a cup sleeve, that could potentially be sold at Starbucks as well, that can go around any of cup. The sleeve is capable of reminding you to take the cup in the morning and wash it in the night. Also, the sleeve has an RFID tag that can be tapped against the reader at the store to order drinks. When the community achieves the goal set by the store, the sleeve will indicate the reward and also deliver a push notification with further information.
What we created
We created a bar graph using foam core, a stepper motor with a driver, neopixel strips, a lead screw mechanism through the use of a threaded rod and a bolt.
We also created a cup sleeve using foam core, neopixels, and an RFID tag embedded in the body.
The RFID tag was read using an RFID reader which was a separate installation.
Methods and techniques we used
Considering the dimensions and weight of the bar graph, we used a NEMA-17 size bipolar stepper motor with 200 steps/rev, which runs on a 12V power supply. To run the motor, the A4988 driver was used. The lead screw mechanism was designed using a 12” long, ¼” threaded rod with 20 TPI(threads per inch) and corresponding nut. By driving the threaded rod with the motor and constraining the nut, the bar was moved vertically both ways. Each bar consisted of a neopixel strip which was connected to a 5V power supply. The motor and the neopixel for the bar graph was controlled using particle argon.
For the sleeve, a neopixel strip and a neopixel ring were installed and controlled by another particle argon. Also, an RFID coil was stuck to the sleeve. To read the same at the store counter, a reader was designed with an RFID RC522 board which was controlled by the third particle argon.
3.489 KB · Download / View
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#define PIXEL_PIN1 D4
#define PIXEL_PIN2 D5
#define PIXEL_PIN3 D6
#define PIXEL_PIN4 D2
#define PIXEL_PIN5 D8
#define PIXEL_PIN6 D9
#define PIXEL_PIN7 D3
#define PIXEL_COUNT 15
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN1, PIXEL_TYPE);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN2, PIXEL_TYPE);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN3, PIXEL_TYPE);
Adafruit_NeoPixel strip4 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN4, PIXEL_TYPE);
Adafruit_NeoPixel strip5 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN5, PIXEL_TYPE);
Adafruit_NeoPixel strip6 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN6, PIXEL_TYPE);
Adafruit_NeoPixel strip7 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN7, PIXEL_TYPE);
long lastPublishedAt = 0;
int publishAfter = 10000;
int threshold=4;
int updelay=700;
int downdelay=1000;
int alloff=0;
const int dirPin=D10;
const int stepPin=D9;
int cup=0;
int cupused=0;
void setup() {
strip1.begin();
strip1.show();
strip2.begin();
strip2.show();
strip3.begin();
strip3.show();
strip4.begin();
strip4.show();
strip5.begin();
strip5.show();
strip6.begin();
strip6.show();
strip7.begin();
strip7.show();
pinMode(dirPin,OUTPUT);
pinMode(stepPin,OUTPUT);
Particle.function("Paper_cup",papercup);
Particle.function("Reset",resetcup);
Particle.function("Threshold",getthresh);
Particle.function("Updelay",getup);
Particle.function("Downdelay",getdown);
Particle.variable("Cup_count",cup);
Particle.variable("Threshold",threshold);
alloff=1;
}
int papercup(String command)
{
alloff=0;
if(cup<10)
{
cupused=1;
cup++;
}
else
{
cupused=0;
return-1;
}
return 1;
}
int getthresh(String command)
{
if(command.toInt()<10)
threshold=command.toInt();
else
return-1;
return 1;
}
int getup(String command)
{
updelay=command.toInt();
return 1;
}
int getdown(String command)
{
downdelay=command.toInt();
return 1;
}
int resetcup(String command)
{
digitalWrite(dirPin,LOW);//CW-bar goes down
for(int j=0;j<16*cup;j++)
{
for(int i=0;i<200;i++)
{
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}
}
alloff=1;
if(cup<=threshold)
publishevent();
cup=0;
}
void loop()
{
barlights();
uint32_t tocolor = strip7.Color(0,0,0);
if(cup==0)
tocolor = strip7.Color(0, 0, 0);
else if(cup>0 && cup<=threshold)
tocolor = strip7.Color(0, 255-(cup*20), 0);
else
tocolor = strip7.Color(225+(cup*5),0,0);
for(int i=0;i<PIXEL_COUNT;i++)
{
strip7.setPixelColor(i, tocolor );
strip7.show();
}
if(cupused==1)
{
digitalWrite(dirPin,HIGH);//CCW-bar goes up
for(int j=0;j<16;j++)
{
for(int i=0;i<200;i++)
{
digitalWrite(stepPin,HIGH);
delayMicroseconds(700);
digitalWrite(stepPin,LOW);
delayMicroseconds(700);
}
}
cupused=0;
}
}
void barlights()
{
uint32_t coloroff = strip1.Color(0, 0, 0);
uint32_t color1 = strip1.Color(255, 0, 0);
uint32_t color2 = strip2.Color(255, 0, 0);
uint32_t color3 = strip3.Color(255, 0, 0);
uint32_t color4 = strip4.Color(255, 0, 0);
uint32_t color5 = strip5.Color(255, 0, 0);
uint32_t color6 = strip6.Color(255, 0, 0);
if(alloff==1)
{
for(int i=0;i<PIXEL_COUNT;i++)
{
strip1.setPixelColor(i, coloroff);
strip1.show();
strip2.setPixelColor(i, coloroff );
strip2.show();
strip3.setPixelColor(i, coloroff );
strip3.show();
strip4.setPixelColor(i, coloroff );
strip4.show();
strip5.setPixelColor(i, coloroff );
strip5.show();
strip6.setPixelColor(i, coloroff );
strip6.show();
}
}
else
{
for(int i=0;i<PIXEL_COUNT;i++)
{
strip1.setPixelColor(i, color1 );
strip1.show();
strip2.setPixelColor(i, color2 );
strip2.show();
strip3.setPixelColor(i, color3 );
strip3.show();
strip4.setPixelColor(i, color4 );
strip4.show();
strip5.setPixelColor(i, color5 );
strip5.show();
strip6.setPixelColor(i, color6 );
strip6.show();
}
}
}
void publishevent()
{
if( lastPublishedAt + publishAfter < millis() )
{
String eventName = "jiangtaoyan/2019/enchantedBar/" + System.deviceID();
Particle.publish( "jiangtaoyan/2019/enchantedBar/", "discount" );
lastPublishedAt = millis();
}
}
Click to Expand
1933 B · Download / View
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#define RING_PIN D9
#define RING_COUNT 7
#define RING_TYPE WS2812
Adafruit_NeoPixel ring = Adafruit_NeoPixel(RING_COUNT, RING_PIN, RING_TYPE);
#define STRIP_PIN D3
#define STRIP_COUNT 4
#define STRIP_TYPE WS2812
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_COUNT, STRIP_PIN, STRIP_TYPE);
int mor_reminder = 0;
int nit_reminder = 0;
int toggle = 0;
int togglerfid=0;
unsigned long startAt = -1;
long elapsed = 0;
int solid_duration = 1000*3;
int fadeOut_duration = 1000*20;
unsigned long running = 0;
unsigned long ring_timer = 0;
uint32_t colorOn = strip.Color(255, 255, 255);
uint32_t colorOff = strip.Color(0 , 0 , 0);
void setup() {
ring.begin();
ring.show();
for(int i=0; i < STRIP_COUNT; i++) {
strip.setPixelColor(i, colorOff );
strip.show();
}
strip.begin();
strip.show();
Particle.subscribe( "jiangtaoyan/2019/enchantedBar/" , handleSharedEvent );
Particle.subscribe( "maverick/2019/rfidok/" , handleRfid );
Particle.function("Morningrem", morrem);
Particle.function("Nightrem", nitrem);
}
void loop() {
// strip
if ( mor_reminder == 1 )
{
elapsed = millis() - startAt; //calculated elapsed time
if ( elapsed <= solid_duration )
{
strip_solid(1);
}
else if ( elapsed > solid_duration && elapsed <= fadeOut_duration )
{
strip_fadeOut(1);
}
else
{
mor_reminder = 0;
}
}
if ( nit_reminder == 1 )
{
elapsed = millis() - startAt; //calculated elapsed time
if ( elapsed <= solid_duration )
{
strip_solid(2);
}
else if ( elapsed > solid_duration && elapsed <= fadeOut_duration )
{
strip_fadeOut(2);
}
else
{
nit_reminder = 0;
}
}
// ring
if ( toggle == 1)
{
ring_on(1);
}
else
{
ring_off();
}
if(togglerfid==1)
{
ring_on(2);
}
else
{
ring_off();
}
delay(100);
}
// strip on and fade out in 20s
void strip_solid(int a)
{
if(a==1)
{
for(int i=0; i < STRIP_COUNT; i++) {
strip.setPixelColor(i, 0 , 255, 255 );
strip.show();
}
}
else if(a==2)
{
for(int i=0; i < STRIP_COUNT; i++) {
strip.setPixelColor(i, 255 , 255, 0 );
strip.show();
}
}
}
void strip_fadeOut (int a)
{
int r=0;
int g=0;
int b=0;
int colorValue = map(elapsed, solid_duration, fadeOut_duration, 0, 255);
if(a==1)
{
g = 255-colorValue;
r = 0;
b = 255-colorValue;
for (int i=0; i< STRIP_COUNT; i++)
{
strip.setPixelColor(i,r,g,b);
}
strip.show();
}
else if(a==2)
{
g = 255-colorValue;
b = 0;
r = 255-colorValue;
for (int i=0; i< STRIP_COUNT; i++)
{
strip.setPixelColor(i,r,g,b);
}
strip.show();
}
}
void handleSharedEvent(const char *event, const char *data)
{
// String eventName = String( event );
// String deviceID = System.deviceID();
// if( eventName.indexOf( deviceID ) != -1 ){
// return;
// }
toggle = 1;
ring_timer = millis();
Particle.publish("Discount");
}
void handleRfid(const char *event, const char *data)
{
togglerfid = 1;
ring_timer = millis();
}
// ring on for 5min then fade out
void ring_on(int a)
{
int r=0;
int g=0;
int b=0;
running = millis() - ring_timer;
if(a==1)
{
if (running <= solid_duration)
{
for(int i=0; i < RING_COUNT; i++) {
ring.setPixelColor(i, 0 , 0, 255 );
}
ring.show();
delay (100);
}
else if ( running > solid_duration && running <= fadeOut_duration )
{
int colorValue = map(running, 0, 1000*20, 0, 255);
g = 0;
r = 0;
b = colorValue;
for (int i=0; i< RING_COUNT; i++)
{
ring.setPixelColor(i,r,g,255-b);
}
strip.show();
}
else {
toggle = 0;
}
}
if(a==2)
{
if (running <= solid_duration)
{
for(int i=0; i < RING_COUNT; i++) {
ring.setPixelColor(i, 255 , 164, 0 );
}
ring.show();
delay (100);
}
else if ( running > solid_duration && running <= fadeOut_duration )
{
int colorValue1 = map(running, 0, 1000*20, 0, 255);
int colorValue2 = map(running, 0, 1000*20, 0, 164);
g = 164-colorValue2;
r = 255-colorValue1;
b = 0;
for (int i=0; i< RING_COUNT; i++)
{
ring.setPixelColor(i,r,g,b);
}
strip.show();
}
else {
togglerfid = 0;
}
}
}
void ring_off (){
for(int i=0; i < RING_COUNT; i++) {
ring.setPixelColor(i, colorOff );
}
ring.show();
delay (100);
}
int morrem (String e){
startAt = millis();
mor_reminder = 1;
sendnot(1);
return 1;
}
int nitrem (String e){
startAt = millis();
nit_reminder = 1;
sendnot(2);
return 1;
}
void sendnot( int a ){
// check if 1 minute has elapsed
if( a == 1 ){
Particle.publish( "Morning");
long last_published = millis();
delay(1000);
}
if( a == 2 ){
Particle.publish( "Night");
long last_published = millis();
delay(1000);
}
}
Click to Expand
1697 B · Download / View
// This #include statement was automatically added by the Particle IDE.
#include <MFRC522.h>
#define SS_PIN A5
#define RST_PIN D2
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
long lastPublishedAt = 0;
int publishAfter = 10000;
void setup() {
// Initialize serial communications with the computer
Serial.begin(9600);
mfrc522.setSPIConfig(); // sets up SPI config
mfrc522.PCD_Init(); // Initialize RC522 card
Serial.println("Start Scanning");
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
Serial.println("New card Detected");
// Read tapped card data
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
//Dump all card data to Serial
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
publishevent();
}
void publishevent()
{
if( lastPublishedAt + publishAfter < millis() )
{
Particle.publish( "maverick/2019/rfidok/" );
lastPublishedAt = millis();
}
}
Click to Expand
The next steps include:
- Working on the live data from Starbucks and integrating it with a remodeled prototype
- Establishing a concrete network of sleeves and collecting info from the user data (peak time to buy coffee, which coffee people buy, how often do they get the cups) to use it to the benefit of releasing new Starbucks’ schemes
- We also would like to work on other methods of positive reinforcement like showing how much a user has saved (in monetary terms) since their use of reusable cups.
- We would also like to work on a referral program where you and the person you refer, both get Starbucks benefits for using reusable cups. This community effect can encourage spreading the message and help making this a viral phenomenon.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
A project that nudges the human behaviour to reduce the paper-cup usage; bringing about an environmental change
December 6th, 2019