Jump to content

DC Motor with Encoder: Difference between revisions

From cognifront
CogWikiEditor (talk | contribs)
CogWikiEditor (talk | contribs)
 
(19 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{DISPLAYTITLE:Arduino Motor RPM Measurement Using LM393 Encoder}}
===Arduino Motor RPM Measurement Using LM393 Encoder===


{| class="wikitable" style="float:right; margin-left:20px; width:300px;"
{| class="wikitable" style="float:right; margin-left:20px; width:300px;"
Line 56: Line 56:
| Ground
| Ground
|-
|-
| L293D
| Motor
| EN1
| EN1
| D5
| D5
| Motor PWM
| Motor PWM
|-
|-
| L293D
| Motor
| IN1
| IN1
| D7
| D7
| Motor direction
| Motor direction
|-
|-
| L293D
| Motor
| IN2
| IN2
| D8
| D8
| Motor direction
| Motor direction
|-
| Motor
| 5V
| External 5 V
| Motor Positive
|-
| Motor
| GND
| Arduino GND
| Motor GND
|-
| External GND
| GND
| Arduino GND
| Common Groudings
|}
|}


=== Motor direction ===
=== Motor direction ===
 
IN1 = HIGH <br>
<syntaxhighlight lang="cpp">
IN1 = HIGH
IN2 = LOW
IN2 = LOW
</syntaxhighlight>


=== Encoder ===
=== Encoder ===
Line 84: Line 96:


20 slots ➡️ 20 pulses ➡️ 1 output-shaft revolution
20 slots ➡️ 20 pulses ➡️ 1 output-shaft revolution
[[File:Encoder-dc-motor-arduino.jpg|thumb|center|700px|Arduino motor speed measurement setup using an L293D driver and LM393 encoder]]


== Working ==
== Working ==
Line 101: Line 115:


The RPM calculation is:
The RPM calculation is:
 
<center>
<math>
<code>RPM = (Pulses × 60) / 20</code>
RPM = \frac{Pulses \times 60}{20}
</center>
</math>
 
For example:
 
<math>
100\ pulses \rightarrow \frac{100 \times 60}{20} = 300\ RPM
</math>


== Arduino Code ==
== Arduino Code ==


<syntaxhighlight lang="cpp">
<pre>
/*
/*
   Encoder disc:
   Encoder disc:
       20 slots
       20 slots
   Encoder location:
   Encoder location:
       Gearbox OUTPUT shaft
       Gearbox OUTPUT shaft
   Therefore:
   Therefore:
       20 pulses = 1 output-shaft revolution
       20 pulses = 1 output-shaft revolution
   Encoder:
   Encoder:
       LM393 DO -> Arduino D2
       LM393 DO -> Arduino D2
   Motor driver:
   Motor driver:
       L293D
       L293D
Line 150: Line 153:
int motorPWM = 150;
int motorPWM = 150;


// Encoder interrupt
// ENCODER INTERRUPT
void encoderISR()
void encoderISR()
{
{
   unsigned long currentTime = micros();
   unsigned long currentTime = micros();
   if ((currentTime - lastPulseTime) >= MIN_PULSE_INTERVAL_US)
   if ((currentTime - lastPulseTime) >= MIN_PULSE_INTERVAL_US)
   {
   {
Line 165: Line 167:
{
{
   Serial.begin(115200);
   Serial.begin(115200);
   pinMode(ENCODER_PIN, INPUT);
   pinMode(ENCODER_PIN, INPUT);
   pinMode(EN1, OUTPUT);
   pinMode(EN1, OUTPUT);
   pinMode(IN1, OUTPUT);
   pinMode(IN1, OUTPUT);
   pinMode(IN2, OUTPUT);
   pinMode(IN2, OUTPUT);
  // Motor direction
   digitalWrite(IN1, HIGH);
   digitalWrite(IN1, HIGH);
   digitalWrite(IN2, LOW);
   digitalWrite(IN2, LOW);
  // Motor speed
   analogWrite(EN1, motorPWM);
   analogWrite(EN1, motorPWM);
  // Encoder interrupt
   attachInterrupt(
   attachInterrupt(
     digitalPinToInterrupt(ENCODER_PIN),
     digitalPinToInterrupt(ENCODER_PIN),
Line 192: Line 186:
{
{
   static unsigned long lastMeasurement = 0;
   static unsigned long lastMeasurement = 0;
   unsigned long currentTime = millis();
   unsigned long currentTime = millis();
   if (currentTime - lastMeasurement >= SAMPLE_TIME_MS)
   if (currentTime - lastMeasurement >= SAMPLE_TIME_MS)
   {
   {
     unsigned long pulses;
     unsigned long pulses;
     noInterrupts();
     noInterrupts();
     pulses = pulseCount;
     pulses = pulseCount;
Line 207: Line 198:
       (pulses * 60.0) /
       (pulses * 60.0) /
       (SLOTS_PER_REV * (SAMPLE_TIME_MS / 1000.0));
       (SLOTS_PER_REV * (SAMPLE_TIME_MS / 1000.0));
 
     Serial.print ("Pulses ");
     Serial.print("Pulses ");
     Serial.print (pulses);
     Serial.print(pulses);
     Serial.print (",RPM ");
 
     Serial.println (rpm);
     Serial.print(",RPM ");
     Serial.println(rpm);
 
     lastMeasurement = currentTime;
     lastMeasurement = currentTime;
   }
   }
}
}
</syntaxhighlight>
</pre>


== Observation ==
== Observation ==


The Serial Monitor is set to '''115200 baud'''.
The Serial Monitor is set to '''115200 baud'''.
 
And observe the speed of the motor
Example observations:
 
{| class="wikitable"
! Pulse Count
! Calculated RPM
|-
| 80
| 240 RPM
|-
| 82
| 246 RPM
|-
| 81
| 243 RPM
|-
| 83
| 249 RPM
|}
 
Example Serial Monitor output:
 
<syntaxhighlight>
RPM
Pulses 80,RPM 240.00
Pulses 82,RPM 246.00
Pulses 81,RPM 243.00
Pulses 83,RPM 249.00
</syntaxhighlight>


'''Result:''' The Arduino successfully controls the geared motor and measures the '''gearbox output-shaft RPM''' using the 20-slot LM393 encoder.
'''Result:''' The Arduino successfully controls the geared motor and measures the '''gearbox output-shaft RPM''' using the 20-slot LM393 encoder.

Latest revision as of 16:24, 3 September 2026

Arduino Motor RPM Measurement Using LM393 Encoder

Motor RPM Measurement
Controller Arduino
Motor Driver L293D
Encoder LM393
Encoder Disc 20 slots
Encoder Position Gearbox output shaft
Output RPM

Arduino Motor RPM Measurement is a simple motor-control and speed-measurement setup using an Arduino, L293D motor driver and LM393 optical encoder.

The 20-slot encoder disc is mounted on the gearbox output shaft. Therefore:

20 pulses = 1 output-shaft revolution

The Arduino controls the motor and counts encoder pulses for one second to calculate the output-shaft RPM.

Connections

Device Pin Arduino Function
LM393 DO D2 Encoder pulse
LM393 VCC 5V Power
LM393 GND GND Ground
Motor EN1 D5 Motor PWM
Motor IN1 D7 Motor direction
Motor IN2 D8 Motor direction
Motor 5V External 5 V Motor Positive
Motor GND Arduino GND Motor GND
External GND GND Arduino GND Common Groudings

Motor direction

IN1 = HIGH
IN2 = LOW

Encoder

The LM393 produces a digital pulse whenever a slot on the encoder disc passes the sensor.

20 slots ➡️ 20 pulses ➡️ 1 output-shaft revolution

Arduino motor speed measurement setup using an L293D driver and LM393 encoder

Working

The motor is driven through the L293D. The encoder disc rotates together with the gearbox output shaft.

The LM393 detects the slots and produces digital pulses. These pulses are connected to Arduino D2.

D2 uses an external interrupt to count the pulses.

Every 1 second, the Arduino:

  1. Reads the number of encoder pulses.
  2. Resets the pulse counter.
  3. Converts the pulse count into RPM.
  4. Displays the result on the Serial Monitor.

The RPM calculation is:

RPM = (Pulses × 60) / 20

Arduino Code

/*
  Encoder disc:
      20 slots
  Encoder location:
      Gearbox OUTPUT shaft
  Therefore:
      20 pulses = 1 output-shaft revolution
  Encoder:
      LM393 DO -> Arduino D2
  Motor driver:
      L293D
      EN1 -> D5
      IN1 -> D7
      IN2 -> D8
*/

#define ENCODER_PIN 2

#define EN1 5
#define IN1 7
#define IN2 8

#define SLOTS_PER_REV 20
#define MIN_PULSE_INTERVAL_US 2000
#define SAMPLE_TIME_MS 1000

volatile unsigned long pulseCount = 0;
volatile unsigned long lastPulseTime = 0;

int motorPWM = 150;

// ENCODER INTERRUPT
void encoderISR()
{
  unsigned long currentTime = micros();
  if ((currentTime - lastPulseTime) >= MIN_PULSE_INTERVAL_US)
  {
    pulseCount++;
    lastPulseTime = currentTime;
  }
}

void setup()
{
  Serial.begin(115200);
  pinMode(ENCODER_PIN, INPUT);
  pinMode(EN1, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(EN1, motorPWM);
  attachInterrupt(
    digitalPinToInterrupt(ENCODER_PIN),
    encoderISR,
    RISING
  );

  Serial.println("RPM");
}

void loop()
{
  static unsigned long lastMeasurement = 0;
  unsigned long currentTime = millis();
  if (currentTime - lastMeasurement >= SAMPLE_TIME_MS)
  {
    unsigned long pulses;
    noInterrupts();
    pulses = pulseCount;
    pulseCount = 0;
    interrupts();

    float rpm =
      (pulses * 60.0) /
      (SLOTS_PER_REV * (SAMPLE_TIME_MS / 1000.0));
    Serial.print ("Pulses ");
    Serial.print (pulses);
    Serial.print (",RPM ");
    Serial.println (rpm);
    lastMeasurement = currentTime;
  }
}

Observation

The Serial Monitor is set to 115200 baud. And observe the speed of the motor

Result: The Arduino successfully controls the geared motor and measures the gearbox output-shaft RPM using the 20-slot LM393 encoder.