Determining distance traveled using encoder issue

Using an optical encoder attached to a DC motor I am trying to get distanced traveled by a robotic unit. The distance measurement should be started from 0 pulses from the encoder to whatever speed the motor is running till it comes back to a full stop or 0 pulses again. I am not sure my calculation are correct as the results given seem off.
The motor is 32 rpm/min with a 1:34 reduction ratio. Encoder count for one complete rotation of the motor shaft is 360 cpr. Wheel diameter is .072 meters.
This is the results of running at full speed on a motor.

Pulses: 31039
Speed: 152.00 RPM
Angular Velocity: 152.00 rad per second 912.00 deg per second
Linear Velocity: 1.15 meters per second
Distance: 0.90 meters

Any help would be greatly appreciated.

// Motor encoder output pulses per 12240 revolution, encoder is 360 cpr, motor reduction ratio 1:34
#define ENC_COUNT_REV 12240
 
// Encoder output to Arduino Interrupt pin. Tracks the pulse count.
#define ENC_IN_RIGHT_A 2
 
// Other encoder output to Arduino to keep track of wheel direction
// Tracks the direction of rotation.
#define ENC_IN_RIGHT_B 4
 
// True = Forward; False = Reverse
boolean Direction_right = true;
 
// Keep track of the number of right wheel pulses
volatile long right_wheel_pulse_count = 0;
 
// One-second interval for measurements
int interval = 1000;
  
// Counters for milliseconds during interval
long previousMillis = 0;
long currentMillis = 0;
 
// Variable for RPM measuerment
float rpm_right = 0;
 
// Variable for angular, linear velocity, distance measurement
float ang_velocity_right = 0;
float ang_velocity_right_deg = 0;
float linear_velocity_right_msec = 0; 
float distance_meters =0;
const float wheel_dia_meters = .072;
const float rpm_to_radians = 0.10471975512;
const float rad_to_deg = 57.29578;
 
void setup() {
 
  // Open the serial port at 9600 bps
  Serial.begin(9600); 
 
  // Set pin states of the encoder
  pinMode(ENC_IN_RIGHT_A , INPUT_PULLUP);
  pinMode(ENC_IN_RIGHT_B , INPUT);
 
  // Every time the pin goes high, this is a pulse
  attachInterrupt(digitalPinToInterrupt(ENC_IN_RIGHT_A), right_wheel_pulse, RISING);
   
}
 
void loop() {
 
  // Record the time
  currentMillis = millis();
 
  // If one second has passed, print the number of pulses
  if (currentMillis - previousMillis > interval) {
 
    previousMillis = currentMillis;
 
    // Calculate revolutions per minute
    rpm_right = (float)(right_wheel_pulse_count * 60 / ENC_COUNT_REV);
    ang_velocity_right = rpm_right * rpm_to_radians;   
    ang_velocity_right_deg = ang_velocity_right * rad_to_deg;
    linear_velocity_right_msec = wheel_dia_meters * ang_velocity_right;
    distance_meters = (2*3.141*wheel_dia_meters)*(right_wheel_pulse_count/12240);
    Serial.print(" Pulses: ");
    Serial.println(right_wheel_pulse_count);
    Serial.print(" Speed: ");
    Serial.print(rpm_right);
    Serial.println(" RPM");
    Serial.print(" Angular Velocity: ");
    Serial.print(rpm_right);
    Serial.print(" rad per second");
    Serial.print("\t");
    Serial.print(ang_velocity_right_deg);
    Serial.println(" deg per second");
    Serial.print(" Linear Velocity: ");
    Serial.print(linear_velocity_right_msec);
    Serial.print(" meters per second");
    Serial.println();
    Serial.print(" Distance: ");
    Serial.print(distance_meters);
    Serial.print(" meters");
    Serial.println();
 
    right_wheel_pulse_count = 0;
   
  }
}
 
// Increment the number of pulses by 1
void right_wheel_pulse() {
   
  // Read the value for the encoder for the right wheel
  int val = digitalRead(ENC_IN_RIGHT_B);
  if(val == LOW) {
    Direction_right = false; // Reverse
  }
  else {
    Direction_right = true; // Forward
  }
   
  if (Direction_right) {
    right_wheel_pulse_count++;
  }
  else {
    right_wheel_pulse_count--;
    
  }
}

RPM usally means "rotation per minute" and not the "radians per second".

Next - 152 rad per second is not a 912.00 deg per second...

Addition -you need to repeat the school geometry course, distance of the one rotation of the wheel is not a

but only
Pi * wheel_dia_meters

What is "rpm to radians" means? RPM is a velosity and radians is a distance, it can't be converted each other.

May be you mean "rotations to radians" - in this case you have a arithmetic mistake in the constant.

      360 pulse/motor-rotation
       34 gear-ratio
    12240 pulse/wheel-rotation

   0.0720 wheel-diameter (m)
   0.2262 wheel-circumference (m)
 0.000018 dist/pulse (m)

    32.00 RPM motor
     0.94 RPM wheel

at robotics, the kids calibrated the motor in inches/encoder-tic and would call functions that moved the robot a specified # of inches

1 Like

It seems odd that one output of the encoder would need a pull-up and the other wouldn't.

Thanks for the suggestions. Much appreciated.

Addition -you need to repeat the school geometry course

Yes, I probably do. It's been a while since I did this stuff. Like almost 50 years ago.

it usually takes me a while. "units analysis" helps

Right. If the units don't work, the rest in nonsense. We called it Factor-Label in school.

Besides the egregious math errors, merely counting rotations doesn't account for the robot's wheels slipping on the surface.

some robotics use Mecanum wheels that allow the robot to move sideways. they calibrated by running the robot some # of encoder tics and measuring how far it traveled in inches. then calculated the conversion from inch to tics

1 Like

It probably doesn't need to be that accurate in accounting for slippage, I guess. I am trying to work through the math again on this. Thanks.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.