Found in Connected Cuisine
This "Smart Apron", which we've dubbed The Signal for this project was designed to inform any chef of a break in his or her schedule, or the “lull”, through a personal ambient notification in the form of a subtle vibration. Based on user research, we determined a light vibration on the back of the next would be the least intrusive and the least ticklish for most users.
An additional visual display of lights will let the executive chef know when a given station is overburdened and in need of additional help.
INPUT: Moments of inactivity (event sent by The Brain)
OUTPUT: Light vibration and visual indicator that the chef is taking a light mental break
#include "neopixel.h" // use for local build
#include <math.h>
// IMPORTANT: Set pixel PIN, COUNT, and TYPE
// Supported pixel types: WS2812, WS2812B, WS2812B2, WS2811, TM1803, TM1829, SK6812RGBW
#define PIXEL_PIN D3
#define PIXEL_COUNT 17
#define PIXEL_TYPE SK6812RGBW
#define BRIGHTNESS 50 // 0 - 255
Adafruit_NeoPixel ring = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
unsigned long break_period = 1*30*1000; //Duration of break
unsigned long threshold = 3*60*1000; //Threshold time when red lights go off
int pixelNum = 17;
int vibratorPin = A4;
bool lull = false;
int lull_end = 0;
unsigned long break_start;
bool on_break = false;
bool button_clicked = false;
int break_button = D2;
int button_reading;
float val;
bool temp_lull = false;
unsigned long time_left;
unsigned long last_break_end = millis();
unsigned long break_end;
bool stressedOut=false;
int vibrator_pin = A4;
String vibrastring = "";
unsigned long time_now=millis();
void setup()
{
Serial.begin(9600);
pinMode(break_button,INPUT_PULLUP); //Taking input to trigger break
pinMode(vibrator_pin, OUTPUT); //Throwing to output to vibrator
initializeLedStrip();
Particle.subscribe("cmu/diot17/FirstBreather",lullfunc);
Particle.function("lull_trigger",triggerLull);
}
void initializeLedStrip()
{
ring.setBrightness(BRIGHTNESS);
ring.begin();
for(uint16_t i = 0 ; i < pixelNum ; i++)
{
ring.setPixelColor(i, 0, 0, 0, 0); //colors stay blank
ring.show();
}
}
int triggerLull(String command)
{
if(command == "t")
{
Particle.publish("cmu/diot17/FirstBreather");
Serial.println("Triggered lull!");
}
}
void lullfunc(const char *event, const char *data)
{
lull = true;
time_now = millis();
}
void loop()
{
button_reading = digitalRead(break_button);
if( button_reading == LOW )
button_clicked = true;
else
button_clicked = false;
if(button_clicked && !on_break) //Button clicked and not on a break
{
on_break = true;
last_break_end = millis();
break_start = last_break_end;
break_end = break_start + break_period;
Particle.publish("cmu/diot2017/breakButtonStart");
delay(500);
}
else if(button_clicked && on_break) //Button clicked and on a break
{
on_break = false;
last_break_end = millis();
Particle.publish("cmu/diot2017/breakButtonEnd");
delay(500);
}
else
{
if(millis() - last_break_end > threshold)
stressedOut = true;
else
stressedOut = false;
}
if(lull)
{
if( millis()-time_now < 10000 )
vibrate();
else
{
lull = false;
temp_lull = false;
analogWrite(vibrator_pin, 0);
}
}
else
{}
lightManagement("");
}
int lightManagement(String command)
{
if(on_break)
{
last_break_end = millis();
time_left = break_end - millis();
if(time_left > 0)
progressive_bar(time_left);
else
{
on_break = false;
last_break_end = millis();
}
}
else if(stressedOut)
{
Particle.publish("cmu/diot17/StressedOut");
//Center lights turn red when stressed
for(uint16_t i=0; i < pixelNum; i++)
{
//LEDs 7,8,9 turn red
if(i > 6 && i < 10)
{
ring.setPixelColor(i, 0, 255, 0, 0);
}
else
{
ring.setPixelColor(i, 0, 0, 0, 0);
}
}
ring.show();
}
else
{
//Center lights stay blue all other times
for(uint16_t i=0; i < pixelNum; i++)
{
//LEDs 7,8,9 turn green
if(i > 6 && i < 10)
{
ring.setPixelColor(i, 255, 0, 0, 0);
}
else
{
ring.setPixelColor(i, 0, 0, 0, 0);
}
}
ring.show();
}
return 1;
}
void progressive_bar(unsigned long t_l)
{
if(t_l > 25*1000)
{
unlightLeds(0);
}
else if(t_l > 20*1000)
{
unlightLeds(1);
}
else if(t_l > 16*1000)
{
unlightLeds(2);
}
else if(t_l > 12*1000)
{
unlightLeds(3);
}
else if(t_l > 9*1000)
{
unlightLeds(4);
}
else if(t_l > 7*1000)
{
unlightLeds(5);
}
else if(t_l > 5*1000)
{
unlightLeds(6);
}
else if(t_l > 3*1000)
{
unlightLeds(7);
}
else
{
unlightLeds(8);
}
}
void unlightLeds(uint16_t blank_led)
{
for(uint16_t i = 0 ; i < pixelNum ; i++)
{
if( i < blank_led || i > pixelNum - blank_led - 1 )
{
ring.setPixelColor(i, 0, 0, 0, 0); //color stays blank
}
else
{
ring.setPixelColor(i, 0, 0, 255, 0); //color turns blue
}
}
ring.show();
}
void vibrate()
{
vibrastring = "Yes, it's vibrating";
float time_constant = sin(float(millis())/10000*M_PI);
val = float(sin(float(millis())/1500 * 3.14159));
val= val*80+175;
//val = (exp(time_constant) - 0.36787944)*200;
Serial.print("The vib value is: ");
Serial.println(val);
analogWrite(vibrator_pin, val);
}
void notifyLull()
{
unsigned long time_now = millis();
while( millis() - time_now < 1*10*1000 )
{
vibrate();
}
Serial.print(val);
}
Click to Expand
A hands-on introductory course exploring the Internet of Things and connected product experiences.
~
March 5th, 2017