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

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!

• @TonyM Im using the sensor: botnroll.com/pt/sensores/… When i have the oportunity ill look at the edges with a oscilloscope – José Salgado May 24 '17 at 22:02
• i was using 5v to power the sensor. just changed it to 3.3 and used the pull resistor and its working! thanks a lot! – José Salgado May 24 '17 at 23:04

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