Computing RPM

I’m using the Pololu 150:1 Metal Gearmotor 37Dx73L mm 24V with 64 CPR Encoder (Helical Pinion) along with the Motoron M2S18v18 Dual High-Power Motor Controller Shield for Arduino (Connectors Soldered). To estimate the motor’s RPM, I wrote some Arduino code based on encoder readings. However, the RPM calculated by the code seems significantly off compared to my manual count. For example, when I set the motor speed to 800, my own count gives me approximately 72 RPM, but the Arduino without Labview reports around 18 RPM. If I use Labview and Visa series communication, the computed RMP from Arduino becomes 168 RPM. According to the website, the no-load RPM is 68. Could anyone help me identify if there’s an issue with the way I’m calculating RPM? I’d appreciate any suggestions or corrections. Here’s the code I’m using for RPM calculation

#include <Wire.h>
#include <Motoron.h>
#include <Encoder.h>

MotoronI2C mc;
Encoder myEnc(2, 3); // yellow = 2, white = 3

const long counts_per_rev = 38400;//64*4*150

long lastCount = 0;
unsigned long lastTime = 0;

void setup() {
  Wire.begin();
  mc.reinitialize();
  mc.clearResetFlag();
  Serial.begin(9600);
}

void loop() {
  // Read speed from LabVIEW
  if (Serial.available()) {
    int speed = Serial.parseInt(); // Expect -800 to 800
    mc.setSpeed(1, speed);
  }

   // Read encoder counts
  long currentCount = myEnc.read();
  float revolutions = (float)currentCount / counts_per_rev;
  
  // Calculate RPM every 100ms for smoother plot
  if (millis() - lastTime >= 100) {
    long diff = currentCount - lastCount;
    float revs = (float)diff / counts_per_rev; // revs in 0.1s
    float rpm = revs * 60.0 * 10; // convert to RPM (10 times because 0.1s interval)

    // Print for Serial Plotter (comma separated)
    Serial.print(revs);
    Serial.print(",");
    Serial.println(rpm);

    lastCount = currentCount;
    lastTime = millis();
  }

  //delay(20);
}

Hello, David.

I moved your post to the motors support category since you are not using a servo.

Your counts_per_rev value should be 9600. The encoder’s 64 CPR resolution given on the product page is for counting the rising and falling edges on both channels, so the resolution of the gearmotor output shaft is calculated with 64×150 and not 64×4×150.

- Patrick

Hello Patrick,

That clears things up perfectly. The Arduino reports approximately 18 RPM, and when multiplied by 4, it matches my manual count of 72 RPM exactly.

Best regards,

David