Skip to content
Snippets Groups Projects
Commit b707a0b0 authored by 도혁 함's avatar 도혁 함
Browse files

docs: 최종종 주석 추가가

parent ff42c792
No related branches found
No related tags found
No related merge requests found
......@@ -8,16 +8,17 @@
#include <time.h>
#include <signal.h>
#define BUFFER_MAX 3
#define DIRECTION_MAX 256
#define VALUE_MAX 256
// 상수 정의
#define BUFFER_MAX 3 // 버퍼 크기
#define DIRECTION_MAX 256 // 방향 경로 최대 길이
#define VALUE_MAX 256 // 값 경로 최대 길이
#define IN 0
#define OUT 1
#define LOW 0
#define HIGH 1
#define IN 0 // GPIO 입력 모드
#define OUT 1 // GPIO 출력 모드
#define LOW 0 // GPIO LOW 상태
#define HIGH 1 // GPIO HIGH 상태
#define BUFFER_SIZE 1024
#define BUFFER_SIZE 1024 // 소켓 버퍼 크기
#define POUT 23 // 초음파 트리거 핀
#define PIN 24 // 초음파 에코 핀
#define FLAME 21 // 불꽃 센서 핀
......@@ -25,28 +26,34 @@
#define RED 22 // 적색 LED 핀
#define BUZZER 27 // 부저 핀
// 부저 알림용 음계 배열
int fireAlarmNotes[] = { 880, 880, 0, 880, 880, 0, 988, 988, 0, 880, 880, 0 };
struct sockaddr_in server_addr;
int park = 0; // 주차 상태: 0 = 주차되지 않음, 1 = 주차됨
int setFire = 1;
int sock;
int redLed = 2;
int CLEAR = 1;
// 전역 변수
struct sockaddr_in server_addr; // 서버 주소 구조체
int park = 0; // 주차 상태: 0 = 비어있음, 1 = 주차됨
int setFire = 1; // 화재 상태: 1 = 정상, 0 = 화재 발생
int sock; // 소켓 디스크립터
int redLed = 2; // 초기 LED 상태
int CLEAR = 1; // 초기 화재 진압상태 1 = 화재 진압 상태 0 = 화재 미진압 상태
/* 스레드 변수 */
pthread_t ultra_thread, flame_thread, receive_thread;
// GPIO 핀 제어 함수 선언
int GPIOExport(int pin);
int GPIOUnexport(int pin);
int GPIODirection(int pin, int dir);
int GPIORead(int pin);
int GPIOWrite(int pin, int value);
/* 인터럽트 신호 처리 함수 */
void signal_handler(int no);
// PWM 기반 부저 소리 발생 함수
/*부저 알림음 생성 함수*/
/* PWM 방식으로 핀을 토글하며 특정 주파수로 소리를 발생시킴 */
void buzzerTone(int pin, int frequency, int duration) {
int period = 1000000 / frequency; // 주기 (마이크로초)
int period = 1000000 / frequency; // 주기 (마이크로초 단위)
int halfPeriod = period / 2;
for (int i = 0; i < (duration * 1000 / period); i++) {
......@@ -57,42 +64,45 @@ void buzzerTone(int pin, int frequency, int duration) {
}
}
/* 초음파 센서를 통한 거리 측정 및 주차 상태 관리 스레드 함수 */
void *ultrasonic_sensor(void *arg) {
clock_t start_t, end_t;
clock_t start_t, end_t; // 에코 신호 시간을 측정하기 위한 변수
double time;
while (1) {
GPIOWrite(POUT, HIGH);
usleep(10);
GPIOWrite(POUT, LOW);
GPIOWrite(POUT, HIGH); // 트리거 신호 발생
usleep(10); // 10마이크로초 유지
GPIOWrite(POUT, LOW); // 트리거 신호 종료
/* 에코 신호 수신 시작 */
while (GPIORead(PIN) == LOW)
start_t = clock();
while (GPIORead(PIN) == HIGH)
end_t = clock();
time = (double)(end_t - start_t) / CLOCKS_PER_SEC;
double distance = time / 2 * 34000;
time = (double)(end_t - start_t) / CLOCKS_PER_SEC; // 에코 시간 계산
double distance = time / 2 * 34000; // 거리 계산 (cm 단위)
/* 상태에 따른 LED 제어 및 서버 메시지 전송 */
if (redLed == 2) {
GPIOWrite(RED, HIGH);
redLed = 1;
}
if (park == 0 && distance <= 10 && redLed == 1) {
GPIOWrite(GREEN, HIGH);
GPIOWrite(RED, LOW);
park = 1;
GPIOWrite(GREEN, HIGH); // 초록색 LED 켜기
GPIOWrite(RED, LOW); // 적색 LED 끄기
park = 1; // 주차 상태 변경
redLed = 0;
printf("0-PARK\n");
send(sock, "0-PARK", strlen("0-PARK"), 0);
send(sock, "0-PARK", strlen("0-PARK"), 0); // 서버로 주차 메시지 전송
} else if (park == 1 && distance > 10 && redLed == 0) {
GPIOWrite(GREEN, LOW);
GPIOWrite(RED, HIGH);
park = 0;
park = 0; // 주차 해제
redLed = 1;
printf("0-EXIT\n");
send(sock, "0-EXIT", strlen("0-EXIT"), 0);
send(sock, "0-EXIT", strlen("0-EXIT"), 0); // 서버로 주차 해제 메시지 전송
}
usleep(500000);
......@@ -101,27 +111,29 @@ void *ultrasonic_sensor(void *arg) {
return NULL;
}
/* 불꽃 센서를 통한 화재 감지 및 부저 알림 스레드 함수 */
void *flame_sensor(void *arg) {
printf("초기 FLAME 값 %d\n", GPIORead(FLAME));
printf("초기 FLAME 값: %d\n", GPIORead(FLAME));
while (1) {
if (GPIORead(FLAME) == 0 && setFire == 1) {
if (GPIORead(FLAME) == 0 && setFire == 1) { // 화재 발생 감지
printf("0-FIRE\n");
send(sock, "0-FIRE", strlen("0-FIRE"), 0);
setFire = 0;
CLEAR = 0;
send(sock, "0-FIRE", strlen("0-FIRE"), 0); // 서버로 화재 메시지 전송
setFire = 0; // 화재 상태 변경
CLEAR = 0; // 화재 진압 상태 변경
printf("FLAME 값: %d\n", GPIORead(FLAME));
}
/* CLEAR 상태가 0일 때 화재 경고음 발생 */
while (CLEAR == 0) {
for (int i = 0; i < sizeof(fireAlarmNotes) / sizeof(int); i++) {
if (CLEAR != 0) {
break;
}
if (fireAlarmNotes[i] > 0) {
buzzerTone(BUZZER, fireAlarmNotes[i], 200);
buzzerTone(BUZZER, fireAlarmNotes[i], 200); // 알림음 발생
} else {
usleep(200000);
usleep(200000); // 음 사이 간격
}
}
if (CLEAR != 0) {
......@@ -136,16 +148,18 @@ void *flame_sensor(void *arg) {
return NULL;
}
/* 서버와 메시지를 주고받는 스레드 함수 */
void *receive_message(void *arg) {
char buffer[BUFFER_SIZE];
int valread;
while (1) {
valread = read(sock, buffer, BUFFER_SIZE - 1);
if (valread <= 0) {
valread = read(sock, buffer, BUFFER_SIZE - 1); // 서버로부터 메시지 읽기
if (valread <= 0) { // 서버 연결 끊김 감지
printf("서버와의 연결이 종료되었습니다. 재연결을 시도합니다...\n");
close(sock);
/* 서버 재연결 시도 */
while (1) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
......@@ -168,7 +182,7 @@ void *receive_message(void *arg) {
buffer[valread] = '\0';
printf("서버로부터 받은 메시지: %s\n", buffer);
buffer[strcspn(buffer, "\r\n")] = '\0';
if (strcmp(buffer, "CLEAR") == 0) {
if (strcmp(buffer, "CLEAR") == 0) { // CLEAR 명령어 처리
setFire = 1;
CLEAR = 1;
printf("setFire 및 CLEAR가 %d, %d로 설정되었습니다.\n", setFire, CLEAR);
......@@ -180,24 +194,26 @@ void *receive_message(void *arg) {
}
int main() {
/* SIGINT 신호 (Ctrl + C) 처리 핸들러 등록 */
signal(SIGINT, (void *)signal_handler);
// 소켓 생성
/* 소켓 생성 */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket creation error");
return -1;
}
/* 서버 주소 설정 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345); // 서버 포트 설정
// localhost IP 주소 설정
/* 서버 IP 주소 설정 (127.0.0.1: localhost) */
if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {
perror("Invalid address / Address not supported");
return -1;
}
// 서버 연결
/* 서버 연결 시도 */
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
return -1;
......@@ -205,30 +221,34 @@ int main() {
printf("서버에 연결되었습니다.\n");
// GPIO 핀 설정
if (GPIOExport(POUT) == -1 || GPIOExport(PIN) == -1 || GPIOExport(FLAME) == -1 || GPIOExport(GREEN) == -1 || GPIOExport(RED) == -1 || GPIOExport(BUZZER) == -1) {
/* GPIO 핀 초기화 */
if (GPIOExport(POUT) == -1 || GPIOExport(PIN) == -1 || GPIOExport(FLAME) == -1 ||
GPIOExport(GREEN) == -1 || GPIOExport(RED) == -1 || GPIOExport(BUZZER) == -1) {
fprintf(stderr, "GPIO Export Error\n");
return 1;
}
usleep(100000); // GPIO 설정 대기
if (GPIODirection(POUT, OUT) == -1 || GPIODirection(PIN, IN) == -1 || GPIODirection(FLAME, IN) == -1 || GPIODirection(GREEN, OUT) == -1|| GPIODirection(RED, OUT) == -1 || GPIODirection(BUZZER, OUT) == -1) {
/* GPIO 핀 방향 설정 */
if (GPIODirection(POUT, OUT) == -1 || GPIODirection(PIN, IN) == -1 ||
GPIODirection(FLAME, IN) == -1 || GPIODirection(GREEN, OUT) == -1 ||
GPIODirection(RED, OUT) == -1 || GPIODirection(BUZZER, OUT) == -1) {
fprintf(stderr, "GPIO Direction Error\n");
return 2;
}
// 스레드 생성
/* 초음파 센서, 불꽃 센서, 서버 메시지 처리 스레드 생성 */
pthread_create(&ultra_thread, NULL, ultrasonic_sensor, NULL);
pthread_create(&flame_thread, NULL, flame_sensor, NULL);
pthread_create(&receive_thread, NULL, receive_message, NULL);
// 스레드 종료 대기
/* 스레드 종료 대기 */
pthread_join(ultra_thread, NULL);
pthread_join(flame_thread, NULL);
pthread_join(receive_thread, NULL);
// 소켓 및 GPIO 정리
/* 종료 시 소켓 및 GPIO 정리 */
close(sock);
GPIOUnexport(POUT);
GPIOUnexport(PIN);
......@@ -239,17 +259,25 @@ int main() {
return 0;
}
/* SIGINT 신호 처리 함수 */
/* 시스템 종료 시 GPIO 상태 정리 및 프로그램 종료 */
void signal_handler(int no) {
printf("System Interrupt.\n");
GPIOWrite(GREEN, LOW);
GPIOWrite(RED, LOW);
GPIOWrite(BUZZER, LOW);
GPIOUnexport(POUT);
GPIOUnexport(PIN);
GPIOUnexport(FLAME);
GPIOUnexport(GREEN);
GPIOUnexport(RED);
GPIOUnexport(BUZZER);
close(sock);
exit(0);
}
/* GPIO 핀 활성화 함수 */
/* 핀 번호를 "/sys/class/gpio/export"에 기록하여 활성화 */
int GPIOExport(int pin) {
char buffer[BUFFER_MAX];
ssize_t bytes_written;
......@@ -267,6 +295,8 @@ int GPIOExport(int pin) {
return (0);
}
/* GPIO 핀 비활성화 함수 */
/* 핀 번호를 "/sys/class/gpio/unexport"에 기록하여 비활성화 */
int GPIOUnexport(int pin) {
char buffer[BUFFER_MAX];
ssize_t bytes_written;
......@@ -283,9 +313,11 @@ int GPIOUnexport(int pin) {
return (0);
}
/* GPIO 핀 방향 설정 함수 */
/* 핀의 입력(IN) 또는 출력(OUT) 방향을 설정 */
int GPIODirection(int pin, int dir) {
static const char s_directions_str[] = "in\0out";
char path[DIRECTION_MAX] = "/sys/class/gpio/gpio%d/direction";
char path[DIRECTION_MAX];
int fd;
snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
......@@ -305,6 +337,8 @@ int GPIODirection(int pin, int dir) {
return (0);
}
/* GPIO 핀 값 읽기 함수 */
/* 핀의 현재 상태(0 또는 1)를 읽어 반환 */
int GPIORead(int pin) {
char path[VALUE_MAX];
char value_str[3];
......@@ -323,10 +357,11 @@ int GPIORead(int pin) {
}
close(fd);
return (atoi(value_str));
return (atoi(value_str)); // 읽은 값을 정수로 변환 후 반환
}
/* GPIO 핀 값 쓰기 함수 */
/* 핀에 0(LOW) 또는 1(HIGH) 값을 기록 */
int GPIOWrite(int pin, int value) {
static const char s_values_str[] = "01";
char path[VALUE_MAX];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment