Un sensor PIR envía una entrada al AVR (ATmega 32A), cuando se recibe una entrada y el ADC (LDR) está por debajo de un valor crítico, PB0 debe subir para activar un relé. Un temporizador cuenta los segundos para que el relé se pueda desactivar después de 3 minutos sin señal PIR.
Funciona, pero a veces lleva mucho tiempo responder, y en momentos aleatorios es instantáneo. ¿Qué debo hacer?
EDITAR: He dejado los pines AVCC y AREF no conectados. ¿Es eso un problema?
# include <avr/io.h>
# define START 1
# define STOP 0
# define RESET 3
# define TRUE 1
# define FALSE 0
uint8_t seconds=0;
void stopwatch(void)
{
seconds=0;
TCNT1=0;
TCCR1B |= 1<<CS10|1<<CS11;//timer counter control register started with prescale 64
}
void InitADC()
{
ADMUX=(1<<REFS0); // For Aref=AVcc;
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128
}
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
//Note you may be wondering why we have write one to clear it
//This is standard way of clearing bits in io as said in datasheets.
//The code writes '1' but it result in setting bit to '0' !!!
ADCSRA|=(1<<ADIF);
return(ADC);
}
int main(void)
{ uint16_t adc_result;
InitADC();
DDRB=0b00000101;
PORTB=0b00000000;
char lightoff=TRUE;
//stopwatch();
while (1)
{
//adc_result=ReadADC(1);
//*****clock work***********
if(TCNT1>15625)
{
TCNT1=0;
seconds++;
}
//********************
if(bit_is_set(PINB,1) && lightoff && ReadADC(1)<700)
{
PORTB|=_BV(0);
lightoff=FALSE;
stopwatch();
}
if(bit_is_set(PINB,1)&& !lightoff)
{
stopwatch();
}
if(seconds>180 && !lightoff){
PORTB&=~_BV(0);
lightoff=TRUE;
TCCR1B = 0; // stop clock
seconds=0;
}
}
}
EDITAR:
La desaceleración no es tan aleatoria como inicialmente pensé. Solo responde tarde si se ha estado ejecutando durante un largo tiempo sin que el pin B1 se haya elevado del PIR. Es rápido si se ha activado al menos en los últimos 30 minutos.