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--;
}
}