# 이분 검색를 사용한 제곱근의 근사치 찾기
x = 25
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon:
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses = ', numGuesses)
print(ans, 'is close to square root of', x)
출력결과
numGuesses = 13
5.00030517578125 is close to square root of 25
한 개의 변수를 가진 다항식은 0이거나 0이 아닌 항들의 합이다. 각 항은 상수와 음수가 아닌 값만큼 거듭제곱된 변수의 곱으로 이루어져 있다. 예를 들어 3X^2 + 2X +3이라는 다항식에서 첫 번째 항 3x^2는 상수 3과 제곱된 변수 x의 곱이다.
만약 다항식 p와 실수 r이 있다면 x=r일 때 다항식의 값을 P(r)이라고 할 것이다. 방정식 p=0의 해는 p의 근이다. 즉 P(r)=0이 될 때의 r인 것이다. 그러므로 예를 들어 24의 제곱근의 근사값을 찾는 문제가 주어졌을 때는 x^2 - 24 = 0에서 x의 값을 찾으면 된다.
뉴턴은 어떤 값 guess가 다항식의 근의 근사값일 때 p'가 p의 1차 도함수라고 한다면 guess - P(guess)/P'(guess)가 더 나은 근사값이 된다는 원리를 증명하였다. 어떤 상수 k와 계수 c가 있을 때 cx^2 + k의 1차 도함수는 2cx이다. 또 x^2 - k의 1차 도함수는 2x이다. 그러므로 현재의 추측 값에서 다시한번 y - (y^2 - k)/2y를 구하여 더 나은 근사값을 구할 수 있음을 알 수 있다. 이것을 연속 근사법(successive approximation)이라고 한다.
다음 코드는 이런 방법으로 제곱근의 근사값을 좀 더 빠르게 구하는 것을 구현한 코드이다.
epsilon = 0.01
k = 24.0
i = 0
guess = k/2.0
while abs(guess*guess - k) >= epsilon:
i = i + 1
guess = guess - (((guess**2) - k)/(2*guess))
print('Square root of', k, 'is about', guess)
print('반복회수 : ', str(i))
출력결과
Square root of 24.0 is about 4.8989887432139305
반복회수 : 4
준비품 : 아우이노UNO R3, TSOP1838 IR 적외선 센서, 적외선 리모컨, LED_red, LED_blue, 릴레이 모듈, 300옴 저항_2개
아두이노UNO
적외선 리모컨
LED_red_blue
릴레이 모듈
아두이노 우노 R3
TSOP1838 IR 적외선 센서
적외선 리모컨
LED
릴레이 모듈
300옴 저항
300옴 저항
회로 결선도
아두이노
적외선 센서
릴레이 모듈
LED red
LED blue
+5V
VCC
VCC
GND
GND
GND
GND
GND
A0
S
D7
IN
D8
"+"
D9
"+"
아두이노와 적외선센서 회로연결
위 회로에서 릴레이 모듈의 VCC를 아두이노의 +5V에 연결하고, 릴레이 모듈의 IN을 아두이노핀의 A0에 연결한다.
다음은 실지 회로도이다.
아두이노, 적외선 센서, 릴레이모듈, LED 연결 회로
위와 같이 회로를 구성하고 아두이노IDE에 코드를 작성한다.
코딩
#include <IRremote.h> // 적외선 함수 라이브러리 선언
int RECV_PIN = A0; // 적외선 센서 신호를 아날로그핀 A0로 송수신 함
int led_red = 8; // LED red를 D8로 선언
int led_blue = 9; // LED blue를 D9로 선언
int swich = 7; // 릴레이 입력을 D7로 선언
IRrecv irrecv(RECV_PIN); // IRremote를 사용하기 위해 irrecv객체 생성
decode_results results; // 디코드한 결과 값
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(led_red, OUTPUT); // LED red
pinMode(led_blue, OUTPUT); // LED blue
pinMode(swich, OUTPUT); // swich_on/off
}
void loop(){
if(irrecv.decode(&results)){ // 적외선 리모컨의 신호를 받을 때
Serial.println(results.value, HEX); // 결과값을 HEX로 출력
switch (results.value){
case 0x80c: digitalWrite(8, HIGH); break; //전원버튼이 눌리면 LED_red ON
case 0xc: digitalWrite(8, LOW); break; //전원버튼이 다시 눌리면 LED_red OFF
case 0x80b: digitalWrite(9, HIGH); break; //AV/TV 버튼이 눌리면 LED_blue ON
case 0xb: digitalWrite(9, LOW); break; //AV/TV버튼이 눌리면 LED_blue OFF
case 0x80d: digitalWrite(7, HIGH); break; // CH_up버튼이 눌리면 swich ON
case 0xd: digitalWrite(7, LOW); break; // CH_down버튼이 눌리면 swich OFF
}
irrecv.resume(); // 수광 다이오드 다음 값 받기
}
}
위의 코딩에서 HEX값인 0x80c, 0xc, 0x80b, 0xb, 0x80d, 0xd는 아두이노를 USB케이블을 연결하고 실행한 다음 리모컨으로 버튼을 눌렀을 때 아두이노 IDE의 툴/ 시리얼 모니터를 실행하면 해당버튼을 눌렀을 때에 따른 HEX값이 출력된다.
리모컨 버튼 기능마다 HEX값이 다르므로 시리얼 모니터를 확인하고 출력된 값을 코딩에 입력하면 된다.
해당 프로그램을 실행시킨 후 왼쪽 상단을 보면 노란색과 초록색의 톱니바퀴 모양의 Configuration아이콘을 눌러준다.
Options 창에서 USB to TTL 컨버터와 연결된 Port 번호를 입력하고, Baud Rate는 9600으로 맞춰준다. (장치 관리자에서 확인한 포트 번호를 입력해준다. COM4)
Send display는 Hex format으로 Receive display는 Char Format으로 설정해준 후, OK 버튼을 눌러준다. 이 후 Hex 명령어로 ‘AA36’을 Send 버튼을 통해 보내주었을 때, Common Mode라는 답변이 온다면, 제대로 연결된 것이다
Hex 명령어로 ‘AA11’을 보내주시면, 음성 명령어 녹음이 시작된다.
음성인식 모듈의 마이크에 대고 명령어를 녹음해주시면 된다.
각 명령의 길이는 최대 1300ms(1.3초)이므로, 단어로 명령을 넣는 게 좋다.
녹음을 시작하면, 한 그룹의 5가지 음성 명령 녹음을 끝내기 전까지 녹음 과정을 멈출 수 없는 점 유의해 주시기 바란다.
START라는 답변이 오면 명령어를 녹음해주시면 된다.
No Voice, Different등을 통해 이전 녹음과 다른지, 녹음이 되고 있는지 확인 가능하다.
Finish one이 나오면 1개의 명령어가 녹음 되었다는 뜻이다.
순차 적으로 5개 모두 녹음 완료되면, Group 1 finish라고 답변이 온다.
이후 Hex 명령어로 ‘AA21’을 보내주시면, Group1 Imported라는 답변이 온다.
첫 번째 그룹의 5개의 명령어 입력이 끝났다.
첫 번째 그룹의 명령어만 입력 완료해도 5개의 명령어로 제어할 수 있다.
명령어 리스트
Common Mode는 음성 명령 값을 ‘Result:11’과 같은 ASCII 코드값으로 전달해 주지만,
Compact Mode는 음성 명령 값을 ‘11’과 같은 Hex 값으로 전달해준다.
따라서 처음 PC와 음성인식 모듈을 연결하여 음성 명령을 녹음할 때는, Common Mode로 녹음 하는게 좋고 아두이노 등의 플랫폼에서 사용할 때는, Compact Mode로 사용해야 한다.
음성 명령어는 녹음할 때 사용자의 목소리 위주로 인식하기 때문에, 다른 사람이 명령어를 넣으면 제대로 작동하지 않을 수 있다.
다음 아두이노와 음성인식 모듈, 도트매트릭스를 아래와 같이 연결한다.
아두이노
음성인식 모듈
도트매트릭스 모듈
5V
VCC
VCC
GND
GND
GND
D2
TxD
D3
RxD
D5
D10
CS
D11
CLK
D12
DIN
다음 아두이노IDE를 실행하여 다음과 같이 코딩한다.
#include "LedControl.h" // 라이브러리 사용 선언 #include <SoftwareSerial.h> // 소프트웨어 Serial 통신 라이브러리 사용 // Serial 통신핀으로 D11번핀을 Rx로, D10번핀을 Tx로 선언 SoftwareSerial mySerial(2, 3); // 모듈 TX=11번핀 , RX=10번핀 연결 // Din 핀을 12번, ClK핀을 11번 CS핀을 10번에 연결 // 매트릭스는 1개를 사용 선언 LedControl lc=LedControl(12,11,10,1); int voice_recogn=0; byte data[5][8]= { // 숫자 1 출력 { B11111111, B10000001, B10100101, B10000001, B10000001, B10111101, B10000001, B11111111 }, // 숫자 2 출력 { B11111111, B10000001, B10100101, B10000001, B10100101, B10111101, B10000001, B11111111 },
// 숫자 3 출력 { B00011000, B00011000, B00011000, B11111111, B11111111, B00011000, B00011000, B00011000 }, // 숫자 4 출력 { B00000000, B01100110, B11111111, B11111111, B11111111, B01111110, B00111100, B00011000 }, // 숫자 5 출력 { B00111100, B01000010, B10100101, B10000001, B10100101, B10011001, B01000010, B00111100 } }; void setup() { Serial.begin(9600); // 통신 속도 9600bps로 PC와 시리얼 통신 시작 mySerial.begin(9600); // 통신 속도 9600bps로 모듈과 시리얼 통신 시작 lc.shutdown(0,false); // 0~3번까지 매트릭스 절전모드 해제 lc.setIntensity(0,8); // 매트릭스의 밝기 선언 0~15의 수 lc.clearDisplay(0); // 매트릭스 led를 초기화 Serial.println("wait settings are in progress"); delay(1000); mySerial.write(0xAA); // compact mode 사용 mySerial.write(0x37); delay(1000); mySerial.write(0xAA); // 그룹1 음성 명령어 imported mySerial.write(0x21); Serial.println("The settings are complete"); } void loop() { while(mySerial.available()) { Serial.println("voice input"); voice_recogn=mySerial.read(); switch(voice_recogn) { case 0x11: for(int j=0; j<8; j++) { lc.setRow(0,j,data[0][j]); // 숫자 1 출력 } Serial.println("숫자 1 출력"); break; case 0x12: for(int j=0; j<8; j++) { lc.setRow(0,j,data[1][j]); // 숫자 2 출력 } Serial.println("숫자 2 출력"); break; case 0x13: for(int j=0; j<8; j++) { lc.setRow(0,j,data[2][j]); // 숫자 3 출력 } Serial.println("숫자 3 출력"); break; case 0x14: for(int j=0; j<8; j++) { lc.setRow(0,j,data[3][j]); // 숫자 4 출력 } Serial.println("숫자 4 출력"); break; case 0x15: for(int j=0; j<8; j++) { lc.setRow(0,j,data[4][j]); // 숫자 5 출력 } Serial.println("숫자 5 출력"); break; } } }
먼저, TCS3200 컬러센서를 아두이노에 연결해야 한다. 그런 다음, 아래의 코드를 사용하여 컬러센서를 통해 검출된 색을 읽고, 해당하는 색에 따라 LED를 제어할 수 있다.
전체 코딩:
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // LCE패널 함수 선언
#define S0 6 // 컬러센서 S0 D6번 설정
#define S1 7 // 컬러센서 S1 D7번 설정
#define S2 8 // 컬러센서 S2 D8번 설정
#define S3 9 // 컬러센서 S3 D9번 설정
#define sensorOut 10 // 컬러센서 출력 D10번 설정
#define redPin 11 // LED_RED D11번 설정
#define greenPin 12 // LED_BLUE D12번 설정
#define bluePin 13 // LED_GREEN D13번 설정
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;
LiquidCrystal_I2C lcd (0x27,16,2); // LCD1602 설정
void setup() {
lcd.init(); // LCD 초기화
lcd.backlight(); // LCD 뒷 전등 켬
pinMode(S0, OUTPUT); // 출력
pinMode(S1, OUTPUT); //
pinMode(S2, OUTPUT); //
pinMode(S3, OUTPUT); //
pinMode(sensorOut, INPUT); // 입력
pinMode(redPin, OUTPUT); // 출력
pinMode(greenPin, OUTPUT); //
pinMode(bluePin, OUTPUT); //
// 주파수 스케일링을 20%로 설정
digitalWrite(S0,HIGH);
digitalWrite(S1,LOW);
Serial.begin(9600);
}
void loop() {
// 빨간색 필터링된 포토다이오드를 읽을 수 있도록 설정
digitalWrite(S2,LOW);
digitalWrite(S3,LOW);
// 빨간색 출력 주파수 판독
redFrequency = pulseIn(sensorOut, LOW);
// 시리얼 모니터에 값 출
Serial.print("R = ");
Serial.print(redFrequency);
delay(100);
lcd.setCursor(0, 0);
// 측정된 RED 값을 LCD에현시
lcd.print("R:");
lcd.print(redFrequency); //주파수
// 녹색 필터링된 포토다이오드를 읽도록 설정
digitalWrite(S2,HIGH);
digitalWrite(S3,HIGH);
// 녹색 출력 주파수 판독
greenFrequency = pulseIn(sensorOut, LOW);
// 시리얼 모니터에 녹색 값 출력
Serial.print(" G = ");
Serial.print(greenFrequency);
delay(100);
lcd.setCursor(7, 0);
// 측정된 GREEN 주파수 값을 LCD에현시
lcd.print("G:");
lcd.print(greenFrequency); //주파수
// 파란색 필터링된 포토다이오드를 읽을 수 있도록 설정
digitalWrite(S2,LOW);
digitalWrite(S3,HIGH);
// 파란색 출력 주파수 판독
blueFrequency = pulseIn(sensorOut, LOW);
// 시리얼 모니터에 파란색 값 출력
Serial.print("B:");
Serial.println(blueFrequency);
delay(100);
lcd.setCursor(0, 1);
// 측정된 BLUE 주파수 값을 LCD에현시
lcd.print("B:");
lcd.print(redFrequency); //주파수
// 검출된 색상을 기반으로 한 LED 제어
if (redFrequency > greenFrequency && redFrequency > blueFrequency) {
// Red LED 출력
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
} else if (greenFrequency > redFrequency && greenFrequency > blueFrequency) {
// Green LED 출력
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
} else if (blueFrequency > redFrequency && blueFrequency > greenFrequency) {
// Blue LED 출력
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
}
else if (redFrequency == greenFrequency && redFrequency == blueFrequency) {
// 모든 LED 출력
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
} else {
// 모든 LED 전부 꺼짐
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
}
준비물 : 아두이노 우노, RGB 컬러센서, 3색 LED, 300옴 저항 등이 사용된다.
아두이노UNO
컬러센서
3색 LED
300옴 저항
아두이노 우노 R3
RGB 컬러센서
3색 LED
300옴 저항
회로 연결 :
아두이노 우노 R3
RGB 컬러센서
RGB LED 다이오드
LCD1602
+5V
VCC
+핀
VCC
GND
GND
GND
D6
S0
D7
S1
D8
S2
D9
S3
D10
OUT
D11
RED
D12
GREEN
D13
BLUE
A4
SDA
A5
SCL
회로도:
색상감지센서 회로도
위와 같이 회로를 연결하고 코드를 아두이노에 업로드하면 시리얼 모니터와 LCD에 색상에 따른 값이 출력될 것이다.
이 코드는 컬러센서를 통해 검출된 색에 따라 3색 LED를 제어한다. 따라서 감지된 색에 따라 LED가 변할 것이다.
다음 void loop문에서 digitalWrite(TRIG, LOW/HIGH)는 초음파센서의 TRIG에서 초음파를 발사하는 부분이다.
long distance = pulseIn(ECHO, HIGH)/58.2; 는 pulseIn 명령어를 사용하여 ECHO에 초음파가 들어오는 시간을 계산한다. 여기서 58.2는 시간을 cm단위로 변환하여 주는 역활을 한다.
삼색 LED의 R, G, B를 모두 255로 설정하여 초기상태에서는 LED를 끄게한다.
여기서 255로 설정하는 이유는 삼색LED의 공동다리가 "+" 이기 때문이다. 만일 LED의 공동다리가 "-"이라면 R, G, B의 값을 모두 0으로 해주어야 한다.
다음 if문에서 distance < 10은 거리 10cm이하에서는 RED가 켜지고, 거리 20cm 이하에서는 GREEN을 켜며, 30cm이하에서는 BLUE가 켜진다. 여기서 analogWrite값을 0으로 정해주어야만 LED가 켜진다. 위에서 얘기한것처럼 LED의 공동핀이 "-"인 경우는 analogWrite값을 255로 정해주어야 할 것이다.
위와 같이 전부 코딩을 끝낸 후 업로드 시켜주면 초음파에 어떠한 물체가 감지되면 거리에 따른 값이 LED에 현시될 것이다.
아두이노는 오픈 소스 하드웨어 및 소프트웨어 플랫폼으로, 전자 제품 개발 및 프로토타이핑을 위해 디자인된 간단하고 유연한 마이크로컨트롤러 보드이다.
아두이노 보드는 다양한 센서 및 액추에이터를 제어하고 외부 입력을 받아들일 수 있으며, 컴퓨터나 다른 장치와 통신할 수 있는 기능을 제공한다. 이러한 특성으로 아두이노는 전자 공학자, 예술가, 디자이너, 학생 등 다양한 사람들에게 인기가 있으며, 작은 프로젝트부터 대규모 제품 개발까지 다양한 용도로 활용된다.
아두이노에는 아두이노UNO, DUE, TRE, NANO 등 여러가지가 있다.
아두이노 UNO
아두이노 DUE
아두이노 TRE
아두이노 NANO
납땜을 하지 않고 핀을 꼽아 연결할 수 있어 간편하다.
아두이노 UNO는 8bit 오픈소스 하드웨어이다.
아두이노 DUE는 32bit 오픈소스 하드웨어이다.
2) 아두이노로 할 수 있는것
아두이노는 유선, 무선으로 인터넷 연결이 가능하며, 입출력 핀을 통하여 각종 센서들의 제어가 가능하다.
또한 스마트폰을 이용하여 집에 있는 각종 전자기기들의 제어가 가능하다.
사물인터넷IOT, 로봇, 드론, 3D프린터, CNC등의 공작기계, 자동제어 분야에서 활용이 된다.
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
(1) 각 층에서 원하는 층으로 자유롭게 이동 가능하게 한다. (2) 층간 이동시 층은 차례대로 이동한다. (3) 예를 들면 1층에서 4층으로 이동할 때 : f1>up2>f2>up3>f3>up4>f4 (4) 엘리베이터 탑승가능 인원은 1~9명이고, 인원 초과 시 정지 후 알람이 울린다. (5) 긴급버튼 : 입력 시 정지한 후 알람이 울린다. (6) 이동 중(up 혹은 down state)에는 입력이 반영되지 않는다. 단 긴급버튼(emergency)은 가능하다. (7) 각 층 도착 시에는 문이 열리고 닫히고, 출발/정지가 가능하다. (8) 엘리베이터 1~4층 사이의 어느 층에서도 출발 가능하고, 출발한 엘리베이터는 1~4층 사이의 어느 층이라도 갈수 있다.
2) entity 조건
(1bit input) CLK : clock 신호 (1bit input) RESET : reset 신호 (1bit input) Emergency : 긴급 상황 버튼 (1bit input) Bell : haz state에서 bell 입력 시 문을 열려있는 상태로 만들어준다. (4bit input) in : 이동하고자 하는 층수 입력 받는다. (5bit input) People : elevator 탑승 인원을 입력 받는다. (3bit output) Floor : elevator가 현재 위치한 층을 알려준다. (1bit output) Emer_s : 긴급 상황일 때 haz state로 이동하였을 때 활성화 되는 신호이다. (1bit output) Door : 1bit, 문의 상태를 알려준다. (1 : open, 0 : close) (1bit output) Over : 1bit, 탑승인원 초과 유무를 나타낸다. (1bit output) Alarm : 원하는 층에 도착하였을 때와 문이 열려있을 때, Hazard state일 때 울리는 알람이다.
3) 제한 사항
(1) 한 번에 단 하나의 요청만 입력받는다. (2) 에러가 들어오는 경우는 존재하지 않는다고 가정한다. (3) Clock의 길이는 상간 없으나 clock의 상승 edge에 맞추어 회로가 동작한다. (4) 입력이 없을 때에는 elevator는 대기한다. (현재 상태에 머무른다.) (5) Elevator의 문이 열리고 닫히는 상황은 목표 층까지 가는 도중에는 따로 처리하지 않는다.
4) State Diagram
코딩
2. 4층 엘리베이터 Verilog 코딩
module ele4(clk, reset, in, people, bell, floor, over, door, alarm, emergency, emer_s);
input clk, reset, emergency, bell; // CLOCK, 재설정, 긴급상황버튼
input [2:0] in; // 층수 입력 변수 선언
input [3:0] people; // 탑승인원 변수 선언
output [2:0] floor; // 층수 출력변수 선언
output over, door, alarm, emer_s; // 탑승인원 초과, 문, 알람 출력 상태 변수 선언
reg over, door, alarm, emer_s;
reg [2:0] floor, state, next_state;
parameter s1=2'b01; // 1층
parameter s2=2'b10; // 2층
parameter s3=3'b011; // 3층
parameter s4=3'b100; // 4층
always @ (posedge clk or negedge reset)
if(reset) state<=s1; // 재설정시 상태는 1층
else state <=next_state; // 그외는 다음상태를 가리킴
always @ (state or in or people or emergency or bell)begin
case(state)
s1 : begin //1층
floor<=3'b001; // state가 001이면 1층 출력
over<=1'b0; // 초과인원 없으면 0 출력
if(emergency==1'b1)begin // 층수 입력이 2 or 3 or 4이고 긴급버튼 입력시 1층에 있다면
next_state<=s1; // 다음 상태도 역시 1층, 즉 1층에서 정지
alarm<=1'b1; // 정지 후 알림
emer_s<=1'b1; // 긴급상황일 때 활성화 되는 신호
end
else if(emergency==1'b0)begin // 층수 입력이 2 or 3 or 4이고 긴급버튼 입력을 하지 않았다면
alarm<=1'b0; // 알람 정지
emer_s<=1'b0; // 긴급 상황일 때 활성화 되는 신호 없음
end
if(in==3'b001)begin // 1층에 도착하면
door<=1'b1; // 문이 열리고
alarm<=1'b1; // 알람이 울림
end
if(people>4'b1001)begin // 인원 초과(9명이상)시
over<=1'b1; // 인원초과 알림
end
if(bell==1'b1)begin // 벨 입력 시
door<=1'b1; // 문 열림
end
if(in==3'b001|people>4'b1001|bell==1'b1|emergency==1'b1)begin // 층수 입력이 1이고, 탑승인원이 9명 초과시
next_state<=s1; // 다음 상태도 1층, 즉 정지
end
else if(in==3'b010|in==3'b011|in==3'b100)begin //만일 입력이 1층외라면
next_state<=s2; // 다음 상태는 2층을 가리킴
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
end
s2 : begin // 2층
floor<=3'b010; // 2층 출력
over<=1'b0; // 초과 인원 없음
if(emergency==1'b1)begin // 긴급버튼 입력 시 2층에 있다면
next_state<=s2; // 다음 상태도 역시 2층, 즉 2층에서 정지
alarm<=1'b1; // 정지 후 알림
emer_s<=1'b1; // 긴급 상황일 때 활성화 되는 신호
end
else if(emergency==1'b0)begin // 긴급버튼 입력을 하지 않았다면
alarm<=1'b0; // 알람 정지
emer_s<=1'b0; // 긴급 상황일 때 활성화 되는 신호 없음
end
if(in==3'b010)begin // 2층에 도착하면
door<=1'b1; // 문이 열리고
alarm<=1'b1; // 알람이 울림
end
if(people>4'b1001)begin // 인원 초과(9명이상)시
over<=1'b1; // 인원초과 알림
end
if(bell==1'b1)begin // 벨 입력 시
door<=1'b1; // 문 열림
end
if(in==3'b010|people>4'b1001|bell==1'b1|emergency==1'b1)begin // 2층시 탑승인원이 초과했다면
next_state<=s2; // 2층에서 정지
end
else if(in==3'b001)begin // 2층에 있을 때 1층을 입력 했다면
next_state<=s1; // 다음 상태는 1층을 가리킴
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
else if(in==3'b011|in==3'b100)begin // 2층에 있을 때 3층 혹은 4층을 입력했다면
next_state<=s3; // 다음 상태는 3층을 가리킴
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
end
s3 : begin // 3층
floor<=3'b011; // 3층 출력
over<=1'b0; // 초과인원 없음
if(emergency==1'b1)begin // 긴급버튼 입력 시 3층에 있다면
next_state<=s2; // 다음 상태도 역시 3층, 즉 3층에서 정지
alarm<=1'b1; // 정지 후 알림
emer_s<=1'b1; // 긴급 상황일 때 활성화 되는 신호
end
else if(emergency==1'b0)begin // 3층에 있고 긴급버튼 입력을 하지 않았다면
alarm<=1'b0; // 알람 정지
emer_s<=1'b0; // 긴급 상황일 때 활성화 되는 신호 없음
end
if(people>4'b1001)begin // 인원 초과(9명이상)시
over<=1'b1; // 인원초과 알림
end
if(in==3'b011)begin // 3층에 도착하면
door<=1'b1; // 문이 열리고
alarm<=1'b1; // 알람이 울림
end
if(bell==1'b1)begin // 벨 입력 시
door<=1'b1; // 문 열림
end
if(in==3'b011|people>4'b1001|bell==1'b1|emergency==1'b1)begin // 3층에 있을 때 탑승인원(9명이상)이 초과 상태이면
next_state<=s3; // 3층에서 정지
end
else if(in==3'b010|in==3'b001)begin // 3층에 있을 때 2층 혹은 1층을 입력했다면
next_state<=s2; // 다음 상태는 2층을 알려줌
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
else if(in==3'b100)begin // 3층에 있을 때 4층을 입력했다면
next_state<=s4; // 다음 상태는 4층을 알려줌
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
end
s4 : begin // 4층
floor<=3'b100; // 5층 출력
over<=1'b0; // 인원초과 없음
if(emergency==1'b1)begin // 긴급버튼 입력 시 4층에 있다면
next_state<=s4; // 다음 상태도 역시 4층, 즉 4층에서 정지
door<=1'b1; // 문이 열리고
alarm<=1'b1; // 정지 후 알림
emer_s<=1'b1; // 긴급 상황일 때 활성화 되는 신호
end
else if(emergency==1'b0)begin // 층수 입력이 4이고 긴급버튼 입력을 하지 않았다면
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람 정지
emer_s<=1'b0; // 긴급 상황일 때 활성화 되는 신호 없음
end
if(people>4'b1001)begin // 인원 초과(9명이상)시
over<=1'b1; // 인원초과 알림
end
if(in==3'b100)begin // 4층에 도착하면
door<=1'b1; // 문이 열리고
alarm<=1'b1; // 알람이 울림
end
if(bell==1'b1)begin // 벨 입력 시
door<=1'b1; // 문 열림
end
if(in==3'b100|people>4'b1001|bell==1'b1|emergency==1'b1)begin // 4층에 있을 때 탑승인원이 초과 상태이면
next_state<=s4; // 4층에서 정지
end
else if(in==3'b011|in==3'b010|in==3'b001)begin // 입력을 3층, 2층 혹은 1층을 입력했다면
next_state<=s3; // 다음 상태는 3층을 알려줌
door<=1'b0; // 문이 닫기고
alarm<=1'b0; // 알람이 울리지 않음
end
end
endcase
end
endmodule
3. 4층 엘리베이터 시뮬레이션
층이동 : 1층 → 4층 → 1층 → 3층 (목적지에 도착하면 알람이 울리면서 문이 열림)
탑승인원(9명: 1001 ) 초과(10명: 1010)시 over=1 출력하고 정지, 초과 탑승자가 내리면 계속 동작
벨(bell) 입력 시 엘리베이터 문(door)이 열린 상태에서 정지, 벨을 놓으면 계속 진행