diff --git a/Woo.c b/Woo.c new file mode 100644 index 0000000000000000000000000000000000000000..5b677214c233bcd4ce85647d813d3f11579020a6 --- /dev/null +++ b/Woo.c @@ -0,0 +1,262 @@ +#include <pthread.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include <linux/spi/spidev.h> +#include <linux/types.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <wiringPi.h> + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#define gpioin 17 +#define motionout 27 +#define gasout 18 + +static const char *DEVICE = "/dev/spidev0.0"; +static uint8_t MODE = 0; +static uint8_t BITS = 8; +static uint32_t CLOCK = 1000000; +static uint16_t DELAY = 5; + +int count = 0; +char msg[10] = ""; +char end[10] = ""; +int str_len; +int sock; + +void error_handling(char *message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} + +static int prepare(int fd) +{ + if (ioctl(fd, SPI_IOC_WR_MODE, &MODE) == -1) + { + error_handling("Can't set MODE"); + return -1; + } + + if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &BITS) == -1) + { + error_handling("Can't set number of BITS"); + return -1; + } + + if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &CLOCK) == -1) + { + error_handling("Can't set write CLOCK"); + return -1; + } + + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &CLOCK) == -1) + { + error_handling("Can't set read CLOCK"); + return -1; + } + + return 0; +} + +uint8_t control_bits_differential(uint8_t channel) +{ + return (channel & 7) << 4; +} + +uint8_t control_bits(uint8_t channel) +{ + return 0x8 | control_bits_differential(channel); +} + +int readadc(int fd, uint8_t channel) +{ + uint8_t tx[] = {1, control_bits(channel), 0}; + uint8_t rx[3]; + + struct spi_ioc_transfer tr = { + .tx_buf = (unsigned long)tx, + .rx_buf = (unsigned long)rx, + .len = ARRAY_SIZE(tx), + .delay_usecs = DELAY, + .speed_hz = CLOCK, + .bits_per_word = BITS, + }; + + if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) == 1) + { + error_handling("IO Error"); + abort(); + } + + return ((rx[1] << 8) & 0x300) | (rx[2] & 0xFF); +} + +void *gas_func(void *fd_ptr) +{ + while (strcmp("e", end) != 0) + { + int *fd = (int *)fd_ptr; + if (readadc(*fd, 0) > 30) + { + digitalWrite(gasout, HIGH); + usleep(1000 * 1000); + } + else + { + digitalWrite(gasout, LOW); + usleep(1000 * 1000); + } + printf("value: %d\n", readadc(*fd, 0)); + usleep(1000 * 1000); + } + digitalWrite(gasout, LOW); //e받으면 LED끄기 +} + +void *motion_func() +{ + while (strcmp("e", end) != 0) + { + if (!digitalRead(gpioin)) + { + digitalWrite(motionout, LOW); + printf("No Motion\n"); + usleep(1000 * 1000); + } + else + { + digitalWrite(motionout, HIGH); + printf("Motion Detected\n"); + count++; + printf("%d\n", count); + usleep(1000 * 1000); + } + delay(1000); + } + digitalWrite(motionout, LOW); //e받으면 LED끄기 +} + +void *read_func() +{ + while (1) + { + str_len = read(sock, msg, sizeof(msg)); + if (str_len == -1) + error_handling("read() error"); + if (strcmp(msg, "e") == 0) + { + strcpy(end, msg); + break; + } + } + pthread_exit; +} + +int main(int argc, char *argv[]) +{ + struct sockaddr_in serv_addr; + + pthread_t p_thread[3]; + int thr_id; + int status; + + if (argc != 3) + { + printf("Usage : %s <IP> <port>\n", argv[0]); + exit(1); + } + + 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"); + + printf("Connection established\n"); + + int fd = open(DEVICE, O_RDWR); + if (fd <= 0) + { + error_handling("Device open error"); + return -1; + } + + if (prepare(fd) == -1) + { + error_handling("Device prepare error"); + return -1; + } + + if (wiringPiSetupGpio() == -1) + { + printf("setup error"); + return -1; + } + + pinMode(gpioin, INPUT); + pinMode(motionout, OUTPUT); + pinMode(gasout, OUTPUT); + + while (1) + { + str_len = read(sock, msg, sizeof(msg)); + if (str_len == -1) + error_handling("read() error"); + if (strcmp("s", msg) == 0) + { + printf("got s\n"); + thr_id = pthread_create(&p_thread[0], NULL, read_func, NULL); + if (thr_id < 0) + { + error_handling("read thread create error : "); + exit(0); + } + thr_id = pthread_create(&p_thread[1], NULL, gas_func, (void *)&fd); + if (thr_id < 0) + { + error_handling("gas thread create error : "); + exit(0); + } + thr_id = pthread_create(&p_thread[2], NULL, motion_func, NULL); + if (thr_id < 0) + { + error_handling("motion thread create error : "); + exit(0); + } + + pthread_join(p_thread[0], (void **)&status); + pthread_join(p_thread[1], (void **)&status); + pthread_join(p_thread[2], (void **)&status); + } + + if (strcmp("e", end) == 0) + { + printf("got e\n"); + // pthread_cancel(p_thread[0]); + // pthread_cancel(p_thread[1]); + snprintf(msg, 2, "%d", count); + write(sock, msg, sizeof(msg)); + printf("motion count : %d\n", count); + break; + } + } + + close(sock); + + return 0; +} \ No newline at end of file