/*
* 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!
You must login before you can post a comment. .