Mida las rpm de un motor de CC usando dos temporizadores/contadores y un sensor IR (atmega 328p)

Estoy tratando de medir la velocidad de un motor DC. Tengo un sensor de velocidad IR conectado al pin T1 (PD5) de un ATMega 328p. Mi idea es que cuando hay un cambio de BAJO a ALTO, se incrementa un contador y para esto estoy usando TIMER2 para crear una interrupción de 1 segundo y TIMER1 para contar los pulsos.

El primer problema es que el TCNT1 me está dando valores aleatorios aunque pase solo una vez en el sensor (cuenta de 0 a 200).

El segundo problema es que está contando ambos cambios de BAJO a ALTO y de ALTO a BAJO.

Mi sensor es www.botnroll.com/pt/sensores/957-motor-speed-sensor-module.html

Aquí está mi código actual:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned int overflow;
volatile unsigned int timer_counts = 0;

void conf_timer2()
{
    //prescaler = 256
    TCCR2B |= (1 << CS22)|(1 << CS21);

    TCNT2 = 0;
    // overflow interrupt
    TIMSK2 |= (1 << TOIE2);

    overflow = 0;
}

void config_timer1()
{
    TCCR1B |= (1<<CS10) | (1<<CS11) | (1<<CS12);    //rising edge
    TIMSK1 |= (1<<TOIE1);   //enable overflow interrupt

    DDRD &= ~(1 << DDB5);
    //PORTD |= (1 << PORTD5);
}

ISR(TIMER2_OVF_vect)
{
    overflow++;
}

ISR(TIMER1_OVF_vect)
{
    //overflow1++; 
    //no need since it will never reach 65536 in 1 sec 
}

int main()
{
    sei();
    config_timer1();
    conf_timer2();
    char aux2[10];
    char aux1[10];

    unsigned int rpm;

    while(1)
    {       
    if(overflow >= 152) // for 1 sec
    {
        if(TCNT2 > 149) //for 1 sec 
        {
            timer_counts = TCNT1;
            rpm = timer_counts * 60;

            itoa(rpm, aux2, 10);
            itoa(timer_counts, aux1, 10);
            USART_putstring("Rot. per sec: "); //print values
            USART_putstring(aux1);
            USART_putstring("\n");
            USART_putstring("Rot. per min = ");
            USART_putstring(aux2);
            USART_putstring("\n");

            TCNT1 = 0;
            overflow = 0;
            rpm = 0;
        }
    }
}
return 0;

}

¡Cualquier ayuda es valiosa!

@TonyM Estoy usando el sensor: botnroll.com/pt/sensores/… Cuando tenga la oportunidad, miraré los bordes con un osciloscopio
estaba usando 5v para alimentar el sensor. ¡simplemente lo cambié a 3.3 y usé la resistencia de extracción y está funcionando! ¡muchas gracias!

Respuestas (1)

Dejando a un lado la lista de software por el momento, me hace preguntarme si su circuito de sensor óptico está produciendo muchos flancos de conmutación rápida cuando el haz del fototransistor está roto o hecho. ¿Puedes mirar de cerca esos bordes en un osciloscopio?

Mirando el sensor, no hay un esquema dado, pero dice que usa un comparador dual LM393 y puedo ver 6 resistencias. Eso significa que podrían tener un disparador Schmitt en la salida del fototransistor para evitar la conmutación múltiple de salida con interrupciones lentas del haz, cuando la salida del fototransistor se activa o desactiva lentamente.

Además, LM393 es una parte de colector abierto, pero es casi un hecho que hay una resistencia pull-up de salida a bordo allí. Casi... pero prueba a poner un pull-up 4K7 entre la salida de la placa y el riel de suministro (3V3 me imagino), a ver si mejora.