Started following some tutorial on att85 usi. Downloaded example code from make avr book.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Sensitive footstep-detector and EWMA demo
|
||||
*/
|
||||
|
||||
// ------- Preamble -------- //
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/sleep.h>
|
||||
#include "pinDefines.h"
|
||||
#include "USART.h"
|
||||
|
||||
#define ON_TIME 2000 /* milliseconds */
|
||||
#define CYCLE_DELAY 10 /* milliseconds */
|
||||
#define INITIAL_PADDING 16 /* higher is less sensitive */
|
||||
|
||||
#define SWITCH PB7 /* Attach LED or switch relay here */
|
||||
|
||||
#define USE_POT 0 /* define to 1 if using potentiometer */
|
||||
#if USE_POT
|
||||
#define POT PC5 /* optional padding pot */
|
||||
#endif
|
||||
|
||||
// -------- Functions --------- //
|
||||
void initADC(void) {
|
||||
ADMUX |= (1 << REFS0); /* reference voltage to AVCC */
|
||||
ADCSRA |= (1 << ADPS1) | (1 << ADPS2); /* ADC clock prescaler /64 */
|
||||
ADCSRA |= (1 << ADEN); /* enable ADC */
|
||||
}
|
||||
|
||||
uint16_t readADC(uint8_t channel) {
|
||||
ADMUX = (0b11110000 & ADMUX) | channel;
|
||||
ADCSRA |= (1 << ADSC);
|
||||
loop_until_bit_is_clear(ADCSRA, ADSC);
|
||||
return (ADC);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// -------- Inits --------- //
|
||||
uint16_t lightsOutTimer = 0; /* timer for the switch */
|
||||
uint16_t adcValue;
|
||||
uint16_t middleValue = 511;
|
||||
uint16_t highValue = 520;
|
||||
uint16_t lowValue = 500;
|
||||
uint16_t noiseVolume = 0;
|
||||
uint8_t padding = INITIAL_PADDING;
|
||||
|
||||
LED_DDR = ((1 << LED0) | (1 << LED1) | (1 << SWITCH));
|
||||
initADC();
|
||||
initUSART();
|
||||
|
||||
// ------ Event loop ------ //
|
||||
while (1) {
|
||||
adcValue = readADC(PIEZO);
|
||||
|
||||
/* moving average -- tracks sensor's bias voltage */
|
||||
middleValue = adcValue + middleValue - ((middleValue - 8) >> 4);
|
||||
/* moving averages for positive and negative parts of signal */
|
||||
if (adcValue > (middleValue >> 4)) {
|
||||
highValue = adcValue + highValue - ((highValue - 8) >> 4);
|
||||
}
|
||||
if (adcValue < (middleValue >> 4)) {
|
||||
lowValue = adcValue + lowValue - ((lowValue - 8) >> 4);
|
||||
}
|
||||
/* "padding" provides a minimum value for the noise volume */
|
||||
noiseVolume = highValue - lowValue + padding;
|
||||
|
||||
/* Now check to see if ADC value above or below thresholds */
|
||||
/* Comparison with >> 4 b/c EWMA is on different scale */
|
||||
if (adcValue < ((middleValue - noiseVolume) >> 4)) {
|
||||
LED_PORT = (1 << LED0) | (1 << SWITCH); /* one LED, switch */
|
||||
lightsOutTimer = ON_TIME / CYCLE_DELAY; /* reset timer */
|
||||
}
|
||||
else if (adcValue > ((middleValue + noiseVolume) >> 4)) {
|
||||
LED_PORT = (1 << LED1) | (1 << SWITCH); /* other LED, switch */
|
||||
lightsOutTimer = ON_TIME / CYCLE_DELAY; /* reset timer */
|
||||
}
|
||||
else { /* Nothing seen, turn off lights */
|
||||
LED_PORT &= ~(1 << LED0);
|
||||
LED_PORT &= ~(1 << LED1); /* Both off */
|
||||
if (lightsOutTimer > 0) { /* time left on timer */
|
||||
lightsOutTimer--;
|
||||
}
|
||||
else { /* time's up */
|
||||
LED_PORT &= ~(1 << SWITCH); /* turn switch off */
|
||||
}
|
||||
}
|
||||
#if USE_POT /* optional padding potentiometer */
|
||||
padding = readADC(POT) >> 4; /* scale down to useful range */
|
||||
#endif
|
||||
/* Serial output and delay */
|
||||
/* ADC is 10-bits, recenter around 127 for display purposes */
|
||||
transmitByte(adcValue - 512 + 127);
|
||||
transmitByte((lowValue >> 4) - 512 + 127);
|
||||
transmitByte((highValue >> 4) - 512 + 127);
|
||||
_delay_ms(CYCLE_DELAY);
|
||||
} /* End event loop */
|
||||
return 0; /* This line is never reached */
|
||||
}
|
||||
Reference in New Issue
Block a user