diff --git a/app b/app index e2e0be1a3fa097c90a616f73c9d4b7976634f06a..9ece996fa773f10eb55f7f19ed1823d6ab1f80c2 100755 Binary files a/app and b/app differ diff --git a/app.c b/app.c index 8b7ef8c5988c3a36eaec7f603856d0ea3a9e4408..727fc827207b8690baf6999e36f36f40d5f56797 100644 --- a/app.c +++ b/app.c @@ -2,84 +2,384 @@ #include <pthread.h> #include <unistd.h> #include <stdlib.h> +#include <wiringPi.h> +#include <wiringPiSPI.h> -// http://www.digipine.com/index.php?mid=clan&document_srl=584 +#include <fcntl.h> +#include <string.h> +#include <stdint.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/sysmacros.h> +#include <linux/spi/spidev.h> -#define TRUE 1 -#define FALSE 0 +#define LOADCELL_MAJOR_NUMBER 502 +#define LOADCELL_MINOR_NUMBER 100 +#define LOADCELL_DEV_PATH_NAME "/dev/loadcell_dev" +#define LOADCELL_THRESHOLD 10000 -#define THRESHOLD_ULTRASONIC_COMING 1234 +#define LED_PED_GREEN 18 +#define LED_CAR_RED 23 +#define LED_CAR_YELLOW 24 +#define LED_CAR_GREEN 25 + +#define HS_TRIG 2 +#define HS_ECHO 3 + +#define HS_MAX 1400 +#define HS_MIN 50 +#define HS_WAIT_THRESHOLD 10 +#define HS_INCOME_THRESHOLD 30 #define TERM_COMING 1 +#define SPI_DEV0_PATH "/dev/spidev0.0" +#define SPI_CHANNEL 0 +#define SPI_SPEED 1000000 +#define SPI_DELAY 0 +#define SPI_BPW 8 +#define ADC_CHANNEL 0 +#define WATER_THRESHOLD 300 + +#define MAIN_WAITTIME 3 + int isPedestrianComing = 0; +long weight = -1; +double distance = -1; +int adc_value = -1; +long tare = -1; + +void *hs_read(void *data){ + printf("hs_read() called\n"); + while(1){ + digitalWrite(HS_TRIG, HIGH); + delayMicroseconds(10); + digitalWrite(HS_TRIG, LOW); + unsigned int echoStart = millis(); + while(digitalRead(HS_ECHO) == LOW && millis()-echoStart < 1000) { + // do nothing + } + if (millis()-echoStart < 1000) { + // Mark start + unsigned int start = micros(); + while(digitalRead(HS_ECHO) == HIGH) { + // do nothing + } + // Mark end + unsigned int end = micros(); + unsigned int delta = end-start; + + if(delta < HS_MAX && delta > HS_MIN){ + distance = 34029 * delta / 2000000.0; + //printf("Distance: %f\n", distance); + } + else distance = -1; + } + } + +} -void *t_function(void *data){ - int buf1 = 0; - int buf2 = 0; - int buf3 = 0; +void *water_read(void *data){ + unsigned char buffer[3]; + struct spi_ioc_transfer spi; + int spiFds = *(int *)data; + + buffer[0] = 1; + buffer[1] = (8 + ADC_CHANNEL) << 4; + buffer[2] = 0; + memset(&spi, 0, sizeof(spi)); + spi.tx_buf = (unsigned long)buffer; + spi.rx_buf = (unsigned long)buffer; + spi.len = 3; + spi.delay_usecs = (uint16_t) SPI_DELAY; + spi.speed_hz = (uint16_t) SPI_SPEED; + spi.bits_per_word = (uint8_t) SPI_BPW; - // ultrasonic.read(&buf1); + while (1) { + ioctl(spiFds, SPI_IOC_MESSAGE(1), &spi); + adc_value = ((buffer[1] & 3) << 8) + buffer[2]; + delay(100); + } +} + +void *incoming_validate(void *data){ + double buf1 = 0; + double buf2 = 0; + double buf3 = 0; + //printf("thread opened\n"); + while(distance<0){ + //printf("distance not ready\n"); + sleep(1); + } + + buf1 = distance; sleep(TERM_COMING); - // ultrasonic.read(&buf2); + + while(distance<0){ + //printf("distance not ready\n"); + sleep(1); + } + buf2 = distance; sleep(TERM_COMING); while(TRUE){ - // ultrasonic.read(&buf3); - if(buf3 > THRESHOLD_ULTRASONIC_COMING - && buf2 - buf1 > 0 - && buf3 - buf2 > 0){ + while(distance<0){ + isPedestrianComing = FALSE; + //printf("distance not ready\n"); + sleep(1); + } + buf3 = distance; + if(buf3 < HS_INCOME_THRESHOLD + & ((isPedestrianComing == TRUE) + || (buf2 - buf1 < 0 + && buf3 - buf2 < 0))){ isPedestrianComing = TRUE; - printf("true\n"); + //printf("%2.1f %2.1f %2.1f true\n",buf1,buf2,buf3); } else{ isPedestrianComing = FALSE; - printf("false\n"); + //printf("%2.1f %2.1f %2.1f false\n",buf1,buf2,buf3); } sleep(TERM_COMING); - // ultrasonic.read(&buf1); - if(buf1 > THRESHOLD_ULTRASONIC_COMING - && buf3 - buf2 > 0 - && buf1 - buf3 > 0){ + while(distance<0){ + isPedestrianComing = FALSE; + //printf("distance not ready\n"); + sleep(1); + } + buf1 = distance; + if(buf1 < HS_INCOME_THRESHOLD + & ((isPedestrianComing == TRUE) + || (buf3 - buf2 < 0 + && buf1 - buf3 < 0))){ isPedestrianComing = TRUE; - printf("true\n"); + //printf("%2.1f %2.1f %2.1f true\n",buf2,buf3,buf1); } else{ isPedestrianComing = FALSE; - printf("false\n"); + //printf("%2.1f %2.1f %2.1f false\n",buf2,buf3,buf1); } sleep(TERM_COMING); - // ultrasonic.read(&buf2); - if(buf2 > THRESHOLD_ULTRASONIC_COMING - && buf1 - buf3 > 0 - && buf2 - buf1 > 0){ + while(distance<0){ + isPedestrianComing = FALSE; + //printf("distance not ready\n"); + sleep(1); + } + buf2 = distance; + if(buf2 < HS_INCOME_THRESHOLD + & ((isPedestrianComing == TRUE) + || (buf1 - buf3 < 0 + && buf2 - buf1 < 0))){ isPedestrianComing = TRUE; - printf("true\n"); + //printf("%2.1f %2.1f %2.1f true\n",buf3,buf1,buf2); } else{ isPedestrianComing = FALSE; - printf("false\n"); + //printf("%2.1f %2.1f %2.1f false\n",buf3,buf1,buf2); } sleep(TERM_COMING); } } +/* +void *weight_read(void *data){ + int loadcell_fd = *(int*)data; + int i, test; + long buffer[1]; + long sample[5]; + long avg; + + while(1){ + *buffer = -1; + while(*buffer < 3000 || *buffer >= 200000){ + usleep(100); + read(loadcell_fd,buffer,4); + } + + } + + test = 0; + while(test<5){ + test = 0; + avg=0; + for(i=0;i<5;i++){ + read(loadcell_fd,buffer,4); + while(*buffer < 0 || *buffer >= 0x7fffff){ + usleep(100000); + read(loadcell_fd,buffer,4); + } + //printf("%ld ",*buffer); + sample[i] = *buffer; + avg += sample[i]; + } + avg /= 5; + for(i=0;i<5;i++){ + if((sample[i] - avg) < (avg*0.1) + && (sample[i] - avg) > -(avg*0.1)){ + test++; + //printf("test+ "); + } + //else printf("test- "); + } + //printf("avg: %ld \n",avg); + } + tare = avg; + + while(1){ + test = 0; + avg = 0; + for(i=0;i<3;i++){ + read(loadcell_fd,buffer,4); + while(*buffer < 0 || *buffer >= 0x7fffff){ + usleep(100000); + read(loadcell_fd,buffer,4); + } + sample[i] = *buffer; + avg += sample[i]; + } + avg /= 3; + //printf("avg: %ld / ",avg); + for(i=0;i<3;i++){ + if((sample[i] - avg) < (avg*0.1) + && (sample[i] - avg) > -(avg*0.1)){ + test++; + //printf("%ld+ ",sample[i]); + } + //else printf("%ld- ",sample[i]); + } + //printf("\n"); + if(test == 3){ + weight = avg - tare; + //printf("weighted : %ld",weight); + } + sleep(1); + } +} +*/ int main(void){ - pthread_t incomeCheckThread; - int status; + pthread_t waterThread, hsReadThread, incomeCheckThread, weightThread; + //setbuf(stdout, NULL); - if(pthread_create(&incomeCheckThread, NULL, t_function, (void *)NULL) < 0){ + int rc = wiringPiSetupGpio(); + if (rc != 0) { + printf("Failed to wiringPiSetupGpio()\n"); + return 0; + } + + // setup trafficlight + pinMode(LED_PED_GREEN, OUTPUT); + pinMode(LED_CAR_RED, OUTPUT); + pinMode(LED_CAR_YELLOW, OUTPUT); + pinMode(LED_CAR_GREEN, OUTPUT); +/* + // setup weight + int loadcell_dev = open(LOADCELL_DEV_PATH_NAME, O_RDWR < 0); + if(loadcell_dev < 0){ + printf("Failed to open loadcell device\n"); + return -1; + } + if(pthread_create(&weightThread, NULL, weight_read, (void *)&loadcell_dev) < 0){ perror("thread create error: "); exit(0); } + // waiting tare + printf("init weight tare, plz wait..\n"); while(1){ - printf("main read: %d\n", isPedestrianComing); - sleep(1); + if(tare>0) break; + } + printf("tare init done: %ld\n",tare); + */ + + // setup water + int waterdev = open(SPI_DEV0_PATH, O_RDWR < 0); + if(waterdev < 0){ + printf("Failed to open water device\n"); + return -1; + } + + if(pthread_create(&waterThread, NULL, water_read, (void *)&waterdev) < 0){ + perror("thread create error: "); + exit(0); + } + + // setup hs + pinMode(HS_TRIG, OUTPUT); + pinMode(HS_ECHO, INPUT); + digitalWrite(HS_TRIG, LOW); + if(pthread_create(&hsReadThread, NULL, hs_read, (void *)NULL) < 0){ + perror("thread create error: "); + exit(0); + } + + if(pthread_create(&incomeCheckThread, NULL, incoming_validate, (void *)NULL) < 0){ + perror("thread create error: "); + exit(0); } - pthread_join(incomeCheckThread, (void *)&status); - printf("thread join : %d\n", status); + int yellowTime; + int pedestrianTime; + int extendCount; + + while(1){ + digitalWrite(LED_PED_GREEN,LOW); // pedestrian = red + digitalWrite(LED_CAR_RED,LOW); + digitalWrite(LED_CAR_YELLOW,LOW); + digitalWrite(LED_CAR_GREEN,HIGH); // car = green + + while(distance<0){ + printf("waiting pedestrian now..\n"); + sleep(MAIN_WAITTIME); + } + if(distance < HS_WAIT_THRESHOLD){ + printf("pedestrian accepted. validating now..\n"); + sleep(MAIN_WAITTIME); + if(distance < HS_WAIT_THRESHOLD && distance != -1){ + // pedestrian waited enough, give him signal + printf("pedestrian validated. turn on yellow\n"); + if(adc_value > WATER_THRESHOLD){ + // road is slippy, long yellow light time + yellowTime = MAIN_WAITTIME *2; + } + else{ + yellowTime = MAIN_WAITTIME; + } + + digitalWrite(LED_CAR_YELLOW,HIGH); + digitalWrite(LED_CAR_GREEN,LOW); // car = yellow + printf("yellow-> sleep %d\n",yellowTime); + sleep(yellowTime); + + digitalWrite(LED_PED_GREEN,HIGH); // pedestrian = green + digitalWrite(LED_CAR_RED,HIGH); + digitalWrite(LED_CAR_YELLOW,LOW); // car = red + pedestrianTime = MAIN_WAITTIME *5; + extendCount = 0; + while(pedestrianTime > 0){ + sleep(MAIN_WAITTIME); + pedestrianTime -= MAIN_WAITTIME; + if(weight < LOADCELL_THRESHOLD + && isPedestrianComing == TRUE + && extendCount < 3){ + // car is NOT waiting, pedestrian coming. + pedestrianTime += MAIN_WAITTIME; + extendCount++; + printf("pedestrian ++, pedestrian = %d\n", pedestrianTime); + } + else{ + printf("pedestrian --, pedestrian = %d\n", pedestrianTime); + } + } + } + else{ + printf("pedestrian declined, move to first step..\n"); + } + } + } + + + digitalWrite(LED_PED_GREEN,LOW); + digitalWrite(LED_CAR_RED,LOW); + digitalWrite(LED_CAR_GREEN,LOW); return 0; }