Back to Parent

/*
 * 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

Content Rating

Is this a good/useful/informative piece of content to include in the project? Have your say!

0