Electrical – Measure rpm of a DC motor using two timers/counter and IR sensor (atmega 328p)

avrcountermotorrpmtimer

I'm trying to measure the speed of a DC motor. I have an IR speed sensor connected to the T1 pin(PD5) of an ATMega 328p. My idea is when there is a change from LOW to HIGH, a counter is incremented and for this I'm using TIMER2 to create a 1 second interrupt and TIMER1 to count the pulses.

First problem is that the TCNT1 is giving me random values even if I pass only one time in the sensor (counts from 0 to 200).

Second problem is that its counting both changes from LOW to HIGH and HIGH to LOW.

My sensor is www.botnroll.com/pt/sensores/957-motor-speed-sensor-module.html

Here is my current code:

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

}

Any1 help is valuable!

Best Answer

Putting the software listing aside for the moment, it makes me wonder if your opto-sensor circuit is producing lots of fast-switching edges as it the photo-transistor beam is broken or made. Can you look closely at those edges on an oscilloscope.

Looking at the sensor, there's no schematic given for it but it says it uses a LM393 dual comparator and I can see 6 resistors. That means they could have a Schmitt trigger on the photo-transistor output to prevent the output multi-switching with slow beam interruptions, when the photo-transistor output is going on or off slowly.

Also, LM393 is an open-collector part but it's almost a given that there's an output pull-up resistor on board there. Almost...but do try putting a 4K7 pull-up between the board output and the supply rail (3V3 I imagine), see if it improves.