/***** Team T1000 2.744 Product Design Door Mechanism Code *****/ //INCLUDE LIBRARIES WITH #include #include "LPD8806.h" #include "SPI.h" //DEFINE PARAMETERS #define OPEN_TIME 30000 #define IR_THRESHOLD 1010 #define CLOSING_TIME 1000 #define OPENING_TIME 1000 #define EMERGENCY_TIME 5000 #define PREOPENING_TIME 1000 #define POSTCLOSING_TIME 1000 #define nLEDs1 20 #define nLEDs2 60 //DEFINE PINS #define PNEUMATIC1 12 #define PNEUMATIC2 13 #define BUTTON 8 #define IRDETECTOR A0 #define IREMITTER 7 #define dataPin1 2 #define clockPin1 3 #define dataPin2 4 #define clockPin2 5 //DEFINE DOOR STATES typedef enum DOOR_STATE { CLOSED_STATE = 0, OPENING_STATE = 1, OPENED_STATE = 2, CLOSING_STATE = 3, EMERGENCY_STATE = 4, } DOOR_STATE; //INITIALIZE VARIABLES int doorState = OPENED_STATE; int startTime = 0; int i = 0; //Define colors for randomization int red[] = {225,0,0}; int blue[] = {0, 0, 255}; int green[] = {0, 255, 0}; int cyan[] = {0, 255, 255}; int purple[] = {255, 0, 255}; int yellow[] = {255, 255, 0}; int* colors[]={blue, green, cyan, purple, yellow}; int *color = cyan; //Number LEDs, SPI, clock pins; both strands use the same clockPin LPD8806 strip1 = LPD8806(nLEDs1, dataPin1, clockPin1); LPD8806 strip2 = LPD8806(nLEDs2, dataPin2, clockPin2); void setup() { Serial.begin(9600); //only need if we are debugging and showing stuff on serial monitor pinMode(PNEUMATIC1, OUTPUT); pinMode(PNEUMATIC2, OUTPUT); pinMode(BUTTON, INPUT); pinMode(IREMITTER, OUTPUT); //pinMode(dataPin, OUTPUT); //pinMode(clockPin, OUTPUT); digitalWrite(PNEUMATIC1, LOW); //write the doors to open. digitalWrite(PNEUMATIC2, LOW); //write the doors to open. digitalWrite(IREMITTER, HIGH); //turn the IR sensor system on. strip1.begin(); // Start up the LED strip strip2.begin(); strip1.show(); // Update the strip, to start they are all 'off' strip2.show(); } void loop() { switch (doorState) { case CLOSED_STATE: { doClosedStateActions(); //do the actions for the closed state while(digitalRead(BUTTON)==LOW) { //while the button is not being pressed... //DO NOTHING //just wait it out. } if(digitalRead(BUTTON)==HIGH) { //if the while loop stopped, we double-check that the button was pressed... debounce(); //and then we wait half a second for good measure... doorState = OPENING_STATE; //then we define the new state... break; //then we break out of the switch statement. } } case OPENING_STATE: { doOpeningStateActions(); //do the actions for the opening state delay(1000); //pause for one second doorState = OPENED_STATE; //define the new state break; //break out of the switch statement } case OPENED_STATE: { doOpenedStateActions(); while(digitalRead(BUTTON)==LOW) { //DO NOTHING } if(digitalRead(BUTTON)==HIGH) { debounce(); doorState = CLOSING_STATE; break; } } case CLOSING_STATE: { doClosingStateActions(); //this contains the IR sensor trip switch code break; } case EMERGENCY_STATE: { doEmergencyStateActions(); doorState = OPENED_STATE; break; } } } void doClosedStateActions() { //all actions that happen when the door enters the closed state Serial.println("the door is closed!"); digitalWrite(PNEUMATIC1, HIGH); digitalWrite(PNEUMATIC2, HIGH); lights_off(); } void doOpeningStateActions() { //all actions that happen when the door is in the opening state Serial.println("the door is opening!"); colorWipe_forward(color, PREOPENING_TIME); digitalWrite(PNEUMATIC1, LOW); digitalWrite(PNEUMATIC2, LOW); colorWipe_circle(color, OPENING_TIME); //the system cannot be interrupted so it can run its process without any checks. } void doOpenedStateActions() { //all actions that happen when the door enters the opened state Serial.println("the door is opened!"); digitalWrite(PNEUMATIC1, LOW); digitalWrite(PNEUMATIC2, LOW); lights_on(color); } void doClosingStateActions() { //all actions that happen when the door is in the closing state Serial.println("the door is closing!"); digitalWrite(PNEUMATIC1, HIGH); digitalWrite(PNEUMATIC2, HIGH); for (i=0; i <= (strip2.numPixels()/2+2); i++) { //break the actions into short increments if(analogRead(IRDETECTOR)>IR_THRESHOLD) { //check the sensor to see if something is in the way doorState = EMERGENCY_STATE; //if something is in the way, change the system state return; //leave the doClosingStateActions() function entirely } else { colorWipe_circle_reverse(i, color, CLOSING_TIME); //if the sensor is clear, do the aesthetic effects } } colorWipe_reverse(color, POSTCLOSING_TIME); //now the door is closed. do the second aesthetic effects doorState = CLOSED_STATE; //update the system state } void doEmergencyStateActions() { //all actions that happen when the door is in the emergency state Serial.println("emergency!"); digitalWrite(PNEUMATIC1, LOW); digitalWrite(PNEUMATIC2, LOW); emergency(red, EMERGENCY_TIME); } void debounce(void) { delay(500); } void irCheck(void) { if(analogRead(IRDETECTOR)>IR_THRESHOLD) { doorState = EMERGENCY_STATE; return; //leave the function entirely } } //LED Functions //SHORT STRAND LIGHTS: LEDs light from the middle, spread outward void colorWipe_forward(int c[], int wait) { int i; int j; int k; float b1 = .8; //Brightness multiplication factors float b2 = .6; int nLEDs=strip1.numPixels()-1; //subtract one to make an odd number of LED's float dur = wait/(nLEDs); //Length of time between LED's lighting up, as defined by the total duration uint32_t color1 = strip1.Color(c[0], c[1], c[2]); //Light up LED's in order of decreasing brightness uint32_t color2 = strip1.Color(int(b1*c[0]), int(b1*c[1]), int(b1*c[2])); uint32_t color3 = strip1.Color(int(b2*c[0]), int(b2*c[1]), int(b2*c[2])); for (i=0; i <= nLEDs; i++) { j=nLEDs/2 + 1 + i; k=nLEDs/2 + 1 - i; strip1.setPixelColor(j, color1); if (i>=1) { strip1.setPixelColor(j-1, color2); strip1.setPixelColor(k+1, color2); } if (i>=2) { strip1.setPixelColor(j-2, color3); strip1.setPixelColor(k+2, color3); } strip1.show(); delay(dur); } strip1.setPixelColor(strip1.numPixels(), color3); //light up the last LED } // REVERSE SHORT STRAND LIGHTS void colorWipe_reverse(int c[], int wait) { int i; int j; int k; float b1 = 1; //Brightness multiplication factor float b2 = .8; float b3 = 0; int nLEDs=strip1.numPixels()-1; //subtract one to make an odd number of LED's float dur = wait/(nLEDs/2+3); //Length of time between LED's lighting up, as defined by the total duration uint32_t color1 = strip1.Color(int(b1*c[0]), int(b1*c[1]), int(b1*c[2])); //Light up LED's in order of increasing brightness, then off uint32_t color2 = strip1.Color(int(b2*c[0]), int(b2*c[1]), int(b2*c[2])); uint32_t color3 = strip1.Color(int(b3*c[0]), int(b3*c[1]), int(b3*c[2])); for (i=0; i <= nLEDs/2+3; i++) { j=nLEDs + 1 - i; k=i; if (nLEDs/2+2>i){ strip1.setPixelColor(j, color1); strip1.setPixelColor(k, color1); } if (nLEDs/2+3>i>=1) { strip1.setPixelColor(j+1, color2); strip1.setPixelColor(k-1, color2); } if (i>=2) { strip1.setPixelColor(j+2, color3); strip1.setPixelColor(k-2, color3); } if (i==nLEDs/2+3) { strip1.setPixelColor(nLEDs/2+1, color3); } strip1.show(); delay(dur); } strip1.setPixelColor(strip1.numPixels(), color3); //light up the last LED } // LONG STRIP LIGHTS: Start at the beginning and end of the strip, and connect void colorWipe_circle(int c[], int wait) { int i; int j; int k; float b1 = .9; float b2 = .7; float b3 = .6; int nLEDs=strip2.numPixels(); float dur = wait/((nLEDs/2)); uint32_t color1 = strip2.Color(c[0], c[1], c[2]); uint32_t color2 = strip2.Color(int(b1*c[0]), int(b1*c[1]), int(b1*c[2])); uint32_t color3 = strip2.Color(int(b2*c[0]), int(b2*c[1]), int(b2*c[2])); uint32_t color4 = strip2.Color(int(b3*c[0]), int(b3*c[1]), int(b3*c[2])); for (i=0; i <= (strip2.numPixels())/2; i++) { j=nLEDs/2 + i; k=0 + i; strip2.setPixelColor(j, color1); strip2.setPixelColor(k, color1); if (i>=1) { strip2.setPixelColor(j-1, color2); strip2.setPixelColor(k-1, color2); } if (i>=2) { strip2.setPixelColor(j-2, color3); strip2.setPixelColor(k-2, color3); } if (i>=3) { strip2.setPixelColor(j-3, color4); strip2.setPixelColor(k-3, color4); } strip2.show(); delay(dur); } } // REVERSE LONG STRIP LIGHTS void colorWipe_circle_reverse(int i, int c[], int wait) { int j; int k; float b1 = .8; float b2 = 1; float b3 = 0; int nLEDs=strip2.numPixels(); float dur = wait/(nLEDs/2+2); uint32_t color1 = strip2.Color(int(b1*c[0]), int(b1*c[1]), int(b1*c[2])); uint32_t color2 = strip2.Color(int(b2*c[0]), int(b2*c[1]), int(b2*c[2])); uint32_t color3 = strip2.Color(int(b3*c[0]), int(b3*c[1]), int(b3*c[2])); j=nLEDs - i; k=nLEDs/2 - i; if ((nLEDs/2 -1)>i) { strip2.setPixelColor(j, color1); strip2.setPixelColor(k, color1); } if ((nLEDs/2)>i>=1) { strip2.setPixelColor(j+1, color2); strip2.setPixelColor(k+1, color2); } if (i>=2) { strip2.setPixelColor(j+2, color3); strip2.setPixelColor(k+2, color3); } strip2.show(); delay(dur); } // EMERGENCY LIGHTS: Lights flash on and off void emergency(int c[], int duration) { uint32_t color1 = strip1.Color(c[0], c[1], c[2]); //Color of flashing emergency lights uint32_t color2 = strip1.Color(0,0,0); //Lights off int i; int nLEDs_1=strip1.numPixels(); int nLEDs_2=strip2.numPixels(); int wait = 500; //delay between flashes int total_time = 0; //Flash the lights for the given duration of time while(total_time < duration){ for (i=0; i <= nLEDs_1; i++) { strip1.setPixelColor(i, color1); } strip1.show(); for (i=0; i < nLEDs2; i++) {strip2.setPixelColor(i, color1);} strip2.show(); delay(wait); for (i=0; i <= nLEDs_1; i++) { strip1.setPixelColor(i, color2); } strip1.show(); for (i=0; i <= nLEDs2; i++) {strip2.setPixelColor(i, color2);} strip2.show(); delay(wait); total_time = total_time + 2*wait; } } // All lights on void lights_on(int c[]) { float b1 = 0.6; uint32_t color1 = strip1.Color(b1*c[0], b1*c[1], b1*c[2]); int i; for(i=0; i