Measure Speed of DC motor using Encoder

Hi,

I am trying to read the speed of a dc motor with encoder using arduino uno board. The motor encoder gives 20 pulses per rotation. I used one of the codes posted on the forum and it seemed to work for other people, but the code has been giving the speed of zero even when the motor is running. Any suggestion what might go wrong? Can you take a look and help me out? I have been stuck at this for a while now

http://files.andymark.com/PDFs/CIMcoder+Spec+Sheet+7-06-16.pdf - spec sheet for the encoder
http://files.andymark.com/CIM-motor-curve.pdf - for motor

here is the code:

#define encoder0PinA 2
#define encoder0PinB 3

volatile long encoder0Pos=0;
long newposition;
long oldposition = 0;
unsigned long newtime;
unsigned long oldtime = 0;
long vel;

void setup()
{
pinMode(encoder0PinA, INPUT);
//digitalWrite(encoder0PinA, HIGH); // turn on pullup resistor
pinMode(encoder0PinB, INPUT);
//digitalWrite(encoder0PinB, HIGH); // turn on pullup resistor
attachInterrupt(0, doEncoder, RISING); // encoDER ON PIN 2
Serial.begin (9600);

}

void loop()
{
newposition = encoder0Pos;
newtime = millis();
vel = (newposition-oldposition)*1000/(newtime-oldtime);
Serial.print ("speed = ");
Serial.println (vel);
oldposition = newposition;
oldtime = newtime;
delay(250);
}

void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
encoder0Pos++;
} else {
encoder0Pos--;
}
}

Thanks so much!

You seem to have disabled internal pullups. The modern way to enable them is

  pinMode(encoder0PinA, INPUT_PULLUP);
  pinMode(encoder0PinB, INPUT_PULLUP);

wire the common terminal to ground.

Hi,

Thank you for your reply. I have tried what you suggested. But the code still did not seem to work. The speed first came out as 500, but then became zero again. Do you know what might cause this problem?

You should disable interrupts while you read encoder0pos - like this

void loop()
{
noInterrupts();
   newposition = encoder0Pos;
interrupts();
newtime = millis();
// etc

Otherwise the value might change while it is being read.

And I suspect it might make more sense to use micros() for timing.

How many pulses per second will you get at maximum speed?

...R

Try using stronger external pullup resistors (4.7K) to 5v on the encoder output lines.

Hi,
Welcome to the forum.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Can you please post link/data of your DC motor and encoder?

Thanks.. Tom... :slight_smile: