├── Inf
├── SCHEMATICS.jpg
└── link_on_video.jpg
├── README.md
├── PanelControll
└── PanelControll.ino
└── Elevator
└── Elevator.ino
/Inf/SCHEMATICS.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlieksieievYurii/Elevator/HEAD/Inf/SCHEMATICS.jpg
--------------------------------------------------------------------------------
/Inf/link_on_video.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlieksieievYurii/Elevator/HEAD/Inf/link_on_video.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Elevator
2 | ## Intro
3 | The project "Elevator" is constructed on platform Arduino. I builded the elevator the which principle of operation
4 | is the same as the real elevator. The elevator has 4 floors, a cabin and a panel control.
5 |
6 | [](https://www.youtube.com/watch?v=cfQdmKm0qJA)
7 |
8 | ## Components
9 | Here are the components I use:
10 |
11 | * Arduino uno
12 | * Arduino nano
13 | * Reed switch(4x)
14 | * Button switches(10x)
15 | * Servomotor
16 | * Lcd display 16x2 I2C
17 | * Driver module ULN2003 for step mottor
18 | * Step motor 28-BYJ48
19 | * Buzzer
20 | ## Schematics
21 |
22 |
23 | ## Description of schematic:
24 | * **F**n (n = 1,2,3,4) - There are sensors (Reed switch) which connected on every floor. Each sensor is connected by a resistor and link up with analog input A0 on Arduino Uno. Each sensor when is active has own signal from interval (0;1024). Level of signal depends on the resisting of resistor.
25 |
26 | * **C**n (n = 1,2,3,4) - There are buttons of calling the elevator (Call bar). They are connected by resistors with different nominals and link up to analog input A1 on Arduino Uno. The call bar has two buttons (only on 2,3 floors).These buttons are used to call Elevator, the dependency wherever you want to go (up/down) - It's not implemented at the moment! Also each floor has one led which light up when this floor is called.
27 |
28 | * **CS** (Calibration Switch) is a calibration switch located on the first floor. When the Elevator starts to work, first and foremost, it is calibrating (down to the first floor, while CS is not pressed).
29 |
30 | * **CB**n ( n = 1,2,3,4) - There are the Elevator call buttons which are located in the cabin. They also are connected by resistors with different nominals and link up to analog input A0 on Arduino nano(In the Cabin).
31 |
32 | * **Motor** - For this project I use a step motor 28-BYJ48 with connected by driver module ULN2003.
33 |
34 | * **Display** - I connected the Lcd display 16x2 by module I2C. The display shows the floor at the moment.
35 |
36 | * **Servor** - The servo drive is used to open and close the door.
37 |
38 | * **Buzzer** - It is used to signal that the Elevator has arrived.
39 |
40 | ## Codes
41 |
42 | * Code of elevator:
43 | https://github.com/AlieksieievYurii/Elevator/blob/master/Elevator/Elevator.ino
44 |
45 | Also you have to download the library LiquidCrystal_I2C for lcd display.
46 |
47 | * Code of the cabin:
48 | https://github.com/AlieksieievYurii/Elevator/blob/master/PanelControll/PanelControll.ino
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/PanelControll/PanelControll.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #define SIGNAL_PIN 8
3 | #define BUTTON_SIGNAL A0
4 | #define DOOR_PIN 3
5 |
6 | ///////COMANDS FOR ELEVATOR//////
7 | #define DOOR_IS_CLOSED 1
8 | #define DOOR_IS_OPENED 2
9 | #define CALL_ON_FLOOR 3
10 |
11 | char command[2]={'0','0'};
12 |
13 | unsigned short calledFloor = 0;
14 | boolean flagCallFloor = true;
15 |
16 | unsigned long timeDelay = 0;
17 | boolean isElevatorErrived = true;
18 |
19 | Servo door;
20 |
21 | void setup() {
22 |
23 | pinMode(SIGNAL_PIN,OUTPUT);
24 | pinMode(BUTTON_SIGNAL,INPUT);
25 |
26 | door.attach(DOOR_PIN);
27 |
28 | Serial.begin(9600);
29 | closeDoor();
30 |
31 | for(byte i = 0; i < 5; i++)
32 | {
33 | digitalWrite(SIGNAL_PIN,HIGH);
34 | delay(100);
35 | digitalWrite(SIGNAL_PIN,LOW);
36 | delay(100);
37 | }
38 |
39 | }
40 |
41 | void loop() {
42 | readSerial(command);
43 | decodeCommand(command);
44 |
45 | calledFloor = whatFloorCall();
46 |
47 | if(calledFloor != 0 && flagCallFloor)
48 | {
49 | sendCommand(CALL_ON_FLOOR);
50 | calledFloor = 0;
51 | flagCallFloor = false;
52 | }
53 |
54 | if( isElevatorErrived && millis() - timeDelay >= 5000)
55 | {
56 | closeDoor();
57 | isElevatorErrived = false;
58 | }
59 |
60 | }
61 |
62 | void decodeCommand(char str[2])
63 | {
64 | if(str[0] == '0' && str[1] == '0')
65 | return;
66 |
67 | if(str[0] == 'e' && str[1] == 'f')
68 | {
69 | elevatorIsArrived();
70 | str[0] = '0';
71 | str[1] = '0';
72 | }
73 |
74 | }
75 |
76 | void elevatorIsArrived()
77 | { isElevatorErrived = true;
78 | digitalWrite(SIGNAL_PIN,HIGH);
79 | delay(500);
80 | digitalWrite(SIGNAL_PIN,LOW);
81 | openDoor();
82 | flagCallFloor = true;
83 | timeDelay = millis();
84 | }
85 |
86 | void readSerial(char str[2])
87 | {
88 | str[0] = '0';
89 | str[1] = '0';
90 |
91 | if(Serial.available())
92 | {
93 | delay(100);
94 | byte i = 0;
95 | while(Serial.available() && i<2)
96 | str[i++] = Serial.read();
97 | }
98 | }
99 |
100 | void sendCommand(short codeOfCommand)
101 | {
102 | char com[2] = {'0','0'};
103 | switch(codeOfCommand)
104 | {
105 | case DOOR_IS_CLOSED:
106 | com[0] = 'd';
107 | com[1] = 'c';
108 | break;
109 |
110 | case DOOR_IS_OPENED:
111 | com[0] = 'd';
112 | com[1] = 'o';
113 | break;
114 |
115 | case CALL_ON_FLOOR:
116 | com[0] = 'c';
117 | itoa(calledFloor,&com[1],10);
118 | //com[1] = (char)calledFloor;
119 | break;
120 | }
121 | Serial.write(com,2);
122 | }
123 |
124 | void openDoor()
125 | {
126 | door.write(180);
127 | sendCommand(DOOR_IS_OPENED);
128 |
129 | }
130 |
131 | void closeDoor()
132 | {
133 | door.write(0);
134 | sendCommand(DOOR_IS_CLOSED);
135 | }
136 |
137 | short whatFloorCall()
138 | {
139 | short value = analogRead(BUTTON_SIGNAL);
140 |
141 | if(925 <= value && value <= 935) return 1;
142 | else if(885 <= value && value <= 895) return 2;
143 | else if(759 <= value && value <= 769) return 3;
144 | else if(696 <= value && value <= 706) return 4;
145 | else return 0;
146 | }
147 |
--------------------------------------------------------------------------------
/Elevator/Elevator.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | /////INIT hardware part////
6 | #define CALL_BUTTONS A1 //--------Here is connection buttons of colling elevator
7 | #define FLOOR_SENSORS A0 //--------Here is connection sensors which are localed on floors
8 | #define CALIBRATION_SENSOR 2 //------Here is connected button for instalation the elevator on first floor
9 | ///////////////////////////
10 | #define DEFAULT_SPEED 300 // Default speed of elevator
11 | #define SLOW_SPEED 150 // Default speed of elevator when it is landing
12 | #define N 4 //Number of floor
13 |
14 | ////////Flags of moving the elevator//////////
15 | #define MOVING_UP 1 //This flag means that the elevator is moving up
16 | #define MOVING_DOWN -1 //This flag means that the elevator is moving down
17 | #define NOT_MOVING 0
18 | /////////////////////////////////////////////
19 |
20 | #define NOT -1
21 |
22 | ///////COMANDS FOR PANEL_CONTROL ///////
23 | #define ELEVATOR_IS_ERIVED 1
24 |
25 | ////////////////Init motor///////////////////////
26 | unsigned short stepsPerRevolution = 64;
27 | Stepper myStepper(stepsPerRevolution, 8,10,9,11); // Conected Step motor
28 | /////////////////////////////////////////////////
29 |
30 | LiquidCrystal_I2C lcd(0x27,16,2);//Connected LDC display
31 |
32 | short registeredFloor;
33 | short arrayFloor[N] = {-1,-1,-1,-1};
34 | short ledFloor[N] = {7,6,5,4};
35 | short executableFloor = NOT; // -1 it means not called floors
36 | boolean canWork = false;
37 | boolean landed = false;
38 | boolean waitForNext = true;
39 | short flagMoving = NOT_MOVING;
40 | short calledFloorFromCabine = NOT;
41 |
42 |
43 | boolean flagPressSameBtn = true;
44 |
45 | void setup() {
46 | Serial.begin(9600);
47 | pinMode(CALL_BUTTONS,INPUT);
48 | pinMode(FLOOR_SENSORS,INPUT);
49 | pinMode(CALIBRATION_SENSOR, INPUT);
50 |
51 | for(byte i = 0; i < N; i++)
52 | pinMode(ledFloor[i],OUTPUT);
53 |
54 | myStepper.setSpeed(DEFAULT_SPEED);
55 |
56 | lcd.begin();
57 | lcd.backlight();
58 | printInf();
59 | calibration();
60 | }
61 | void loop()
62 | {
63 | readComFromPanelControl();
64 |
65 | registerFloor();
66 | writeTurn();
67 |
68 | if(waitForNext && canWork)
69 | nextFloor();
70 |
71 | if(executableFloor != NOT && canWork)
72 | moveElevator();
73 |
74 | delay(10);
75 | }
76 |
77 | void nextFloor()
78 | {
79 |
80 | if(calledFloorFromCabine != NOT && calledFloorFromCabine != registeredFloor )
81 | {
82 | executableFloor = calledFloorFromCabine;
83 | landed = false;
84 | waitForNext = false;
85 | return;
86 | }
87 |
88 | if(arrayFloor[0] == NOT)
89 | {
90 | for(byte i = 0; i < N; i++)
91 | {
92 | swipeArray(arrayFloor);
93 | if(arrayFloor[0] != NOT)
94 | break;
95 | }
96 | }
97 | executableFloor = arrayFloor[0];
98 |
99 | if(executableFloor != NOT)
100 | {
101 | swipeArray(arrayFloor);
102 | landed = false;
103 | waitForNext = false;
104 | }
105 |
106 | }
107 |
108 | void swipeArray(short * arrayFloor){
109 | for(byte i = 0; i < N - 1; i++)
110 | arrayFloor[i] = arrayFloor[i+1];
111 | arrayFloor[N-1] = NOT;
112 | }
113 |
114 | void moveElevator()
115 | {
116 |
117 | if(executableFloor == registeredFloor && !landed)
118 | {
119 | if(flagMoving == MOVING_UP)
120 | moveUpMiddle();
121 | else if(flagMoving == MOVING_DOWN)
122 | moveDownMiddle();
123 |
124 | ElevatorErrived(executableFloor);
125 | return;
126 | }
127 |
128 | if(executableFloor > registeredFloor)
129 | {
130 | moveUp();
131 | flagMoving = MOVING_UP;
132 | }else if(executableFloor < registeredFloor)
133 | {
134 | moveDown();
135 | flagMoving = MOVING_DOWN;
136 | }
137 | }
138 |
139 | void ElevatorErrived(short errivedOnFloor)
140 | {
141 |
142 | for(byte i = 0; i < N; i++)
143 | if(arrayFloor[i] == errivedOnFloor)
144 | arrayFloor[i] = NOT;
145 |
146 | executableFloor = NOT;
147 | turnOffLedOnFloor(errivedOnFloor);
148 | sendCommandToPanelControl(ELEVATOR_IS_ERIVED);
149 | flagMoving = NOT_MOVING;
150 | waitForNext = true;
151 |
152 | if(calledFloorFromCabine == registeredFloor)
153 | calledFloorFromCabine = NOT;
154 |
155 | landed = true;
156 | canWork = false;
157 | }
158 |
159 | void turnOffLedOnFloor(short errivedOnFloor)
160 | {
161 | digitalWrite(ledFloor[errivedOnFloor-1],LOW);
162 | }
163 |
164 | void writeTurn()
165 | {
166 | short localCalledFloorExpected = calledFloor();
167 |
168 | ///////if we call the elevator on floor wheme we are, elevator will just send command to the cabin for opening door
169 | if( (localCalledFloorExpected == registeredFloor && flagPressSameBtn && executableFloor == NOT) ||
170 | (calledFloorFromCabine == registeredFloor && executableFloor == NOT && flagPressSameBtn ))
171 | {
172 | digitalWrite(ledFloor[localCalledFloorExpected - 1],HIGH);
173 | delay(10);
174 | digitalWrite(ledFloor[localCalledFloorExpected - 1],LOW);
175 | sendCommandToPanelControl(ELEVATOR_IS_ERIVED);
176 | calledFloorFromCabine = NOT;
177 | flagPressSameBtn = false;
178 | return;
179 | }
180 |
181 | ///here we create queue calling the elevator
182 | if(localCalledFloorExpected != NOT)
183 | {
184 | if(executableFloor == NOT && localCalledFloorExpected == registeredFloor)
185 | return;
186 |
187 | //if called floor is in queue, it will not add to queue again
188 | for (byte i = 0; i < 4;i++)
189 | if (localCalledFloorExpected == arrayFloor[i])
190 | return;
191 |
192 | for (byte i = 0; i < 4; i++)
193 | if (arrayFloor[i] == -1)
194 | {
195 | arrayFloor[i] = localCalledFloorExpected;
196 | digitalWrite(ledFloor[abs(localCalledFloorExpected)-1],HIGH);// Turn on led on floor which called
197 | return;
198 | }
199 | }
200 | }
201 | void calibration()
202 | {
203 | for (byte i = 0; i < N; i++)
204 | digitalWrite(ledFloor[i], HIGH);
205 | lcd.setCursor(0,0);
206 | lcd.print(" CALIBRATION...");
207 |
208 | while(!digitalRead(CALIBRATION_SENSOR))
209 | myStepper.step(-10);
210 |
211 | for (byte i = 0; i < N; i++)
212 | digitalWrite(ledFloor[i], LOW);
213 |
214 | registeredFloor = 1;
215 | lcd.clear();
216 | lcd.print("Floor:1");
217 | }
218 |
219 | void moveUp()
220 | {
221 | myStepper.step(50);
222 | }
223 |
224 | void moveUpMiddle()
225 | {
226 | myStepper.setSpeed(SLOW_SPEED);
227 |
228 | switch(registeredFloor)
229 | {
230 | case 2:
231 | myStepper.step(950);
232 | break;
233 | case 3:
234 | myStepper.step(900);
235 | break;
236 | case 4:
237 | myStepper.step(900);
238 | break;
239 | }
240 | myStepper.setSpeed(DEFAULT_SPEED);
241 | }
242 |
243 | void moveDownMiddle()
244 | {
245 | myStepper.setSpeed(SLOW_SPEED);
246 | switch(registeredFloor)
247 | {
248 | case 1:
249 | myStepper.step(-700);
250 | break;
251 | case 2:
252 | myStepper.step(-950);
253 | break;
254 | case 3:
255 | myStepper.step(-950);
256 | break;
257 | case 4:
258 | myStepper.step(-650);
259 | break;
260 | }
261 | myStepper.setSpeed(DEFAULT_SPEED);
262 | }
263 |
264 | void moveDown()
265 | {
266 | myStepper.step(-50);
267 | }
268 |
269 | void registerFloor()
270 | {
271 | unsigned short value = analogRead(FLOOR_SENSORS);
272 | short bufRegisteredFloor = 0;
273 | if(value >= 221 && value <= 231) bufRegisteredFloor = 4;
274 | else if(value >= 300 && value <= 310) bufRegisteredFloor = 3;
275 | else if(value >= 395 && value <= 405) bufRegisteredFloor = 2;
276 | else if(value >= 691 && value <= 701) bufRegisteredFloor = 1;
277 |
278 | if(bufRegisteredFloor != 0 && bufRegisteredFloor != registeredFloor)
279 | {
280 | registeredFloor = bufRegisteredFloor;
281 | printFloor();
282 | }
283 | }
284 |
285 | short calledFloor()
286 | {
287 | short value = analogRead(CALL_BUTTONS);
288 |
289 | if(value >= 85 && value <= 95) return 4;
290 | else if(value >= 333 && value <= 345) return 3;
291 | else if(value >= 175 && value <= 185) return 3;
292 | else if(value >= 505 && value <= 515) return 2;
293 | else if(value >= 402 && value <= 412) return 2;
294 | else if(value >= 670 && value <= 705) return 1;
295 | else return NOT;
296 |
297 | }
298 |
299 | void printFloor()
300 | {
301 | lcd.clear();
302 | lcd.setCursor(0,0);
303 | lcd.print("Floor:");
304 | lcd.print(registeredFloor);
305 | }
306 |
307 | void printInf()
308 | {
309 | lcd.print(" Elevalor");
310 | lcd.setCursor(0,1);
311 | lcd.print("Y.Alieksieiev");
312 | delay(3000);
313 | //lcd.setCursor(0,1);
314 | //lcd.println("S.Michalewski ");
315 | //delay(2000);
316 | lcd.clear();
317 | }
318 |
319 | void sendCommandToPanelControl(short command)
320 | {
321 | char str[2] = {'0','0'};
322 | switch(command)
323 | {
324 | case ELEVATOR_IS_ERIVED:
325 | str[0] = 'e';
326 | str[1] = 'f';
327 | break;
328 | }
329 |
330 | Serial.write(str,2);
331 | }
332 |
333 | void readComFromPanelControl()
334 | {
335 | if(!Serial.available())
336 | return;
337 |
338 | byte i = 0;
339 | char str[2] = {'0','0'};
340 | delay(100);
341 | while(Serial.available())
342 | str[i++] = Serial.read();
343 |
344 | if(str[0] == 'd' && str[1] == 'o')
345 | canWork = false;
346 | else if(str[0] == 'd' && str[1] == 'c')
347 | {
348 | canWork = true;
349 | flagPressSameBtn = true;
350 | }else if(str[0] == 'c')
351 | {
352 | calledFloorFromCabine = str[1] - '0';
353 | }
354 | }
355 |
--------------------------------------------------------------------------------