mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
IR & photoresistor calibrated; added 5ms delay for ADC noice removal
This commit is contained in:
parent
05fe707864
commit
52447eef63
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.
@ -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))
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user