/*
ATtiny45
Capacitive sensor
Pros 2010
*/
#define F_CPU 8000000UL
#define OUT _BV(PB3)
#define _OUT _BV(PB4)
#define TST _BV(PB1)
#define LED _BV(PB0)
#define NO 0xAA
#define YES 0x55
#define GEM 16
#include <avr/io.h>
#include <avr/interrupt.h>
#include <compat/deprecated.h>
#include <util/delay.h>
volatile unsigned char ref, tcnt0_gem, T, INT;
volatile unsigned int init_cnt, cnt, err_cnt, gem_cnt;
#define delay(x) _delay_loop_1(x)
void delay_ms(unsigned int ms)
{
for (; ms > 0; ms--) {
_delay_ms(0.99);
}
}
void delay_us(unsigned int us)
{
for (; us > 0; us--) {
_delay_us(0.95);
}
}
ISR(TIMER1_OVF_vect)
{ // 7812 maal per seconde
T = TCNT0; // 123 ... 136
TCNT0 = 0; // Teller terug op 0 zetten
INT = YES; // Vlag zetten voor main()
}
ISR(TIMER0_OVF_vect)
{
}
// Verstandige waarden voor PART: 8 (erg ongevoelig), 16, 32, 64 (heel gevoelig)
#define PART 64
int main(void)
{
CLKPR = (1 << CLKPCE);
CLKPR = 0; // Schakel CLKDIV8 uit
TCCR0A = 0; // Counter0 telt voordurend van 0 tot 255
TCCR0B = _BV(CS01) | _BV(CS02); // op het ritme van T0 (PB2)
TCCR1 = _BV(CS10) | _BV(CS11); // Counter1-CLK = F_CPU / 4 = 2MHz
GTCCR = 0;
TIMSK = _BV(TOIE1); // Enable overflow-interrupt
DDRB = OUT | _OUT | LED | TST;
PORTB |= LED | _OUT;
delay_ms(2000);
init_cnt = 0;
err_cnt = 0;
gem_cnt = 0;
INT = NO;
delay_ms(5000);
PORTB = _OUT; // _OUT is default hoog
sei(); // Enable global interrupts
delay_ms(2000);
while (1) {
while (INT == NO) { // Wacht op het eind
} // van de volgende telronde
INT = NO; // Interrupt-vlag resetten
if (init_cnt == 0) { // Eerste sample?
tcnt0_gem = T; // tcnt0_gem initialiseren ±134
init_cnt = 1;
} else if (init_cnt < 10000) { // Nog aan het initialiseren?
init_cnt++;
tcnt0_gem -= (tcnt0_gem / PART); // 1/PART aftrekken
ref = tcnt0_gem; // En als referentie gebruiken
//ref += 3; // Een beetje erbij
tcnt0_gem += (T / PART); // Nieuw gemiddelde berekenen
if (init_cnt > 9900) {
PORTB = _OUT;
} else if (init_cnt > 8000) {
PORTB |= LED;
}
} else { // Normaal bedrijf
if (T < ref) { // Lage frequentie? (±124)
if (err_cnt > 250) { // 250 maal na mekaar?
PORTB = OUT | LED; // OUT en LED hoog, _OUT laag
delay_ms(5000); // 5 seconden wachten
PORTB = _OUT; // _OUT is default hoog
delay_ms(10000); // 10 seconden inactief blijven
init_cnt = 0; // en terug initialiseren
err_cnt = 0;
} else {
err_cnt++;
}
} else { // Gemiddelde bijwerken
gem_cnt++; // Dat doen we maar
if (gem_cnt > 1000) { // 7 maal per seconde
tcnt0_gem -= (tcnt0_gem / PART); // 1/PART aftrekken
ref = tcnt0_gem; // Resultaat als referentie gebruiken
//ref += 3; // Een beetje erbij
tcnt0_gem += (T / PART); // Nieuw gemiddelde berekenen
gem_cnt = 0;
}
}
}
}
}