El sensor PIR se activa solo cuando se usa el temporizador, funciona sin temporizador

4

TL; DR

Un sensor PIR se activa solo cuando se usa un temporizador para esperar 2 segundos después de que se active el sensor. Sin usar el temporizador para esperar, el sensor funciona como se esperaba.

Fondo y configuración

Tengo un sensor PIR conectado a un ATMega328p . El sensor PIR tiene tres pines; VCC , GND y AL . El pin AL usa el colector abierto para mostrar que el movimiento es detectado

Lo que he hecho es que conecté el pin AL al pin PC0 en mi ATMega y configuré el pin como entrada con resistencia interna de extracción y un LED conectado a PC5 para mostrar cuando se detecta movimiento:

void setup_default_values()
{
        DDRC |= (1 << PC5);
        DDRC &= ~(1 << PC0);

        PORTC |= (1 << PC0);
}

Luego tengo una función que comprueba cuando el PC0 pin es LOW :

void check_sensor()
{
        if (PINC & (1 << PC0)) {
                PORTC &= ~(1 << PC5);
        }else{
                PORTC |= (1 << PC5);
        }
}

Esta función enciende el LED cuando PC0 es LOW y lo apaga cuando PC0 es HIGH . Esta función se ejecuta en todos los ciclos de mi ciclo principal:

int main()
{
        setup_default_values();
        blink(4);

    for (;;) {
                check_sensor();
    }

    return 0;
}

Problema encontrado

Todo funciona como se esperaba, el LED se ilumina cuando agito mi mano frente al sensor y no se dispara sin movimiento El sensor establece el AL pin LOW durante aproximadamente 100 - 200 ms.

La cosa es que no quiero usar la señal durante 2 segundos después de que se haya detectado el movimiento. Así lo implementé una lógica de temporizador y bandera que ignora la señal durante estos 2 segundos. El problema es que ahora el LED se enciende solo después de que el temporizador haya dejado de contar y comience a aceptar señales de movimiento

Configuración problemática

Para usar este temporizador y la lógica de la bandera, agregué 2 LED, uno que muestra que el temporizador está activo y otro que muestra cuando la señal está registrada:

volatile bool motion_detected;

void setup_default_values()
{
        DDRC |= (1 << PC5);
        DDRC |= (1 << PC4);
        DDRC |= (1 << PC3);
        DDRC &= ~(1 << PC0);

        PORTC |= (1 << PC0);

        TCCR1B |= (1 << CS12); // Timer 1B set up to use a prescaler of 256
        TCNT1 = 0; // Timer value set to 0

        motion_detected = false;
}

Luego, hago una nueva lógica a la función check_sensor :

void check_sensor()
{
        if (PINC & (1 << PC0)) {
                PORTC &= ~(1 << PC5);
        }else{
                PORTC |= (1 << PC5);

                if (!motion_detected) {
                        PORTC |= (1 << PC3);
                        _delay_ms(50);
                        PORTC &= ~(1 << PC3);

                        PORTC |= (1 << PC4);
                        TCNT1 = 0;        
                        motion_detected = true;
                }
        }
}

Cuando se detecta movimiento la primera vez, esto es lo que sucede:

  • el LED que indica la señal de PIR está encendido
  • LED que indica la aceptación de la señal, parpadeó una vez
  • el LED que indica que el temporizador está activo está encendido
  • El temporizador se reinicia y se marca un indicador que indica que se detectó movimiento

Luego hay una nueva función que maneja la cuenta atrás:

#define F_CPU 1000000UL

/*
 * Timer increments per second
 *
 * This value represents how many increments the timer will do to the TCNT1 register
 * per second. 
 *
 * To produce this value you divide the clock frequency in hz with the prescaler amount.
 * For example: 
 * 1000000 / 256 = 3906
 */

#define TMR_INC_PER_SEC 3906

void check_timer()
{
        if (!motion_detected) return;

        if (TCNT1 >= TMR_INC_PER_SEC * 3) {
                PORTC &= ~(1 << PC4);
                motion_detected = false;
        }
}

int main()
{
        setup_default_values();
        blink(4);

    for (;;) {
                check_timer();
                check_sensor();
    }

    return 0;
}

Esta función debe ignorarse a menos que se detecte un movimiento. Cuando cuenta regresiva tiene se ha completado el temporizador que indica que el LED está apagado y se restablece el indicador de movimiento que indica que una nueva señal puede ser aceptada.

Cosas que he probado

Software rebote

He intentado agregar la funcionalidad software debounce donde el movimiento solo se acepta si PC0 es LOW para Una cantidad definida de ciclos. Esto no cambió el comportamiento defectuoso.

Pulse el botón en lugar de PIR

He intentado quitar el PIR y agregar un botón que está LOW al presionar hacia abajo. Al usar el botón pulsador el circuito y la lógica funcionan como se esperaba.

Esquemas

Aquí están los esquemas para la fuente de alimentación. El circuito está conectado a una fuente de alimentación de CC estabilizada donde el riel de + 5V está alrededor de + 6.5V (no sé cómo editar el texto de un componente en gschem). VCC es lo que conecto a mi microcontrolador y sensor PIR, como verá en el segundo esquema.

Aquíestánlosesquemasdelmicrocontrolador,losLEDyelsensorPIR.Algunospinesnosemuestranenlosesquemas:RESETpinestáconectadoamiprogramador,lomismoconMOSI,MISOySCK.

    
pregunta rzetterberg

1 respuesta

3

El voltaje típico de deserción del 7805 es de 2.0V pero solo tiene una entrada de 6.5V por lo que el regulador no puede funcionar correctamente. Esto podría significar que cualquier pequeño pico de corriente en la demanda en el lado de carga del regulador, por ejemplo, cuando se encienden los LED, provocará fluctuaciones de voltaje, a pesar del condensador de 10uF, y los PIR son muy sensibles a las fluctuaciones de voltaje.

Recomiendo aumentar la entrada al 7805 a al menos 7.0V y probablemente a 8.0V para permitir variaciones en el voltaje de desconexión (2.0V aparece como típico, no máximo), y agregar un filtro RC al suministro al circuito PIR. Sin embargo, necesitará dimensionar la R con cuidado para evitar reducir el suministro del circuito PIR a menos del mínimo especificado (tal vez un inductor sería más efectivo y menos pérdidas). Otra opción sería usar dos 7805, uno para el micro y otro para el circuito PIR, con 0V común, lo que evitaría que el ruido del lado micro entrara tanto en el circuito PIR.

    
respondido por el Martin

Lea otras preguntas en las etiquetas