Determine RPM of DC Motor using Encoder

Hello,

I have created a cylic loading machine with a Pololu 12V DC motor (Pololu - 30:1 Metal Gearmotor 37Dx68L mm 12V with 64 CPR Encoder (Spur Pinion)) and am using an Adafruit Motor Shield V2.3 to control the motor.

My goal is to use the encoder attached to the DC motor to eventually read the RPM of the shaft.

I have the encoder configured in an X1 with a "falling" interupt (and can easily change to X2 configuration with a "change" interupt).

I am able to determine the number of pulses the encoder outputs, but am having trouble converting that to an accurate RPM.

Attached are several things:

  1. The code I am using which is a varient from this forum post (Getting RPM of a 12 V dc motor w/ its quadrature encoder - Sensors - Arduino Forum).
  2. A graph which shows MotorSpeed vs. Pulses. I determined that this relationship was not linear (something I did not know going in)

Does anybody have experience with this use of an encoder?

Thank you.

-pmk

OnlineRPM_Reader.ino (827 Bytes)

Considering that the motor slows down a bit between pulses, your graph appears perfect. The closer the pulses are to each other, the less time to slow down.

Paul

Paul,

When I count the RPM of the motor shaft at a Motor Speed of 20 I get 37 RPM. This is quite a bit higher than the serial.print of 28. Any idea why this is the case?

-pmk

This code is extracted from a program I use to control a small DC motor. I have an optical sensor that produces one pulse per revolution. It is not complete but it should give the idea. It simply measures the time between pulses.

volatile unsigned long isrMicros;
unsigned long latestIsrMicros;
unsigned long previousIsrMicros;
volatile boolean newISR = false;


void loop() {
   if (newISR == true) {
     previousIsrMicros = latestIsrMicros; // save the old value
     noInterrupts(); // pause interrupts while we get the new value
        latestIsrMicros = isrMicros;
        newISR = false;
     interrupts();
     microsThisRev = latestIsrMicros - previousIsrMicos;
}

void myISR() {
   isrMicros = micros();
   newISR = true;
}

...R