Este sistema de luz automatizado se está desacelerando aleatoriamente

1

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?

Código:

# 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.

    
pregunta thekindlyone

2 respuestas

1

Si este es el esquema completo de su configuración, entonces falta algo que podría ser la causa del comportamiento observado:

Las tapas de desacoplamiento. O más precisamente, la falta de condensadores de desacoplamiento.

Intente colocar un capacitor de ~ 100nF entre GND y Vcc del ATmega. Lo más cerca posible de su pin de potencia. Los picos de voltaje, probablemente provenientes del relé, pueden perturbar, restablecer o hacer cosas extrañas a su ATmega. Y esto podría ser una causa del comportamiento observado.

Otros consejos:

  • Compruebe que tiene un diodo de rueda libre conectado a su entrada de relé.
  • Use un regulador de voltaje IC para alimentar su ATmega en lugar de una conexión directa a la batería.

Estas cosas garantizarían una fuente de alimentación limpia para su ATmega. Y esto es algo bueno. Especialmente cuando usas su ADC.

    
respondido por el Blup1980
0

EDIT: I have left the AVCC and AREF pins not connected. Is that a problem?

AVcc es la fuente de alimentación para el hardware ADC y es independiente de Vcc a menos que haya escrito a ADMUX para usar voltajes de referencia externa o para usar una referencia interna, que usted tiene.

De la Hoja de datos de AtMega32 :

  

El ADC tiene un pin de voltaje de suministro analógico separado, AVCC. AVCC no debe diferir más de ± 0.3V de VCC.   Los voltajes de referencia internos de 2.56V o AVCC se proporcionan en el chip. La referencia de tensión puede ser externa.   desacoplado en el pin AREF por un condensador para un mejor rendimiento de ruido.

Lo más seguro es que desee desacoplar el pin Aref con un condensador de desacoplamiento colocado cerca si no está suministrando un voltaje de referencia aquí; de lo contrario, este pin es una enorme fuente de ruido, especialmente en las tablas de pruebas.

Además, estoy bastante seguro de que debes conectar AVcc a algo; No creo que haya ningún cambio interno en el que Vcc se pueda acortar a AVcc .

Comenzaría haciendo que el ADC funcione correctamente asegurándome de que los valores de lectura son los que usted espera. Use un medidor de voltaje y un potenciómetro para verificar sus expectativas. Una vez que está funcionando, la parte de conmutación es solo un poco de código.

También tenga en cuenta que para eliminar aún más el ruido, puede apagar temporalmente la CPU durante el muestreo. Esta función se describe en la página 200 de la hoja de datos vinculada anteriormente.

    
respondido por el sherrellbc

Lea otras preguntas en las etiquetas