Project 1
Onderzoeksverslag
Schetsen individuele lift etage
Componenten diagram individuele lift etage
Filmpje werkende liftetage
Code liftetage
#include <Wire.h> // Define the pins for the sensor, LEDs and buttons connected to the arduino const int IRSensorPin = 2; const int DoorOpenLED = 3; const int dataPin = 5; //Pin connected to DS of 74HC595 to be used as data line const int latchPin = 6;//Pin connected to ST_CP of 74HC595 which indicates if data is sent or not const int clockPin = 7;//Pin connected to SH_CP of 74HC595 for the clock signal const int buttonUpPin = 8; const int buttonUpLED = 9; const int buttonDownPin = 10; const int buttonDownLED = 11; // Variables to keep track of the status of the sensor and buttons int liftAvailable, buttonUp, buttonDown; // Array of values which corresponds to the numbers 0 till 9 on the 7 segment display int datArray[10] = {3, 159, 37, 13, 153, 73, 65, 31, 1, 9}; void setup() { // Specify if the pins are input, output or input_pullup(connected with an internal resistor, so the input is always high and will be low when a button is pressed pinMode(buttonUpPin, INPUT_PULLUP); pinMode(buttonDownPin, INPUT_PULLUP); pinMode(IRSensorPin, INPUT); pinMode(DoorOpenLED, OUTPUT); pinMode(buttonUpLED, OUTPUT); pinMode(buttonDownLED, OUTPUT); pinMode(latchPin,OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin,OUTPUT); // Start the I2C connection with 12 as address Wire.begin(12); Wire.onRequest(requestEvent); Wire.onReceive(receiveEvent); // Show an 8 on the 7segment to test if the 7segment is working well when the elevator is turned on ShowOn7Segment(8); } void loop() { static unsigned long startTime = millis(); //Specify the starttime // When the buttons are pressed, the corresponding LEDs will turn on, the values are inverted because of the pullup resistor if(!digitalRead(buttonUpPin)){ digitalWrite(buttonUpLED, HIGH); buttonUp = 1; } if(!digitalRead(buttonDownPin)){ digitalWrite(buttonDownLED, HIGH); buttonDown = 1; } // Inverted because HIGH signal on the IRSensorPin means no elevator detected // When the Elevator is detected, 4 is shown on the 7segment which is my floor and when the elevator is on the floor for 1 second, the doors will open if(!digitalRead(IRSensorPin)){ liftAvailable = 1; // When the elevator is detected, set liftAvailable to 1 if(millis() - startTime > 1500){ // When the elevator is detected for 1,5 seconds, open the doors, turn off the LEDs and set the state of the buttons to 0 digitalWrite(DoorOpenLED, HIGH); digitalWrite(buttonUpLED, LOW); buttonUp = 0; digitalWrite(buttonDownLED, LOW); buttonDown = 0; } } else{ liftAvailable = 0; // When the elevator is not detected, set liftAvailable to 0, close the doors and reset the timer digitalWrite(DoorOpenLED, LOW); startTime = millis(); } } // to start sending data, the latchPin is set to LOW and to stop sending data, the latchPin is set to HIGH // The data is sent as serial communication, so every clock signal there will be sent 1 bit with the least signicant bit as first void ShowOn7Segment(int number){ digitalWrite(latchPin, LOW); shiftOut(dataPin,clockPin,LSBFIRST,datArray[number]); digitalWrite(latchPin, HIGH); } // When the master sends a request, set the first, second and third bit of the integer "data" to 1 or 0 dependent on the state of the buttons or the sensor // and send the data to the master with Wire.write void requestEvent(){ int data = B00000000; data += B1 * liftAvailable; data += B10 * buttonUp; data += B100 * buttonDown; Wire.write(data); } // When the master sends data, read it with Wire.read and use it to show the floor number on the 7segment void receiveEvent(int howMany){ int liftPos = Wire.read(); ShowOn7Segment(liftPos); }
Links Git
Schetsen gehele lift
Filmpje werkende lift
Testrapport gehele lift
Code master
#include <Wire.h> #include <LiquidCrystal.h> #include <Keypad.h> // Setup stepper #define IN1 2 #define IN2 3 #define IN3 4 #define IN4 5 // Setup LCD Screen #define d4 8 #define d5 9 #define d6 10 #define d7 11 #define rs 12 #define en 13 // Setup Keypad #define ROW1 22 #define ROW2 24 #define ROW3 26 #define ROW4 28 #define COL1 30 #define COL2 32 #define COL3 34 // Stepper int steps = 0; boolean clockwise = true; // LCD Screen LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // Keypad const byte ROWS = 4; //four rows const byte COLS = 3; //four columns char liftLayout[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'*', '0', '#'} }; byte rowPins[ROWS] = {ROW1, ROW2, ROW3, ROW4}; byte colPins[COLS] = {COL1, COL2, COL3}; Keypad liftKeypad = Keypad( makeKeymap(liftLayout), rowPins, colPins, ROWS, COLS); // For I2C and lift const int CONNECTED_SLAVES = 5; // Amount of slaves attached int floorButtonUp[CONNECTED_SLAVES]; // Array containing button information from the slaves int floorButtonDown[CONNECTED_SLAVES]; // Array containing button information from the slaves int floorButtonElevator[CONNECTED_SLAVES]; // Array containing button information from the master int emergencyButton; // Value containing information about the emergency button boolean liftAvailable[CONNECTED_SLAVES]; // Array containing which IR-modules are currently triggered int currentFloor = 0; // Current location of the elevator int floorStopTime = 4000; // Amount of milliseconds to stop on a floor boolean movingUp = true; // which direction the elevator is going boolean moveUp = false; // Should the motor move clockwise boolean moveDown = false; // Should the motor move counter-clockwise void setup() { Serial.begin(2000000); // Begin serial communication Wire.begin(); // Begin I2C communication lcd.begin(16, 2); // Begin LCD Scherm // Setup stepper pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); // this data is used for obtaining the information from the slaves, so set to false first for (int i = 0; i < CONNECTED_SLAVES; i++) { liftAvailable[i] = false; floorButtonUp[i] = 0; floorButtonDown[i] = 0; } // Call the keypadEvent function when event is received from the keypad liftKeypad.addEventListener(keypadEvent); } void loop() { char liftKey = liftKeypad.getKey(); // Check the input of the keypad every loop cycle // Serial.println("getAndSendDataToAllFloors"); getAndSendDataToAllFloors(); // Retrieve which buttons are pressed and send the location of the elevator to the slaves lcdDisplayHandler(currentFloor); // Change the display on the master // Serial.println("debugArray"); // debugArray(); // Print contents of the arrays to the terminal for debugging purposes // Serial.println("checkForMoveLift"); checkForMoveLift(); // Check to see whether the elevator needs to move // Serial.println("moveLift"); moveLift(); // Move the elevator to its destination // Serial.print("Current lift location is "); // Serial.println(currentFloor); // Serial.println("End of loop"); } /*********************** I2C CODE ***********************/ void getAndSendDataToAllFloors() { // For each of the connected slaves, request the currently pressed buttons and send where the elevator is and whether the door should open for (int i = 0; i < CONNECTED_SLAVES; i++) { int c = 0; // Initialize the variable for the data received from the slave Wire.requestFrom(i + 8, 1); // Request 1 byte from the slave while (Wire.available()) { // Only process the data when the slave sends data c = Wire.read(); // Load the data into the variable liftAvailable[i] = c & 1; // Put the first received bit in the liftAvailable array if (c & 1) { // If the first bit is set, change the currentfloor currentFloor = i; } floorButtonUp[i] = c >> 1 & 1; // If the second bit is set, set the value of the buttonup to 1 for the specific floor, otherwise to 0 floorButtonDown[i] = c >> 2 & 1; // If the third bit is set, set the value of the buttondown to 1 for the specific floor, otherwise to 0 } } // Send the current floor to each of the slaves for (int j = 0; j < CONNECTED_SLAVES; j++) { Wire.beginTransmission(j + 8); Wire.write(currentFloor); Wire.endTransmission(); } } /*********************** NON I2C CODE ***********************/ void debugArray() { // Prints all the arrays to the terminal for debugging purposes Serial.print("Array length is "); Serial.println(sizeof(floorButtonUp) / sizeof(int)); Serial.println("Floor button up"); for (int i = 0; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { Serial.println(floorButtonUp[i]); } Serial.println("Floor button down"); for (int i = 0; i < (sizeof(floorButtonDown) / sizeof(int)); i++) { Serial.println(floorButtonDown[i]); } Serial.println("Elevator button"); for (int i = 0; i < 6; i++) { Serial.println(floorButtonElevator[i]); } } //=============================================================== void keypadEvent(KeypadEvent liftKey) { // In case of 0 till 4, set the place in the array corresponding to the floor to 1 // When the '*' is pressed, set the emergencyButton variable to 1, so the Elevator will stop switch(liftKey){ case '0': floorButtonElevator[0] = 1; break; case '1': floorButtonElevator[1] = 1; break; case '2': floorButtonElevator[2] = 1; break; case '3': floorButtonElevator[3] = 1; break; case '4': floorButtonElevator[4] = 1; break; case '*': emergencyButton = 1; break; } } //================================================================= void checkForMoveLift() { // Main algorithm to check to where the lift should move Serial.print("Check to see if current floor wants to use lift: "); if ((floorButtonDown[currentFloor] || floorButtonUp[currentFloor] || floorButtonElevator[currentFloor]) && liftAvailable[currentFloor]) { // If there is a button pressed for the current floor and the lift is available if (movingUp && (floorButtonUp[currentFloor] || floorButtonElevator[currentFloor])) { // If lift is moving up and floorUp is pressed, stop at current floor moveUp = false; moveDown = false; Serial.println("Current floor wants to use lift"); delay(floorStopTime); floorButtonElevator[currentFloor] = 0; // If the elevator has stopped on the currentfloor, it doesn't has to stop there anymore, so set to 0 return; } else if (!movingUp && (floorButtonDown[currentFloor] || floorButtonElevator[currentFloor])) { // If lift is moving down and floorDown is pressed, stop at current floor moveUp = false; moveDown = false; Serial.println("Current floor wants to use lift"); delay(floorStopTime); floorButtonElevator[currentFloor] = 0; // If the elevator has stopped on the currentfloor, it doesn't has to stop there anymore, so set to 0 return; } else if (movingUp) { // if lift is moving up and buttonDown is pressed and there are no buttons pressed above me, stop at current floor boolean stopHere = true; for (int i = currentFloor + 1; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { if (floorButtonUp[i] || floorButtonDown[i] || floorButtonElevator[i]) { stopHere = false; break; } } if (stopHere) { moveUp = false; moveDown = false; Serial.println("Current floor wants to use lift"); delay(floorStopTime); floorButtonElevator[currentFloor] = 0; // If the elevator has stopped on the currentfloor, it doesn't has to stop there anymore, so set to 0 return; } } else if (!movingUp) { // if lift is moving down and buttonUp is pressed and there are no buttons pressed below me, stop at current floor boolean stopHere = true; for (int i = currentFloor - 1; i >= 0; i--) { if (floorButtonUp[i] || floorButtonDown[i] || floorButtonElevator[i]) { stopHere = false; break; } } if (stopHere) { moveUp = false; moveDown = false; Serial.println("Current floor wants to use lift"); delay(floorStopTime); floorButtonElevator[currentFloor] = 0; // If the elevator has stopped on the currentfloor, it doesn't has to stop there anymore, so set to 0 return; } } else { Serial.println("current floor wants to go in a different direction, skipping floor"); } } else { Serial.println("Current floor does not want to use the lift"); } Serial.print("Check for other floor wants to use lift: "); if (movingUp) { // When the lift is moving up // check floors above current floor to see if anyone wants to go up for (int i = currentFloor; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { // sizeof(int) used bacause arduino is a bitch https://www.arduino.cc/en/Reference/Sizeof if (floorButtonUp[i] || floorButtonElevator[i]) { Serial.println("A floor above me wants to go up"); moveUp = true; moveDown = false; movingUp = true; return; } } //==================================================================== // check floors above current floor to see if anyone wants to go down for (int i = currentFloor; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { // sizeof(int) used bacause arduino is a bitch https://www.arduino.cc/en/Reference/Sizeof if (floorButtonDown[i] || floorButtonElevator[i]) { Serial.println("A floor above me wants to go down"); moveUp = true; moveDown = false; movingUp = true; return; } } //============================================================================= // check floor below current floor to see if anyone wants to go down for (int i = currentFloor; i >= 0; i--) { if (floorButtonDown[i] || floorButtonElevator[i]) { Serial.println("A floor below me wants to go up"); moveUp = false; moveDown = true; movingUp = false; return; } } // check floors below current floor to see if anyone wants to go up for (int i = currentFloor; i >= 0; i--) { if (floorButtonUp[i] || floorButtonElevator[i]) { Serial.println("A floor below me wants to go down"); moveUp = false; moveDown = true; movingUp = false; return; } } Serial.println("Nothing wants to use lift"); } else if (!movingUp) { // When the lift is moving down // check floors below current floor to see if anyone wants to go up for (int i = currentFloor; i >= 0; i--) { if (floorButtonUp[i] || floorButtonElevator[i]) { Serial.println("A floor below me wants to go up"); moveUp = false; moveDown = true; movingUp = false; return; } } // check floor below current floor to see if anyone wants to go down for (int i = currentFloor; i >= 0; i--) { if (floorButtonDown[i] || floorButtonElevator[i]) { Serial.println("A floor below me wants to go down"); moveUp = false; moveDown = true; movingUp = false; return; } } //=============================================================== // check floors above current floor to see if anyone wants to go down for (int i = currentFloor; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { if (floorButtonDown[i] || floorButtonElevator[i]) { Serial.println("A floor above me wants to go down"); moveUp = true; moveDown = false; movingUp = true; return; } } //=============================================================== // check floors above current floor to see if anyone wants to go up for (int i = currentFloor; i < (sizeof(floorButtonUp) / sizeof(int)); i++) { if (floorButtonUp[i] || floorButtonElevator[i]) { Serial.println("A floor above me wants to go up"); moveUp = true; moveDown = false; movingUp = true; return; } } } Serial.println("Nothing wants to use lift"); moveUp = false; moveDown = false; } void moveLift() { // Controls the lift controller if (moveUp) { liftController(true); } else if (moveDown) { liftController(false); } } void liftController(boolean up) { // Controls how many the stepping motor should rotate clockwise = !up; if (emergencyButton) { // When the emergency button is pressed, stop moving the motor until the arduino resets return; } for (int i = 0; i < 100; i++) { // with this for loop the motor moves more between requests. stepper(); delayMicroseconds(2000); char liftKey = liftKeypad.getKey(); // Also check the input of the keypad while the elevator is moving } } // http://www.nmbtc.com/step-motors/engineering/full-half-and-microstepping/ // Using two-phase fullstep void stepper() { // controls the steppenmotor switch (steps) { case 0: digitalWrite(IN1, HIGH); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break; case 1: digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); break; case 2: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, HIGH); break; case 3: digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); break; default: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break; } if (clockwise) { steps++; } else { steps--; } if (steps > 3) { steps = 0; } else if (steps < 0) { steps = 3; } } void lcdDisplayHandler(int currentFloor){ // Print the status of the elevator on the lcd screen lcd.setCursor(0, 0); lcd.print("Lift: "); lcd.setCursor(6, 0); if(moveUp){ lcd.print("Going Up "); } else if(moveDown){ lcd.print("Going Down"); } else{ lcd.print("Idle "); } // Print the current floor on the lcd screen lcd.setCursor(0, 1); lcd.print("Current floor:"); lcd.setCursor(14, 1); lcd.print(currentFloor); }