Skip to content
Snippets Groups Projects
Commit d542adc7 authored by KangHyun Kim's avatar KangHyun Kim
Browse files

detectorPi

parents
No related branches found
No related tags found
No related merge requests found
Makefile 0 → 100644
detect : danger_detect.o pwm.o gpio.o
gcc -o detect danger_detect.o pwm.o gpio.o -lpthread
gpio.o : gpio.c
gcc -c gpio.c
pwm.o : pwm.c
gcc -c pwm.c
danger_detect.o : danger_detect.c
gcc -c danger_detect.c
#include<stdint.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<getopt.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<linux/types.h>
#include<linux/spi/spidev.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<string.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include"gpio.h"
#include"pwm.h"
#define IN 0
#define OUT 1
#define LOW 0
#define HIGH 1
#define FD 27
#define MD 5
#define RED 17
#define GREEN 22
char danger[4];
int fire = 1;
float gas; //for saving gas ppm.
int motion = 0; //for saving motion detecting
int fi = 0; // for fire index;
int gi = 0; // for gas index;
#define ARRAY_SIZE(array) sizeof(array) / sizeof(array[0])
const char *DEVICE = "/dev/spidev0.0";
uint8_t MODE = SPI_MODE_0;
uint8_t BITS = 8;
uint32_t CLOCK = 1000000;
uint8_t DELAY = 5;
int prepare(int fd);
uint8_t control_bits_differential(uint8_t channel);
uint8_t control_bits(uint8_t channel);
int readadc(int fd, uint8_t channel);
void *fire_detect();
void *gas_detect();
void *motion_detect();
int main(int argc, int argv[]){
pthread_t fid, gid, mid; //fid is for detecting fire thread, gid fs for detecting gas thread.
pthread_create(&fid, NULL, fire_detect, NULL);
pthread_create(&gid, NULL, gas_detect, NULL);
pthread_create(&mid, NULL, motion_detect, NULL);
int serv1_sock, serv2_sock, allert_sock = -1, control_sock = -1; //serv1 for allert Rpi, serv2 for controller RPi
struct sockaddr_in serv1_addr, serv2_addr, allert_addr, control_addr;
socklen_t allert_addr_size, control_addr_size;
char msg[3]; // danger data to send other Rpi.
char recv[2]; // receive data from controller Rpi.
if(argc != 3){
printf("Usage : %s <port>\n", argv[0]);
}
serv1_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv1_sock == -1){
fprintf(stderr,"Error in socket() for serv1_sock\n");
}
memset(&serv1_addr, 0, sizeof(serv1_addr));
serv1_addr.sin_family = AF_INET;
serv1_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv1_addr.sin_port = htons(atoi(argv[1]));
serv2_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv2_sock == -1){
fprintf(stderr, "Error in socket() for serv2_sock\n");
}
memset(&serv2_addr, 0, sizeof(serv2_addr));
serv2_addr.sin_family = AF_INET;
serv2_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv2_addr.sin_port = htons(atoi(argv[2]));
if(bind(serv1_sock, (struct sockaddr*) &serv1_addr, sizeof(serv1_addr))==-1){
fprintf(stderr, "Error in bind() for serv1");
exit(0);
}
if(bind(serv2_sock, (struct sockaddr*) &serv2_addr, sizeof(serv2_addr))==-1){
fprintf(stderr, "Error in bind() for serv2");
exit(0);
}
if(listen(serv1_sock, 5) == -1 || listen(serv2_sock, 5)){
fprintf(stderr, "listen error!\n");
exit(0);
}
//accept other Rpi's request
if(allert_sock < 0){
allert_addr_size = sizeof(allert_addr);
allert_sock = accept(serv1_sock, (struct sockaddr*)&allert_addr, &allert_addr_size);
if(allert_sock == -1){
fprintf(stderr, "Error in allert_sock!\n");
}
}
if(control_sock < 0){
control_addr_size = sizeof(control_addr);
control_sock = accept(serv2_sock, (struct sockaddr*)&control_addr, &control_addr_size);
if(control_sock == -1){
fprintf(stderr, "Error in control_sock!\n");
}
}
danger[3] = '\0';
while(1){
if(danger[0] == '1' && danger[1] == '1'){
printf("fire and gas!\n");
printf("ppm : %.2f\n\n", gas);
}
else if(danger[0] == '0' && danger[1] == '1'){
printf("gas!\n");
printf("ppm : %.2f\n\n", gas);
}
else if(danger[0] == '1' && danger[1] == '0'){
printf("fire!\n");
}
else{
printf("safe now!\n");
}
// send data through socket programming.
write(allert_sock, danger, 2);
write(control_sock, danger, sizeof(danger));
usleep(500000);
}
int status;
pthread_join(fid, (void**)&status);
pthread_join(gid, (void**)&status);
pthread_join(mid, (void**)&status);
}
// other functions to maintain the detector Rpi.
int prepare(int fd){
if(ioctl(fd, SPI_IOC_WR_MODE, &MODE) == -1){
perror("Can't set MODE");
return -1;
}
if(ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &BITS) == -1){
perror("Can't set number of BITS");
return -1;
}
if(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &CLOCK) == -1){
perror("Can't set write CLOCK");
return -1;
}
if(ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &CLOCK) == -1){
perror("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){
perror("IO Error");
abort();
}
return ((rx[1] << 8) & 0x300) | (rx[2] & 0xFF);
}
void *fire_detect(){
if(-1 == GPIOExport(FD) || -1 == GPIOExport(RED)){
printf("error in fire export\n");
exit(0);
}
usleep(100000);
if(-1 == GPIODirection(FD, IN) || -1 == GPIODirection(RED, OUT)){
printf("error in fire direction\n");
exit(0);
}
fi = 0;
while(1){
fire = GPIORead(FD);
if(!fire && fi < 10){
fi++;
}
else if(!fire && fi >= 10){
GPIOWrite(RED, HIGH);
danger[0] = '1';
//send danger message to other RPi
}
else if(fire && fi > 0){
fi--;
}
else{
GPIOWrite(RED, LOW);
danger[0] = '0';
}
usleep(100000);
}
return;
}
void *gas_detect(){
if(GPIOExport(GREEN) == -1){
printf("gas export error\n");
exit(0);
}
if(GPIODirection(GREEN, OUT) == -1){
printf("gas direction error\n");
exit(0);
}
int fd = open(DEVICE, O_RDWR);
if(fd <= 0 ){
printf("SPI file open error!\n");
exit(0);
}
if(prepare(fd) == -1){
printf("SPI prepare error!\n");
exit(0);
}
gi = 0;
while(1){
gas = (float)readadc(fd, 0);
gas = (gas / 1024) * 9800 + 200;
//printf("now GAS PPM : %.2f\n", gas);
if(gas >= 5000 && gi < 10){
gi++;
}
else if(gas >= 5000 && gi >= 10){
GPIOWrite(GREEN, HIGH);
danger[1] = '1';
//send danger message to other RPi
}
else if(GREEN < 5000 && gi > 0){
gi--;
}
else{
GPIOWrite(GREEN, LOW);
danger[1] = '0';
}
usleep(100000);
}
return;
}
void *motion_detect(){
if(-1 == GPIOExport(MD)){
printf("error in motion export\n");
exit(0);
}
usleep(100000);
if(-1 == GPIODirection(MD, IN)){
printf("error in motion direction\n");
exit(0);
}
while(1){
motion = GPIORead(FD);
if(!motion){ //nothing detected!!!
danger[2] = '0';
}
else{ //people detected
danger[2] = '1';
}
usleep(100000);
}
return;
}
File added
detect 0 → 100755
File added
gpio.c 0 → 100644
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include"gpio.h"
int GPIOExport(int pin){
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;
}
int GPIODirection(int pin, int dir){
static const char s_directions_str[] = "in\0out";
char path[DIRECTION_MAX] = "/sys/class/gpio/gpio%d/direction";
int fd;
snprintf(path, 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");
close(fd);
return -1;
}
close(fd);
return 0;
}
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");
close(fd);
return -1;
}
close(fd);
return 0;
}
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");
close(fd);
return -1;
}
close(fd);
return(atoi(value_str));
}
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;
}
gpio.h 0 → 100644
#ifndef __GPIO_H__
#define __GPIO_H__
#define VALUE_MAX 256
#define BUFFER_MAX 3
#define DIRECTION_MAX 45
#define IN 0
#define OUT 1
#define LOW 0
#define HIGH 1
int GPIOExport(int pin);
int GPIODirection(int pin, int dir);
int GPIOWrite(int pin , int value);
int GPIORead(int pin);
int GPIOUnexport(int pin);
#endif
gpio.o 0 → 100644
File added
pwm.c 0 → 100644
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include"pwm.h"
int PWMExport(int pwmnum){
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;
}
int PWMEnable(int pwmnum){
static const char s_unenable_str[] = "0";
static const char s_enable_str[] = "1";
char path[DIRECTION_MAX];
int fd;
snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm%d/enable", pwmnum); // agian to check
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;
}
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); //check again
fd = open(path, O_WRONLY);
if(-1 == fd){
fprintf(stderr, "Failed to open in period!\n");
return -1;
}
byte = snprintf(s_values_str, VALUE_MAX, "%d", value); //check again
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;
}
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); //check this again
fd = open(path, O_WRONLY);
if(-1 == fd){
fprintf(stderr, "Faided to open in duty_cycle!\n");
return -1;
}
byte = snprintf(s_values_str, VALUE_MAX, "%d", value); //check this again
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;
}
pwm.h 0 → 100644
#ifndef __PWM_H__
#define __PWM_H__
#define VALUE_MAX 256
#define BUFFER_MAX 3
#define DIRECTION_MAX 45
int PWMExport(int pwmnum);
int PWMEnable(int pwmnum);
int PWMWritePeriod(int pwmnum, int value);
int PWMWriteDutyCycle(int pwmnum, int value);
#endif
pwm.o 0 → 100644
File added
spi 0 → 100755
File added
spi.c 0 → 100644
#include<stdint.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<getopt.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<linux/types.h>
#include<linux/spi/spidev.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<inttypes.h>
#include"spi.h"
int prepare(int fd){
if(ioctl(fd, SPI_IOC_WR_MODE, &MODE) == -1){
perror("Can't set MODE");
return -1;
}
if(ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &BITS) == -1){
perror("Can't set number of BITS");
return -1;
}
if(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &CLOCK) == -1){
perror("Can't set write CLOCK");
return -1;
}
if(ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &CLOCK) == -1){
perror("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){
perror("IO Error");
abort();
}
return ((rx[1] << 8) & 0x300) | (rx[2] & 0xFF);
}
spi.h 0 → 100644
#ifndef __SPI_H__
#define __SPI_H__
#define VALUE_MAX 256
#define BUFFER_MAX 3
#define DIRECTION_MAX 45
#define ARRAY_SIZE(array) sizeof(array) / sizeof(array[0])
const char *DEVICE = "/dev/spidev0.0";
uint8_t MODE = SPI_MODE_0;
uint8_t BITS = 8;
uint32_t CLOCK = 1000000;
uint8_t DELAY = 5;
int prepare(int fd);
uint8_t control_bits_differential(uint8_t channel);
uint8_t control_bits(uint8_t channel);
int readadc(int fd, uint8_t channel);
#endif
spi.o 0 → 100644
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment