From 52447eef632dabb3d55849756c202afafbe2b247 Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 16 Sep 2015 12:15:35 +0300 Subject: [PATCH] IR & photoresistor calibrated; added 5ms delay for ADC noice removal --- Timelapse_keyboard/adc.c | 71 ++++++++++++++++++++++--------- Timelapse_keyboard/adc.h | 12 ++++-- Timelapse_keyboard/main.c | 51 +++++++++++++++++----- Timelapse_keyboard/main.h | 4 +- Timelapse_keyboard/timelapse.bin | Bin 9712 -> 10064 bytes Timelapse_keyboard/usbkeybrd.c | 9 ++-- Timelapse_keyboard/usbkeybrd.h | 3 +- 7 files changed, 108 insertions(+), 42 deletions(-) diff --git a/Timelapse_keyboard/adc.c b/Timelapse_keyboard/adc.c index 9568d0d..1467a67 100644 --- a/Timelapse_keyboard/adc.c +++ b/Timelapse_keyboard/adc.c @@ -21,6 +21,7 @@ #include "adc.h" #include "main.h" +#include "usbkeybrd.h" uint16_t ADC_value[ADC_CHANNEL_NUMBER]; // Values of ADC uint16_t ADC_trig_val[2]; // -//- at trigger time @@ -64,35 +65,63 @@ adwd_stat adc_status[ADC_CHANNEL_NUMBER] = {ADWD_MID, ADWD_MID, ADWD_MID}; // levels for thresholding -const uint16_t ADC_lowlevel[2] = {1800, 2700}; // signal if ADC value < lowlevel -const uint16_t ADC_midlevel[2] = {2000, 3000}; // when transit through midlevel set status as ADWD_MID -const uint16_t ADC_highlevel[2]= {2200, 5000}; // signal if ADC value > highlevel +/* + * Infrared sensor calibration + * distance, cm ADC value, ADU (+- 3%) + * 0 100 + * 10 3300 + * 20 3170 + * 30 2400 + * 40 1720 + * 50 1400 + * 60 1200 + * 70 1100 + * 80 980 + * 90 860 + * 100 760 + * 145 490 + * + * IR distance \approx 74000/ADU (cm) + * + * Laser photoresistor: 2700 ADU in laser beam, 1760 in light room, 300 when darkened + */ +const uint16_t ADC_lowlevel[2] = {0, 2000}; // signal if ADC value < lowlevel +const uint16_t ADC_midlevel[2] = {400, 2500}; // when transit through midlevel set status as ADWD_MID +const uint16_t ADC_highlevel[2]= {800, 5000}; // signal if ADC value > highlevel void poll_ADC(){ int i; for(i = 0; i < 2; ++i){ - if(adc_ms[i] != DIDNT_TRIGGERED) continue; + uint32_t adcms = adc_ms[i]; uint16_t val = ADC_value[i]; adwd_stat st = adc_status[i]; - if(val > ADC_highlevel[i]){ // watchdog event on high level - if(st != ADWD_HI){ - adc_ms[i] = Timer; - memcpy(&adc_time[i], ¤t_time, sizeof(curtime)); - adc_status[i] = ADWD_HI; - ADC_trig_val[i] = val; + if(adcms == DIDNT_TRIGGERED){ + if(val > ADC_highlevel[i]){ // watchdog event on high level + if(st != ADWD_HI){ + adc_ms[i] = Timer; + memcpy(&adc_time[i], ¤t_time, sizeof(curtime)); + adc_status[i] = ADWD_HI; + ADC_trig_val[i] = val; + } + }else if(val < ADC_lowlevel[i]){ // watchdog event on low level + if(st != ADWD_LOW){ + adc_ms[i] = Timer; + memcpy(&adc_time[i], ¤t_time, sizeof(curtime)); + adc_status[i] = ADWD_LOW; + ADC_trig_val[i] = val; + } } - }else if(val < ADC_lowlevel[i]){ // watchdog event on low level - if(st != ADWD_LOW){ - adc_ms[i] = Timer; - memcpy(&adc_time[i], ¤t_time, sizeof(curtime)); - adc_status[i] = ADWD_LOW; - ADC_trig_val[i] = val; - } - }else if((st == ADWD_HI && val < ADC_midlevel[i]) || - (st == ADWD_LOW && val > ADC_midlevel[i])){ + } + if((st == ADWD_HI && val < ADC_midlevel[i]) || + (st == ADWD_LOW && val > ADC_midlevel[i])){ adc_status[i] = ADWD_MID; - if(adc_ms[i] == Timer) // remove noice - adc_ms[i] = DIDNT_TRIGGERED; + if(adcms != DIDNT_TRIGGERED){ + int32_t timediff = Timer - adcms; + if(timediff < 0) timediff += 1000; + if(timediff <= ADC_NOICE_TIMEOUT){ // remove noice + adc_ms[i] = DIDNT_TRIGGERED; + } + } } } } diff --git a/Timelapse_keyboard/adc.h b/Timelapse_keyboard/adc.h index f55c171..7692187 100644 --- a/Timelapse_keyboard/adc.h +++ b/Timelapse_keyboard/adc.h @@ -36,12 +36,18 @@ typedef enum{ extern adwd_stat adc_status[]; +// pause for noice removal +#define ADC_NOICE_TIMEOUT (5) + // channels: 0 - IR, 1 - laser's photoresistor, 6 - 12V #define ADC_CHANNEL_NUMBER (3) -// 10.8V - power alarm (resistor divider: 10kOhm : 3.0kOhm, U/100=7/20*ADC_value) -#define POWER_ALRM_LEVEL (3086) +// 10.8V - power alarm (resistor divider: 10kOhm : (3.0kOhm || zener), U/100=2/5*ADC_value) +// (11.15Vin == 2.25Vout) +#define POWER_ALRM_LEVEL (2705) +// critical voltage: approx 8V +#define POWER_CRITICAL_LEVEL (2000) // 11.5V - power OK -#define GOOD_POWER_LEVEL (3286) +#define GOOD_POWER_LEVEL (2880) void init_adc_sensor(); void poll_ADC(); diff --git a/Timelapse_keyboard/main.c b/Timelapse_keyboard/main.c index 602e824..c125220 100644 --- a/Timelapse_keyboard/main.c +++ b/Timelapse_keyboard/main.c @@ -28,6 +28,7 @@ #include "ultrasonic.h" #endif #include "adc.h" +#include // independent watchdog volatile uint32_t Timer = 0; // global timer (milliseconds) volatile uint32_t msctr = 0; // global milliseconds for different purposes @@ -64,7 +65,7 @@ void time_increment(){ } int main(void){ - uint8_t *string; + uint8_t *string, *lastGPSans = NULL; // string from UART2 & pointer to last full GPS answer int i; rcc_clock_setup_in_hse_8mhz_out_72mhz(); // init systick (1ms) @@ -86,8 +87,8 @@ int main(void){ UART_init(USART2); // init GPS UART #ifdef ULTRASONIC tim2_init(); // ultrasonic timer - //tim4_init(); // beeper timer #endif + //tim4_init(); // beeper timer /* for (i = 0; i < 0x80000; i++) __asm__("nop"); @@ -103,6 +104,8 @@ int main(void){ // istriggered == 1 after ANY trigger's event (set it to 1 at start to prevent false events) // GPSLEDblink - GPS LED blinking uint8_t istriggered = 1, GPSLEDblink = 0; + iwdg_set_period_ms(50); // set watchdog timeout to 50ms + iwdg_start(); while(1){ poll_usbkeybrd(); if(usbkbrdtm != msctr){ // process USB not frequently than once per 1ms @@ -114,8 +117,20 @@ int main(void){ #endif poll_ADC(); if((string = check_UART2())){ + lastGPSans = string; GPS_parse_answer(string); } +/* +if(msctr - trigrtm > 3000){ + trigrtm = msctr; + for(i = 0; i < 3; ++i){ // IR or Laser + P("ADC"); + put_char_to_buf('0' + i); + P(" val: "); + print_int(ADC_value[i]); + newline(); + } +}*/ if(istriggered){ // there was any trigger event if(msctr - trigrtm > TRIGGER_DELAY || trigrtm > msctr){ // turn off LED & beeper istriggered = 0; @@ -129,26 +144,37 @@ int main(void){ #endif } }else{ - if(trigger_ms != DIDNT_TRIGGERED){ + if(trigger_ms != DIDNT_TRIGGERED){ // Control Button pressed trigrtm = msctr; istriggered = 1; P("Button time: "); print_time(&trigger_time, trigger_ms); + if(lastGPSans){ + P("GPS last message: "); + send_msg((char*)lastGPSans); + newline(); + } } - //#if 0 - for(i = 0; i < 2; ++i){ - if(adc_ms[i] != DIDNT_TRIGGERED && !istriggered){ + for(i = 0; i < 2; ++i){ // IR or Laser + uint32_t adcms = adc_ms[i]; + if(adcms == DIDNT_TRIGGERED) continue; + int32_t timediff = Timer - adcms; + if(timediff < 0) timediff += 1000; + // pause for noice removal + if(timediff > ADC_NOICE_TIMEOUT && !istriggered){ trigrtm = msctr; istriggered = 1; if(i == 0) P("Infrared"); else P("Laser"); - P(" time: "); - print_time(&adc_time[i], adc_ms[i]); + /* P(" trig val: "); + print_int(ADC_trig_val[i]);*/ + put_char_to_buf(' '); + //P(" time: "); + print_time(&adc_time[i], adcms); } } - //#endif #ifdef ULTRASONIC - if(ultrasonic_ms != DIDNT_TRIGGERED){ + if(ultrasonic_ms != DIDNT_TRIGGERED && !istriggered){ trigrtm = msctr; istriggered = 1; P("Ultrasonic time: "); @@ -168,7 +194,9 @@ int main(void){ // calculate blink time only if there's [was] too low level if(_12V < POWER_ALRM_LEVEL || powerLEDblink){ powerLEDblink = GOOD_POWER_LEVEL - _12V; - if(powerLEDblink > 900) powerLEDblink = 900; // shadow LED not more than 0.9s + // critical level: power LED is almost OFF + if(_12V < POWER_CRITICAL_LEVEL) powerLEDblink = 990; + //if(powerLEDblink > 990) powerLEDblink = 990; // shadow LED not more than 0.99s } }else{ // power restored - LED R2 shines if(powerLEDblink){ @@ -214,6 +242,7 @@ int main(void){ gpio_set(LEDS_G_PORT, LEDS_G1_PIN); } } + iwdg_reset(); // reset watchdog } } diff --git a/Timelapse_keyboard/main.h b/Timelapse_keyboard/main.h index 65a235e..6f17e29 100644 --- a/Timelapse_keyboard/main.h +++ b/Timelapse_keyboard/main.h @@ -50,8 +50,8 @@ extern void *memcpy(void *dest, const void *src, int n); #define DIDNT_TRIGGERED (2000) -// debounce delay: 1.5s -#define TRIGGER_DELAY (1500) +// debounce delay: .5s +#define TRIGGER_DELAY (500) typedef struct{ uint8_t H; diff --git a/Timelapse_keyboard/timelapse.bin b/Timelapse_keyboard/timelapse.bin index ffeeb24017caaa6915edefa3a2f2dbc42719122f..fe2eca11cd94cade97810c3318aa96738cdc77e1 100755 GIT binary patch delta 3220 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 v*K7su3d-#$k09#t5H^