IR & photoresistor calibrated; added 5ms delay for ADC noice removal

This commit is contained in:
eddyem 2015-09-16 12:15:35 +03:00
parent 05fe707864
commit 52447eef63
7 changed files with 108 additions and 42 deletions

View File

@ -21,6 +21,7 @@
#include "adc.h" #include "adc.h"
#include "main.h" #include "main.h"
#include "usbkeybrd.h"
uint16_t ADC_value[ADC_CHANNEL_NUMBER]; // Values of ADC uint16_t ADC_value[ADC_CHANNEL_NUMBER]; // Values of ADC
uint16_t ADC_trig_val[2]; // -//- at trigger time 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 // 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 * Infrared sensor calibration
const uint16_t ADC_highlevel[2]= {2200, 5000}; // signal if ADC value > highlevel * 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(){ void poll_ADC(){
int i; int i;
for(i = 0; i < 2; ++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]; uint16_t val = ADC_value[i];
adwd_stat st = adc_status[i]; adwd_stat st = adc_status[i];
if(val > ADC_highlevel[i]){ // watchdog event on high level if(adcms == DIDNT_TRIGGERED){
if(st != ADWD_HI){ if(val > ADC_highlevel[i]){ // watchdog event on high level
adc_ms[i] = Timer; if(st != ADWD_HI){
memcpy(&adc_time[i], &current_time, sizeof(curtime)); adc_ms[i] = Timer;
adc_status[i] = ADWD_HI; memcpy(&adc_time[i], &current_time, sizeof(curtime));
ADC_trig_val[i] = val; 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], &current_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){ if((st == ADWD_HI && val < ADC_midlevel[i]) ||
adc_ms[i] = Timer; (st == ADWD_LOW && val > ADC_midlevel[i])){
memcpy(&adc_time[i], &current_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])){
adc_status[i] = ADWD_MID; adc_status[i] = ADWD_MID;
if(adc_ms[i] == Timer) // remove noice if(adcms != DIDNT_TRIGGERED){
adc_ms[i] = DIDNT_TRIGGERED; int32_t timediff = Timer - adcms;
if(timediff < 0) timediff += 1000;
if(timediff <= ADC_NOICE_TIMEOUT){ // remove noice
adc_ms[i] = DIDNT_TRIGGERED;
}
}
} }
} }
} }

View File

@ -36,12 +36,18 @@ typedef enum{
extern adwd_stat adc_status[]; extern adwd_stat adc_status[];
// pause for noice removal
#define ADC_NOICE_TIMEOUT (5)
// channels: 0 - IR, 1 - laser's photoresistor, 6 - 12V // channels: 0 - IR, 1 - laser's photoresistor, 6 - 12V
#define ADC_CHANNEL_NUMBER (3) #define ADC_CHANNEL_NUMBER (3)
// 10.8V - power alarm (resistor divider: 10kOhm : 3.0kOhm, U/100=7/20*ADC_value) // 10.8V - power alarm (resistor divider: 10kOhm : (3.0kOhm || zener), U/100=2/5*ADC_value)
#define POWER_ALRM_LEVEL (3086) // (11.15Vin == 2.25Vout)
#define POWER_ALRM_LEVEL (2705)
// critical voltage: approx 8V
#define POWER_CRITICAL_LEVEL (2000)
// 11.5V - power OK // 11.5V - power OK
#define GOOD_POWER_LEVEL (3286) #define GOOD_POWER_LEVEL (2880)
void init_adc_sensor(); void init_adc_sensor();
void poll_ADC(); void poll_ADC();

View File

@ -28,6 +28,7 @@
#include "ultrasonic.h" #include "ultrasonic.h"
#endif #endif
#include "adc.h" #include "adc.h"
#include <libopencm3/stm32/iwdg.h> // independent watchdog
volatile uint32_t Timer = 0; // global timer (milliseconds) volatile uint32_t Timer = 0; // global timer (milliseconds)
volatile uint32_t msctr = 0; // global milliseconds for different purposes volatile uint32_t msctr = 0; // global milliseconds for different purposes
@ -64,7 +65,7 @@ void time_increment(){
} }
int main(void){ int main(void){
uint8_t *string; uint8_t *string, *lastGPSans = NULL; // string from UART2 & pointer to last full GPS answer
int i; int i;
rcc_clock_setup_in_hse_8mhz_out_72mhz(); rcc_clock_setup_in_hse_8mhz_out_72mhz();
// init systick (1ms) // init systick (1ms)
@ -86,8 +87,8 @@ int main(void){
UART_init(USART2); // init GPS UART UART_init(USART2); // init GPS UART
#ifdef ULTRASONIC #ifdef ULTRASONIC
tim2_init(); // ultrasonic timer tim2_init(); // ultrasonic timer
//tim4_init(); // beeper timer
#endif #endif
//tim4_init(); // beeper timer
/* /*
for (i = 0; i < 0x80000; i++) for (i = 0; i < 0x80000; i++)
__asm__("nop"); __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) // istriggered == 1 after ANY trigger's event (set it to 1 at start to prevent false events)
// GPSLEDblink - GPS LED blinking // GPSLEDblink - GPS LED blinking
uint8_t istriggered = 1, GPSLEDblink = 0; uint8_t istriggered = 1, GPSLEDblink = 0;
iwdg_set_period_ms(50); // set watchdog timeout to 50ms
iwdg_start();
while(1){ while(1){
poll_usbkeybrd(); poll_usbkeybrd();
if(usbkbrdtm != msctr){ // process USB not frequently than once per 1ms if(usbkbrdtm != msctr){ // process USB not frequently than once per 1ms
@ -114,8 +117,20 @@ int main(void){
#endif #endif
poll_ADC(); poll_ADC();
if((string = check_UART2())){ if((string = check_UART2())){
lastGPSans = string;
GPS_parse_answer(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(istriggered){ // there was any trigger event
if(msctr - trigrtm > TRIGGER_DELAY || trigrtm > msctr){ // turn off LED & beeper if(msctr - trigrtm > TRIGGER_DELAY || trigrtm > msctr){ // turn off LED & beeper
istriggered = 0; istriggered = 0;
@ -129,26 +144,37 @@ int main(void){
#endif #endif
} }
}else{ }else{
if(trigger_ms != DIDNT_TRIGGERED){ if(trigger_ms != DIDNT_TRIGGERED){ // Control Button pressed
trigrtm = msctr; trigrtm = msctr;
istriggered = 1; istriggered = 1;
P("Button time: "); P("Button time: ");
print_time(&trigger_time, trigger_ms); 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){ // IR or Laser
for(i = 0; i < 2; ++i){ uint32_t adcms = adc_ms[i];
if(adc_ms[i] != DIDNT_TRIGGERED && !istriggered){ 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; trigrtm = msctr;
istriggered = 1; istriggered = 1;
if(i == 0) P("Infrared"); if(i == 0) P("Infrared");
else P("Laser"); else P("Laser");
P(" time: "); /* P(" trig val: ");
print_time(&adc_time[i], adc_ms[i]); print_int(ADC_trig_val[i]);*/
put_char_to_buf(' ');
//P(" time: ");
print_time(&adc_time[i], adcms);
} }
} }
//#endif
#ifdef ULTRASONIC #ifdef ULTRASONIC
if(ultrasonic_ms != DIDNT_TRIGGERED){ if(ultrasonic_ms != DIDNT_TRIGGERED && !istriggered){
trigrtm = msctr; trigrtm = msctr;
istriggered = 1; istriggered = 1;
P("Ultrasonic time: "); P("Ultrasonic time: ");
@ -168,7 +194,9 @@ int main(void){
// calculate blink time only if there's [was] too low level // calculate blink time only if there's [was] too low level
if(_12V < POWER_ALRM_LEVEL || powerLEDblink){ if(_12V < POWER_ALRM_LEVEL || powerLEDblink){
powerLEDblink = GOOD_POWER_LEVEL - _12V; 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 }else{ // power restored - LED R2 shines
if(powerLEDblink){ if(powerLEDblink){
@ -214,6 +242,7 @@ int main(void){
gpio_set(LEDS_G_PORT, LEDS_G1_PIN); gpio_set(LEDS_G_PORT, LEDS_G1_PIN);
} }
} }
iwdg_reset(); // reset watchdog
} }
} }

View File

@ -50,8 +50,8 @@ extern void *memcpy(void *dest, const void *src, int n);
#define DIDNT_TRIGGERED (2000) #define DIDNT_TRIGGERED (2000)
// debounce delay: 1.5s // debounce delay: .5s
#define TRIGGER_DELAY (1500) #define TRIGGER_DELAY (500)
typedef struct{ typedef struct{
uint8_t H; uint8_t H;

Binary file not shown.

View File

@ -161,7 +161,7 @@ static const char *usb_strings[] = {
/* Buffer to be used for control requests. */ /* Buffer to be used for control requests. */
uint8_t usbd_control_buffer[128]; 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, 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)(usbd_device *usbddev, struct usb_setup_data *req)){
(void)complete; (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; *buf = (uint8_t *)hid_report_descriptor;
*len = sizeof(hid_report_descriptor); *len = sizeof(hid_report_descriptor);
got_config = 1;
return 1; return 1;
} }
@ -209,15 +209,16 @@ void send_msg(char *msg){
put_char_to_buf(*(msg++)); put_char_to_buf(*(msg++));
} }
} }
/*
void newline(){ void newline(){
put_char_to_buf('\n'); put_char_to_buf('\n');
} }*/
/** /**
* send data from keyboard buffer * send data from keyboard buffer
*/ */
void process_usbkbrd(){ void process_usbkbrd(){
if(!got_config) return; // don't allow sending messages until first connection - to prevent hangs
static uint8_t pressed = 0; static uint8_t pressed = 0;
if(pressed){ // the keyboard was "pressed" if(pressed){ // the keyboard was "pressed"
if(8 == usbd_ep_write_packet(usbd_dev, 0x81, release_key(), 8)) if(8 == usbd_ep_write_packet(usbd_dev, 0x81, release_key(), 8))

View File

@ -36,7 +36,8 @@ void usbkeybrd_setup();
void print_hex(uint8_t *buff, uint8_t l); void print_hex(uint8_t *buff, uint8_t l);
void print_int(int32_t N); 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) #define poll_usbkeybrd() usbd_poll(usbd_dev)