diff --git a/Actuator/source.c b/Actuator/source.c new file mode 100644 index 0000000000000000000000000000000000000000..e72954aff69997ead5672a2f209eaf24be289943 --- /dev/null +++ b/Actuator/source.c @@ -0,0 +1,350 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <time.h> +#include <pthread.h> + +#define BUFFER_MAX 3 + +#define IN 0 +#define OUT 1 +#define PWM 0 + +#define LOW 0 +#define HIGH 1 +#define VALUE_MAX 256 + +#define LED_R 16 +#define LED_G 20 +#define LED_B 21 +#define BUZZER 0 //PWM + +#define MAX_BUFFER_SIZE 1024 + +static int +PWMExport(int pwmnum) +{ +#define BUFFER_MAX 3 + char buffer[BUFFER_MAX]; + int bytes_written; + int fd; + + fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY); + if(-1 == fd){ + fprintf(stderr, "Failed to open in unexport!\n"); + return(-1); + } + + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); + write(fd, buffer, bytes_written); + close(fd); + + sleep(1); + fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY); + if(-1 == fd) { + fprintf(stderr, "Failed to open in export!\n"); + return(-1); + } + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); + write(fd, buffer, bytes_written); + close(fd); + sleep(1); + return(0); +} + +static int +PWMEnable(int pwmnum) +{ + static const char s_unenable_str[] = "0"; + static const char s_enable_str[] = "1"; + + #define PWM_DIRECTION_MAX 45 + + char path[PWM_DIRECTION_MAX]; + int fd; + + snprintf(path, PWM_DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm%d/enable", pwmnum); + fd = open(path, O_WRONLY); + if(-1 == fd){ + fprintf(stderr, "Failed to open in enable!\n"); + return -1; + } + + write(fd, s_unenable_str, strlen(s_unenable_str)); + close(fd); + + fd = open(path, O_WRONLY); + if(-1 == fd) { + fprintf(stderr, "Failed to open in enable!\n"); + return -1; + } + + write(fd, s_enable_str, strlen(s_enable_str)); + close(fd); + return 0; +} + +static int +PWMWritePeriod(int pwmnum, int value) +{ + char s_values_str[VALUE_MAX]; + char path[VALUE_MAX]; + int fd, byte; + + snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/period", pwmnum); + fd = open(path, O_WRONLY); + if(-1 == fd){ + fprintf(stderr, "Failed to open in period!\n"); + return -1; + } + + byte = snprintf(s_values_str, 10, "%d", value); + + if(-1 == write(fd, s_values_str, byte)) { + fprintf(stderr, "Failed to write value in period!\n"); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int +PWMWriteDutyCycle(int pwmnum, int value) +{ + char path[VALUE_MAX]; + char s_values_str[VALUE_MAX]; + int fd, byte; + + snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", pwmnum); + fd = open(path, O_WRONLY); + if(-1 == fd){ + fprintf(stderr, "Failed to open in duty_cycle!\n"); + return -1; + } + + byte = snprintf(s_values_str, 10, "%d", value); + + if(-1 == write(fd, s_values_str, byte)) { + fprintf(stderr, "Failed to write value in duty_cycle!\n"); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int GPIOExport(int pin) +{ +#define BUFFER_MAX 3 + char buffer[BUFFER_MAX]; + ssize_t bytes_written; + int fd; + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (-1 == fd) { + 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; + + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (-1 == fd) { + 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"; + + #define GPIO_DIRECTION_MAX 35 + char path[GPIO_DIRECTION_MAX] = "/sys/class/gpio/gpio%d/direction"; + int fd; + + snprintf(path, GPIO_DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin); + fd = open(path, O_WRONLY); + if (-1 == fd) { + 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"); + return(-1); + } + + close(fd); + return(0); +} + +static int +GPIORead(int pin) +{ + char path[VALUE_MAX]; + char value_str[3]; + int fd; + + snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); + fd = open(path, O_RDONLY); + if (-1 == fd) { + fprintf(stderr, "Failed to open gpio value for reading!\n"); + return(-1); + } + + if (-1 == read(fd, value_str, 3)) { + fprintf(stderr, "Failed to read value!\n"); + 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 (-1 == fd) { + 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"); + return(-1); + } + + close(fd); + return(0); +} + +void error_handling(char *message) { + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} + +void LED_clear(){ + GPIOWrite(LED_R, 0); + GPIOWrite(LED_G, 0); + GPIOWrite(LED_B, 0); +} + +int main(int argc, char *argv[]) { + int state = 1; + int prev_state = 1; + int light = 0; + char buf[2]; + int str_len; + + int serv_sock,clnt_sock=-1; + struct sockaddr_in serv_addr,clnt_addr; + socklen_t clnt_addr_size; + + if (-1 == GPIOExport(LED_R) || -1 == GPIOExport(LED_G) || -1 == GPIOExport(LED_B) || -1 == PWMExport(0)) + return(1); + + if (-1 == GPIODirection(LED_R, OUT) || -1 == GPIODirection(LED_G, OUT) || -1 == GPIODirection(LED_B, OUT)) + return(2); + + if(argc!=2){ + printf("Usage : %s <port>\n",argv[0]); + } + + serv_sock = socket(PF_INET, SOCK_STREAM, 0); + if(serv_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 = htonl(INADDR_ANY); + serv_addr.sin_port = htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) + error_handling("bind() error"); + + if(listen(serv_sock,5) == -1) + error_handling("listen() error"); + + if(clnt_sock<0){ + clnt_addr_size = sizeof(clnt_addr); + clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); + if(clnt_sock == -1) + error_handling("accept() error"); + } +while(1) + { + + str_len = read(clnt_sock, buf, sizeof(buf)); + if(str_len == -1) + error_handling("read() error"); + + printf("Receive message from client : %s\n",buf); + if(strncmp("0",buf,1)==0){ + LED_clear(); + GPIOWrite(LED_G, HIGH); + + } + else if(strncmp("1", buf, 1) == 0){ + LED_clear(); + GPIOWrite(LED_R, HIGH); + } + else if(strncmp("2", buf, 1) == 0){ + LED_clear(); + GPIOWrite(LED_R, HIGH); + + PWMWritePeriod(0, 1000000); // 1초 동안의 주기 설정 (단위: 마이크로초) + PWMWriteDutyCycle(0, 500000); // 50%의 듀티 사이클 설정 (단위: 마이크로초) + PWMEnable(0); + sleep(1); // 1초 대기 + PWMWriteDutyCycle(0, 0); // 듀티 사이클을 0으로 설정하여 스피커 소리 중지 + sleep(1); // 추가적으로 1초 대기 + + } + + } + + close(clnt_sock); + close(serv_sock); + + if (-1 == GPIOUnexport(LED_R) || -1 == GPIOUnexport(LED_G) ||-1 == GPIOUnexport(LED_B)) + return(4); + + return 0; +} + +