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 ffeeb24..fe2eca1 100755 Binary files a/Timelapse_keyboard/timelapse.bin and b/Timelapse_keyboard/timelapse.bin differ diff --git a/Timelapse_keyboard/usbkeybrd.c b/Timelapse_keyboard/usbkeybrd.c index ecfe62c..b5b7a77 100644 --- a/Timelapse_keyboard/usbkeybrd.c +++ b/Timelapse_keyboard/usbkeybrd.c @@ -161,7 +161,7 @@ static const char *usb_strings[] = { /* Buffer to be used for control requests. */ uint8_t usbd_control_buffer[128]; - +static int got_config = 0; static int hid_control_request(usbd_device *usbddev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, void (**complete)(usbd_device *usbddev, struct usb_setup_data *req)){ (void)complete; @@ -174,7 +174,7 @@ static int hid_control_request(usbd_device *usbddev, struct usb_setup_data *req, *buf = (uint8_t *)hid_report_descriptor; *len = sizeof(hid_report_descriptor); - + got_config = 1; return 1; } @@ -209,15 +209,16 @@ void send_msg(char *msg){ put_char_to_buf(*(msg++)); } } - +/* void newline(){ put_char_to_buf('\n'); -} +}*/ /** * send data from keyboard buffer */ void process_usbkbrd(){ + if(!got_config) return; // don't allow sending messages until first connection - to prevent hangs static uint8_t pressed = 0; if(pressed){ // the keyboard was "pressed" if(8 == usbd_ep_write_packet(usbd_dev, 0x81, release_key(), 8)) diff --git a/Timelapse_keyboard/usbkeybrd.h b/Timelapse_keyboard/usbkeybrd.h index e1a5066..ab3de8f 100644 --- a/Timelapse_keyboard/usbkeybrd.h +++ b/Timelapse_keyboard/usbkeybrd.h @@ -36,7 +36,8 @@ void usbkeybrd_setup(); void print_hex(uint8_t *buff, uint8_t l); void print_int(int32_t N); -void newline(); +//void newline(); +#define newline() do{put_char_to_buf('\n');}while(0) #define poll_usbkeybrd() usbd_poll(usbd_dev)