# velocity using encoder

i am using rotary encoder having 5000 pulses per rotation with 600 rpm otor .

can i calculate the velocity using rotary encoder?
and as I am using interrupt and timer stops in ISR , will the calculated velocity be accurate .

If you know how many pulses have happened in a given time frame, and you know the circumference (or radius) of the item you want to measure, then yes you can calculate the velocity.

Velocity is distance divided by time. (By the way, speed is abs(velocity) for those pedants out there )

Distance is pulses / pulses per rotation * distance per rotation.

as I am using interrupt and timer stops in ISR , will the calculated velocity be accurate .

Accurate, yes. Precise? no.

How accurate do you need? If you are counting pulses, and you never miss a pulse (so they happen slower than the ISR can handle), and you count them over an accurate time period, then yes, it will be accurate.

If you miss a pulse because they are coming in too fast, or your time period is not accurate, then you will lose accuracy.

but even if I do not miss any count , timer stop will executing the ISR . therefore total time calculated will be less than actual time time .
so when I use formula velocity = dist. / time , my calculated velocity will not be right.

"timer stop will executing the ISR"

Google translate has failed you there, that makes no sense and I don't understand what you're trying to say.

What time frame are you counting pulses over? How are you measuring that time?

At 600 rpm you get 50,000 pulses per second. Or 20 microseconds between pulses. Are you sure your ISR can complete in that time?

BTW velocity is the rate of change of position. Distance divided by time gives you average speed. (from us pedants out here )

that's my concern . will arduino mega will be able to calculate accurate ticks as well as velocity or i should use another board ( like beaglebone )

Hi varangupta

I don't think you've answered majenko's question

``````What time frame are you counting pulses over?  How are you measuring that time?
``````

If the ISR only needs to increment a counter, which is then read every 1 second (for example) to calculate average speed / velocity in that second, then 50,000 pulses per second sounds achievable.

All the best

Ray

DavidOConnor:
BTW velocity is the rate of change of position. Distance divided by time gives you average speed. (from us pedants out here )

My point there was that velocity is signed, speed is unsigned. A velocity of -5m/s is a speed of 5m/s, going backwards

You might want to pre-scale the pulses to give your ISR more time. Maybe a simple binary counter would do the trick - it could give you prescaling of /2, /4, /8, /16 etc - just remember to multiply your count by the right amount

Can you use an encoder with fewer pulses per rev.?

this is my code

``````#include <digitalWriteFast.h>  // library for high performance reads and writes by jrraines
// see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267553811/0

// It turns out that the regular digitalRead() calls are too slow and bring the arduino down when
// I use them in the interrupt routines while the motor runs at full speed creating more than
// 40000 encoder ticks per second per motor.
// encoder gives 5000 pulses per revolution

#define c_EncoderInterrupt 3
#define c_EncoderPinA 20
#define c_EncoderPinB 21
#define EncoderIsReversed
volatile bool _EncoderBSet;
volatile float x2 = 0;
volatile boolean interrupt = 0;

unsigned long t1=0,t2=0;
float x1=0;
void setup()
{
Serial.begin(115200);

pinMode(c_EncoderPinA, INPUT);  	// sets pin A as input
digitalWrite(c_EncoderPinA, LOW);  // turn on pullup resistors
pinMode(c_EncoderPinB, INPUT);  	// sets pin B as input
digitalWrite(c_EncoderPinB, LOW);  // turn on pullup resistors
attachInterrupt(c_EncoderInterrupt, HandleLeftMotorInterruptA, RISING);

}

float rpm = 0 ;
void loop()
{

if(x2 - x1 == 50 )
{

rpm = ((x2-x1)/(t2-t1))*12000; // 12000 (= 60*1000000/5000) is conversion factor

x1 = x2;
t1=t2;

}
t2 = micros();

//Serial.println(rpm);

/*
....rest of the code
*/

}

// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA()
{
// Test transition; since the interrupt will only fire on 'rising' we don't need to read pin A

x2 -= _EncoderBSet ? -1 : +1;

}
``````

DavidOConnor:
Can you use an encoder with fewer pulses per rev.?

I do not have any other encoder .

I will consider using a binary counter

majenko:
Google translate has failed you there, that makes no sense and I don’t understand what you’re trying to say.

my main question is , will the time calculated by micros will be correct as timer stops “while” executing the ISR.

my main question is , will the time calculated by micros will be correct as timer stops "while" executing the ISR.

You need to make sure that your interrupt doesn't take long. That's how you ensure that you don't interfere with the timer that micros() reports.

first of all Thanks to all,

I think if i calculate velocity after every 32 or 64 pulses using binary counter the error in velocity calculation will be less and i will get more time for the rest of the code .

can you please name a good binary counter IC.