From 5779caecbab45e5b85c8388fb3c4372df1583e53 Mon Sep 17 00:00:00 2001 From: Seona Eo <eosa3993@ajou.ac.kr> Date: Fri, 23 Jun 2023 22:30:12 +0900 Subject: [PATCH] =?UTF-8?q?=EC=96=B4=EC=84=A0=EC=95=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client_motion.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 Client_motion.c diff --git a/Client_motion.c b/Client_motion.c new file mode 100644 index 0000000..71206ec --- /dev/null +++ b/Client_motion.c @@ -0,0 +1,223 @@ +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#define IN 0 +#define OUT 1 +#define LOW 0 +#define HIGH 1 +#define MOTION 17 +#define SPEAKER 18 +#define BUFFER_MAX 3 +#define DIRECTION_MAX 1024 +#define VALUE_MAX 40 + +static int GPIOExport(int pin) { + char buffer[BUFFER_MAX]; + ssize_t bytes_written; + int fd; + + // GPIO 핀을 사용하기 위해 /sys/class/gpio/export 파일에 핀 번호를 기록 + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open export for writing!\n"); + return -1; + } + + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); + write(fd, buffer, bytes_written); + close(fd); + return 0; +} + +static int GPIOUnexport(int pin) { + char buffer[BUFFER_MAX]; + ssize_t bytes_written; + int fd; + + // GPIO 핀을 사용하지 않기 위해 /sys/class/gpio/unexport 파일에 핀 번호를 기록 + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open unexport for writing!\n"); + return -1; + } + + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); + write(fd, buffer, bytes_written); + close(fd); + return 0; +} + +static int GPIODirection(int pin, int dir) { + static const char s_directions_str[] = "in\0out"; + + char path[DIRECTION_MAX]; + //char path[DIRECTION_MAX] = "/sys/class/gpio/gpio%d/direction"; + int fd; + + // GPIO 핀을 입력으로 설정 + snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin); + + fd = open(path, O_WRONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open gpio direction for writing!\n"); + return -1; + } + + if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) { + fprintf(stderr, "Failed to set direction!\n"); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int GPIORead(int pin) { + char path[VALUE_MAX]; + char value_str[3]; + int fd; + + // GPIO 핀의 값을 읽어옴 + snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); + fd = open(path, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open unexport for writing!\n"); + return -1; + } + + if (-1 == read(fd, value_str, 3)) { + fprintf(stderr, "Failed to read value!\n"); + close(fd); + return -1; + } + + close(fd); + + return(atoi(value_str)); +} + +static int GPIOWrite(int pin, int value) { + static const char s_values_str[] = "01"; + + char path[VALUE_MAX]; + int fd; + + snprintf(path,VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); + fd = open(path, O_WRONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open gpio value for writing!\n"); + return -1; + } + + if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) { + fprintf(stderr, "Failed to write value!\n"); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +void playSound(int frequency, int time) { + // Period = 1초 / Frequency + int period = 1000000 / frequency; + // 75% Duty Cycle 계산 + int dutycycle = period * 0.75; + // 사운드 출력 횟수 (사운드를 지속할 시간을 위한 계산) + int num = (frequency * time) / 1000000; + + for (int i = 0; i < num; i++) { + GPIOWrite(SPEAKER, 1); + usleep(dutycycle); + GPIOWrite(SPEAKER, 0); + usleep(period - dutycycle); + } +} + +void error_handling(char *message){ + fputs(message,stderr); + fputc('\n',stderr); + exit(1); +} + +int main(int argc, char *argv[]) { + int sock; + struct sockaddr_in serv_addr; + char msg[2]; + char on[2]="1"; + int str_len; + + int detected; + + if(argc!=3){ + printf("Usage : %s <IP> <port>\n",argv[0]); + exit(1); + } + + // Enable GPIO pins + if (GPIOExport(SPEAKER) == -1) + return 1; + + // Set GPIO directions + if (GPIODirection(SPEAKER, OUT) == -1) + return 2; + + sock = socket(PF_INET, SOCK_STREAM, 0); + if(sock == -1) + error_handling("socket() error"); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(argv[1]); + serv_addr.sin_port = htons(atoi(argv[2])); + + if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) + error_handling("connect() error"); + + while(1){ + str_len = read(sock, msg, sizeof(msg)); + if(str_len == -1) + error_handling("read() error"); + + printf("Receive message from Server : %s\n",msg); + + if(strncmp(on,msg,1)==0) { + if (GPIORead(MOTION) == 1) { + detected = 1; + printf("Motion detected\n"); + snprintf(msg, 2, "%d", detected); + write(sock, msg, sizeof(msg)); + printf("msg = %s\n", msg); + } else { + detected = 0; + printf("Nothing\n"); + playSound(1000,1000000); // 1000Hz, 1sec(1000000ms) + snprintf(msg, 2, "%d", detected); + write(sock, msg, sizeof(msg)); + printf("msg = %s\n", msg); + } + } else { + write(sock, msg, sizeof(msg)); + printf("msg = %s\n", msg); + } + } + close(sock); + + while(1) + + //Disable GPIO pins + if (GPIOUnexport(SPEAKER) == -1) + return 3; + + return(0); +} + -- GitLab