-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathelevator.h
239 lines (200 loc) · 5.79 KB
/
elevator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#include "inside.h"
#ifndef LINUX
#include <Windows.h>
#endif
// #define DEBUG_ELEVATOR
static int power_on = 0; // 엘리베이터 전원 on/off 체크
static int cur_floor; // 현재 층
enum {
ELEVATOR_DOWN = 0,
ELEVATOR_UP,
ELEVATOR_STOPPED,
};
// 엘리베이터 초기화
int elevator_power_on(void) {
int i;
int ok = 1;
// 내부 버튼들 초기화
if (power_on != 1) {
for (i = 0; i < TOTAL_FLOORS; i++)
inside.floor_button[i] = 0;
inside.open_button = 0;
inside.close_button = 0;
// FIXME : 추후 파일 입출력을 통해 초기 값 저장하는 방법 구현
cur_floor = 1;
// 엘리베이터 전원 on
power_on = 1;
#ifdef DEBUG_ELEVATOR
printf("elevator_power_on OK!\n");
#endif
return ok;
}
printf("elevator_power_on failed!\n");
ok = 0;
return ok;
}
void elevator_print_manual(void) {
printf("\n\
메뉴얼\n\n\
층-1 2 3 4 5 6 7 8 9 10\n\
bt:1 2 3 4 5 6 7 8 9 0\n\
▲:q w e r t y u i o p\n\
▼:a s d f g h j k l ;\n\
\n\
층-11 12 13 14 15 16 17 18 19 20\n\
bt:! @ # $ %% ^ & * ( )\n\
▲:Q W E R T Y U I O P\n\
▼:A S D F G H J K L :\n\
\n\
◀▶: z 또는 Z\n\
▶◀: x 또는 X\n\
\n");
}
// 엘리베이터 활성된 버튼들 출력
void elevator_print_active_buttons(void) {
int i;
printf("Active buttons : ");
for (i = 0; i < TOTAL_FLOORS; i++) {
if (inside.floor_button[i])
printf("%d ", i + 1);
}
if (inside.open_button)
printf("◀▶ ");
if (inside.close_button) {
printf("▶◀ ");
}
printf("\n");
}
// 엘리베이터 led 출력 함수
void elevator_print_led(int is_up) {
switch (is_up) {
case ELEVATOR_DOWN:
printf("▼ ");
break;
case ELEVATOR_UP:
printf("▲ ");
break;
case ELEVATOR_STOPPED:
break;
}
printf("%d\n", cur_floor);
}
void elevator_print_to_screen(int is_up) {
#ifndef DEBUG_ELEVATOR
#ifdef LINUX
system("clear");
#else
system("cls");
#endif
#endif /* DEBUG_ELEVATOR */
elevator_print_active_buttons();
printf("Current floor : ");
elevator_print_led(is_up);
}
// 엘리베이터 문 열기 함수
void elevator_door_open(void) {
clock_t timer_start;
int door_delay = 1200 / ELEVATOR_SPEED; // 출입문 작동 지연
inside.floor_button[cur_floor - 1] = 0; // 해당 층 수 버튼 초기화
elevator_print_to_screen(ELEVATOR_STOPPED);
inside.open_button = 0;
elevator_print_to_screen(ELEVATOR_STOPPED);
printf("Door Opend!\n");
// 출입문 열기 지연
wait(door_delay);
// 타이머 활성화
timer_start = clock();
while (1) {
inside.open_button = 0;
inside.close_button = 0;
// 버튼 입력 활성화
inside_button_press();
// 열기 버튼이나 현재 층과 같은 버튼 눌리면 출입문 재개방
if (inside.open_button || inside.floor_button[cur_floor - 1]) {
inside.floor_button[cur_floor - 1] = 0; // 해당 층 수 버튼 초기화
elevator_print_to_screen(ELEVATOR_STOPPED);
printf("Door Re-opend!\n");
inside.open_button = 0;
continue;
}
// 닫기 버튼 눌리면 출입문 닫음
if (inside.close_button) {
elevator_print_to_screen(ELEVATOR_STOPPED);
printf("Force Door Closd!\n");
inside.close_button = 0;
// 출입문 닫기 지연
wait(door_delay);
return;
}
// 시간 만료되면 출입문 닫음
// ELEVATOR_SPEED 가 1인 경우 3초 후 만료됨
if (clock() - timer_start > 3 * CLOCKS_PER_SEC / ELEVATOR_SPEED) {
elevator_print_to_screen(ELEVATOR_STOPPED);
printf("Door Closd!\n");
inside.close_button = 0;
// 출입문 닫기 지연
wait(door_delay);
return;
}
}
}
// 엘리베이터 올라가기 함수
void elevator_up(void) {
int i;
// 올라가는 방향으로 눌린 버튼이 있는지 확인 후 없으면 함수 종료
if (!inside_button_check(cur_floor, ELEVATOR_UP))
return;
// 엘리베이터가 정지해 있을때 열림 버튼에 대한 확인
// 아래 for 문이 루프를 돌고 있는동안엔 이곳을 못오기 때문에
// 엘리베이터가 정지해 있는 동안에만 입력을 확인함
if(inside.open_button)
elevator_door_open();
for (i = cur_floor - 1; i < TOTAL_FLOORS; i++) {
#ifdef DEBUG_ELEVATOR
printf("elevator_up() called\n");
#endif
// 열기/닫기 버튼 비활성화 되지 않는 버그 수정
inside.open_button = 0;
inside.close_button = 0;
elevator_print_to_screen(ELEVATOR_UP);
if (inside.floor_button[i]) { // 버튼이 눌린 층을 발견하면
elevator_door_open(); // 출입문 개방
}
// 남은 버튼이 있는지 확인
// 올라가는 방향으로 더 이상 버튼 없으면 함수 종료
if (!inside_button_check(cur_floor, ELEVATOR_UP))
return;
inside_button_press(); // 버튼 입력 대기 및 엘리베이터 이동 지연
cur_floor++;
}
}
// 엘리베이터 내려가기 함수
void elevator_down(void) {
int i;
// 내려가는 방향으로 눌린 버튼이 있는지 확인 후 없으면 함수 종료
if (!inside_button_check(cur_floor, ELEVATOR_DOWN))
return;
// 엘리베이터가 정지해 있을때 열림 버튼에 대한 확인
// 아래 for 문이 루프를 돌고 있는동안엔 이곳을 못오기 때문에
// 엘리베이터가 정지해 있는 동안에만 입력을 확인함
if (inside.open_button)
elevator_door_open();
for (i = cur_floor - 1; i >= 0; i--) {
#ifdef DEBUG_ELEVATOR
printf("elevator_down() called\n");
#endif
// 열기/닫기 버튼 비활성화 되지 않는 버그 수정
inside.open_button = 0;
inside.close_button = 0;
elevator_print_to_screen(ELEVATOR_DOWN);
if (inside.floor_button[i]) { // 버튼이 눌린 층을 발견하면
elevator_door_open(); // 출입문 개방
}
// 남은 버튼이 있는지 확인
// 내려가는 방향으로 더 이상 버튼 없으면 함수 종료
if (!inside_button_check(cur_floor, ELEVATOR_DOWN))
return;
inside_button_press(); // 버튼 입력 대기 및 엘리베이터 이동 지연
cur_floor--;
}
}