0

The Brain

We've designed a smart door that welcomes front of house staff back in the kitchen only when it's not too busy. If the kitchen is experiencing a back log (more orders coming in than going out), the shutter window on the door will shut providing a subtle cue to LEAVE THE COOKS ALONE. Because afterall, the waiters and waitresses don't need to come back to tell the cooks when it's busy. We assure you, they already know.

When the back log is cleared, the shutter window opens up and the front of the house is again welcome back into the kitchen if they so please.

0

Input/Output

INPUT: The swinging of the kitchen door and number of orders being placed + signal from apron when chefs are too stressed

OUTPUT: Signal to apron when there is a lull + size of door aperture

0

Bill of Materials

  • 1 x Acrylic Sheets 24" x 24"x .47"
  • 3 x Acrylic Sheet 12" x 12" x  .23"
  • 5 x Balsa Wood 1" x 1" x 36"
  • Screws & Bolts
  • 2 x Spray Paint
  • 1 x Stepper Motor
  • 1 x Stepper Motor Driver
  • 1 x Door Magnet Sensor
0
/*
 * Project: Lullz
 * Description: An aperture retracts based on restaurant traffic
 * Author: Nicholas Stone
 * Date: 3/1/2017
 * Version: 4
 */
//Timers and Thresholds
bool lullzStatus = false;
int kitchenTraffic = 0;
int prevKitchenTraffic = 0;
const int kitchenTrafficThreshold = 3;
const int lullzKitchenTrafficThreshold = 0;
int trafficTimer = 0;
int antiTrafficTimer = 0;
int publishTimer = 0;
const int timerThresholdMillis = 5000; //5 seconds
const int lullzTimerThresholdMillis = 10000; //10 seconds
const int publishThresholdMillis = 30000; //30 seconds
// Stepper Motor for the aperture
int stepDelay = 100;
int currStepperPos = 0;
int maxStepperPos = 180;
int stepperStepSize = 30;
const int stepperDirPin = D2;
const int stepperStepPin = D1;
const int stepperEnablePin = D3;
// Door Magnet
const int doorMagnetPin = A0;
int doorMagnetReading = 0;
const int doorMagnetThreshold = 700;
const int doorDeBounceMillis = 3000;
const int doorMagnetSampleRateMillis = 300;
// Manual Switch
const int systemSwitchPin = D0;
int systemSwitchValue = 0;
const int systemSwitchSampleRateMillis = 500;
void setup() {
    Serial.begin(9600);
    pinMode(doorMagnetPin,INPUT);
    pinMode(systemSwitchPin,INPUT_PULLUP);
    pinMode(stepperStepPin,OUTPUT);
    pinMode(stepperDirPin,OUTPUT);
    pinMode(stepperEnablePin,OUTPUT);
    // Restaurant Subscription
    Particle.subscribe("cmu/diot17/StressedOut", kitchenStatus);
    //disable stepper
    digitalWrite(stepperEnablePin,HIGH);
  }
void loop() {
    //set timer on 1st iteration
    if(trafficTimer == 0) {
      antiTrafficTimer = millis();
    }
    //zero out value for intermediate
    if(systemSwitchValue != digitalRead(systemSwitchPin && systemSwitchValue > 0)) {
      kitchenTraffic = 0; //zero out the traffic
      antiTrafficTimer = millis();
      trafficTimer = millis();
    }
    //monitor switch
    systemSwitchValue = digitalRead(systemSwitchPin);
    if(systemSwitchValue > 0) { //on
      readDoorMagnet();
      checkLullz();
      delay(doorMagnetSampleRateMillis);
    } else {
      Serial.println("System Off");
      delay(systemSwitchSampleRateMillis);
    }
}
void readDoorMagnet() {
  doorMagnetReading = analogRead(doorMagnetPin);
  //Serial.println(doorMagnetReading);
  //door removed from frame, and has been sufficient time since last count
  if(doorMagnetReading > doorMagnetThreshold && (kitchenTraffic == 0 || trafficTimer + doorDeBounceMillis < millis())) {
    kitchenTraffic++;
    //reset traffic timers
    trafficTimer = millis();
    antiTrafficTimer = millis();
    Serial.println("Traffic Increased");
  }
  //reset if it has been enough time since the last one
  if(kitchenTraffic > 0 && trafficTimer + timerThresholdMillis < millis()) {
    kitchenTraffic = kitchenTraffic - 1;
    prevKitchenTraffic = prevKitchenTraffic - 1;
    trafficTimer = millis();
    antiTrafficTimer = millis();
    Serial.println("Traffic Decreased");
    if(currStepperPos > 0) {
    //calculate remaining clearance
        if(currStepperPos < stepperStepSize)
        {
          rotateStepper(currStepperPos,0,10);
        } else {
          rotateStepper(stepperStepSize,0,10);
        }
    }
  }
  //if over threshold, and value increased from previous rotation
  if(kitchenTraffic >= kitchenTrafficThreshold && kitchenTraffic > prevKitchenTraffic) {
    //if still clearance
    if(currStepperPos < maxStepperPos) {
    //calculate remaining clearance
        if(currStepperPos + stepperStepSize > maxStepperPos)
        {
          rotateStepper(maxStepperPos - currStepperPos,1,10);
        } else {
          rotateStepper(stepperStepSize,1,10);
        }
    }
    prevKitchenTraffic = kitchenTraffic;
  }
    return;
}
void checkLullz() {
    // publish lullz if below threshold (amound & time) and hasn't published in past ThresholdMillis time period
  if(kitchenTraffic <= lullzKitchenTrafficThreshold && antiTrafficTimer + lullzTimerThresholdMillis < millis()
      && publishTimer + publishThresholdMillis < millis())
  {
    Particle.publish("cmu/diot17/FirstBreather",true);
    Serial.println("Published Lullz");
    //reset timers
    publishTimer = millis();
    antiTrafficTimer = millis();
    // retract aperture completely
    if(currStepperPos !=0) {
      rotateStepper(currStepperPos,0,5);
    }
  }
}
//trigger presence of veggie from event publish by other photon
void kitchenStatus(const char *event,const char *data) {
  //completely close aperature
  if(currStepperPos < maxStepperPos) {
    rotateStepper(maxStepperPos - currStepperPos,1,10);
    currStepperPos = maxStepperPos;
  }
  return;
  }
//direction: 0 -- CCW , 1 -- CW
//speed: 1 (fastest) - 10 (slowest)
void rotateStepper(int degrees,int direction,int speed) {
  //enable motor
  digitalWrite(stepperEnablePin,LOW);
  Serial.println("Rotate Stepper");
  delay(500);
  //handle direction
  if(direction == 1) {//CW
      digitalWrite(stepperDirPin,LOW);
    } else {
        digitalWrite(stepperDirPin,HIGH); //CCW
      }
  int degreeTransform = degrees / 1.8;
  //handle speed
  if(speed > 10) {
    speed = 10;
  }
  if(speed < 1) {
    speed = 1;
  }
    //create i number of pulses at speed
  for(int i = 0; i < degreeTransform; i++) {
      digitalWrite(stepperStepPin,HIGH);
      delay(speed);
      digitalWrite(stepperStepPin,LOW);
      delay(speed);
      }
  //disable motor
  digitalWrite(stepperEnablePin,HIGH);
  if(direction == 1) {
    currStepperPos = currStepperPos + degrees;
  } else {
    currStepperPos = currStepperPos - degrees;
  }
}
Click to Expand
0

Circuit

x
Share this Project

Courses

49-713 Designing for the Internet of Things

· 26 members

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


About

~

Created

March 5th, 2017