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 "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,16 +65,37 @@ 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(adcms == DIDNT_TRIGGERED){
if(val > ADC_highlevel[i]){ // watchdog event on high level
if(st != ADWD_HI){
adc_ms[i] = Timer;
@ -88,11 +110,18 @@ void poll_ADC(){
adc_status[i] = ADWD_LOW;
ADC_trig_val[i] = val;
}
}else if((st == ADWD_HI && 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
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;
}
}
}
}
}

View File

@ -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();

View File

@ -28,6 +28,7 @@
#include "ultrasonic.h"
#endif
#include "adc.h"
#include <libopencm3/stm32/iwdg.h> // 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
}
}

View File

@ -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;

Binary file not shown.

View File

@ -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))

View File

@ -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)