• Home
  • Projecten
    Project 0 Project 1 Project 2 Project 3 Project 4

Project 1

Onderzoeksverslag

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

Persoonlijk Groep

Schetsen gehele lift

Filmpje werkende lift

Testrapport gehele lift

Testrapport

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);
            }
          

© Hogeschool Rotterdam