DC Motor with Encoder: Difference between revisions
Created page with "# Arduino L293D Motor Speed Measurement Using LM393 Encoder ## Overview This practical measures the **RPM (revolutions per minute)** of a geared DC motor using an **LM393 optical encoder module** and an **Arduino**. The encoder disc is mounted on the **gearbox output shaft** and contains **20 slots**. > **20 encoder pulses = 1 complete output-shaft revolution** The motor is driven using an **L293D motor driver**, while the encoder pulse signal is connected to Arduin..." |
No edit summary |
||
| Line 1: | Line 1: | ||
```wiki | |||
{{DISPLAYTITLE:Arduino Motor Speed Measurement Using L293D and LM393 Encoder}} | |||
{| class="wikitable infobox" style="float:right; margin:0 0 1em 1em; width:300px;" | |||
! colspan="2" style="font-size:125%;" | Arduino Motor Speed Measurement | |||
|- | |||
! Controller | |||
| [[Arduino]] | |||
|- | |||
! Motor driver | |||
| L293D | |||
|- | |||
! Encoder | |||
| LM393 optical encoder | |||
|- | |||
! Encoder disc | |||
| 20 slots | |||
|- | |||
! Encoder position | |||
| Gearbox output shaft | |||
|- | |||
! Encoder output | |||
| Digital (DO) | |||
|- | |||
! Encoder input | |||
| Arduino D2 | |||
|- | |||
! Motor PWM | |||
| Arduino D5 | |||
|- | |||
! Motor direction | |||
| Arduino D7, D8 | |||
|- | |||
! Measurement period | |||
| 1 second | |||
|- | |||
! Output | |||
| RPM | |||
|} | |||
'''Arduino Motor Speed Measurement Using L293D and LM393 Encoder''' is an embedded motor-control system that controls a geared DC motor using an [[L293D]] motor driver and measures the rotational speed of the gearbox output shaft using an [[LM393]] optical encoder. | |||
The encoder disc is mounted on the | The encoder disc contains '''20 slots'''. Because the encoder is mounted on the gearbox output shaft, '''20 encoder pulses correspond to one complete output-shaft revolution'''. | ||
__TOC__ | |||
== Objective == | |||
* Control a geared DC motor using an L293D motor driver. | |||
* Measure the rotational speed of the gearbox output shaft. | |||
* Count encoder pulses using an Arduino external interrupt. | |||
* Calculate and display the speed in revolutions per minute (RPM). | |||
== Hardware == | |||
| Component | {| class="wikitable" | ||
| - | ! Component | ||
| Arduino | ! Quantity | ||
| Geared DC | |- | ||
| L293D | | Arduino | ||
| LM393 | | 1 | ||
| | |- | ||
| Jumper | | Geared DC motor | ||
| Motor | | 1 | ||
|- | |||
| L293D motor driver | |||
| 1 | |||
|- | |||
| LM393 optical encoder module | |||
| 1 | |||
|- | |||
| 20-slot encoder disc | |||
| 1 | |||
|- | |||
| Jumper wires | |||
| As required | |||
|- | |||
| Motor power supply | |||
| 1 | |||
|} | |||
== Pin connections == | |||
=== Encoder === | |||
{| class="wikitable" | |||
! LM393 | |||
! Arduino | |||
! Purpose | |||
|- | |||
| DO | |||
| D2 | |||
| Encoder pulse signal | |||
|- | |||
| VCC | |||
| 5V | |||
| Power | |||
|- | |||
| GND | |||
| GND | |||
| Ground | |||
|} | |||
=== L293D === | |||
{| class="wikitable" | |||
! L293D | |||
! Arduino | |||
! Purpose | |||
|- | |||
| EN1 | |||
| D5 | |||
| PWM speed control | |||
|- | |||
| IN1 | |||
| D7 | |||
| Motor direction | |||
|- | |||
| IN2 | |||
| D8 | |||
| Motor direction | |||
|} | |||
The motor direction used by the program is: | |||
<syntaxhighlight lang="cpp"> | |||
IN1 = HIGH | |||
IN2 = LOW | |||
</syntaxhighlight> | |||
The PWM signal applied to EN1 controls the motor speed. | |||
== System diagram == | |||
<syntaxhighlight> | |||
IN1 | ARDUINO | ||
IN2 = | ┌────────────────┐ | ||
│ │ | |||
D5 ────┼───────────────►│ EN1 | |||
D7 ────┼───────────────►│ IN1 | |||
D8 ────┼───────────────►│ IN2 | |||
│ │ | |||
D2 ◄───┼────────────────┤ LM393 DO | |||
│ │ | |||
└────────────────┘ | |||
│ | |||
│ PWM + Direction | |||
▼ | |||
┌───────────┐ | |||
│ L293D │ | |||
└─────┬─────┘ | |||
│ | |||
▼ | |||
┌───────────┐ | |||
│ DC MOTOR │ | |||
│ + GEARBOX │ | |||
└─────┬─────┘ | |||
│ | |||
▼ | |||
┌───────────┐ | |||
│ ENCODER │ | |||
│ 20 SLOTS │ | |||
└─────┬─────┘ | |||
│ | |||
│ 20 pulses / revolution | |||
▼ | |||
Arduino D2 | |||
</syntaxhighlight> | |||
== Working == | |||
The geared motor rotates the gearbox output shaft. The encoder disc is attached to this output shaft. | |||
As the disc rotates, its slots pass the LM393 optical sensor. The sensor generates digital pulses at its DO output. | |||
The Arduino receives these pulses on D2 using an external interrupt. | |||
The basic sequence is: | |||
- | <syntaxhighlight> | ||
Motor rotation | |||
↓ | |||
Gearbox output shaft | |||
↓ | |||
20-slot encoder disc | |||
↓ | |||
LM393 optical sensor | |||
↓ | |||
Digital pulses | |||
↓ | |||
Arduino D2 interrupt | |||
↓ | |||
Pulse counting | |||
↓ | |||
RPM calculation | |||
↓ | |||
Serial Monitor | |||
</syntaxhighlight> | |||
== Encoder resolution == | |||
The encoder disc | The encoder disc has: | ||
<math> | |||
20\ slots/revolution | |||
</math> | |||
Therefore: | Therefore: | ||
<math> | |||
1 revolution | 20\ pulses = 1\ revolution | ||
</math> | |||
Since the encoder is located on the gearbox output shaft, the calculated RPM represents the '''gearbox output-shaft speed'''. | |||
== RPM calculation == | |||
The program measures the number of encoder pulses received during a fixed time interval. | |||
The | The general equation is: | ||
<math> | |||
RPM = | RPM = | ||
\frac{Pulses \times 60} | \frac{Pulses \times 60} | ||
{Slots\ per\ revolution \times Measurement\ time\ (seconds)} | {Slots\ per\ revolution \times Measurement\ time\ (seconds)} | ||
</math> | |||
For this implementation: | |||
<math> | |||
Slots\ per\ revolution = 20 | |||
</math> | |||
and: | |||
<math> | |||
Measurement\ time = 1\ second | |||
</math> | |||
Therefore: | |||
<math> | |||
RPM = | RPM = | ||
\frac{Pulses \times 60}{20} | \frac{Pulses \times 60}{20} | ||
</math> | |||
=== Example === | |||
If the Arduino detects | If the Arduino detects 100 pulses during one second: | ||
<math> | |||
RPM = \frac{100 \times 60}{20} | RPM = | ||
\frac{100 \times 60}{20} | |||
</math> | |||
<math> | |||
RPM = 300 | RPM = 300 | ||
</math> | |||
Thus, 100 pulses per second correspond to an output-shaft speed of '''300 RPM'''. | |||
== Interrupt-based pulse counting == | |||
The encoder is connected to Arduino D2 and configured to generate an interrupt on a rising edge. | |||
<syntaxhighlight lang="cpp"> | |||
attachInterrupt( | attachInterrupt( | ||
digitalPinToInterrupt(ENCODER_PIN), | digitalPinToInterrupt(ENCODER_PIN), | ||
| Line 163: | Line 270: | ||
RISING | RISING | ||
); | ); | ||
</syntaxhighlight> | |||
When a rising edge is detected, the interrupt service routine is executed. | |||
<syntaxhighlight lang="cpp"> | |||
encoderISR() | void encoderISR() | ||
{ | |||
unsigned long currentTime = micros(); | |||
if ((currentTime - lastPulseTime) >= MIN_PULSE_INTERVAL_US) | |||
{ | |||
pulseCount++; | |||
pulseCount++; | lastPulseTime = currentTime; | ||
} | |||
} | |||
</syntaxhighlight> | |||
Each accepted pulse increments the variable <code>pulseCount</code>. | |||
== Pulse filtering == | |||
A minimum pulse interval is defined as: | |||
<syntaxhighlight lang="cpp"> | |||
#define MIN_PULSE_INTERVAL_US 2000 | #define MIN_PULSE_INTERVAL_US 2000 | ||
</syntaxhighlight> | |||
This corresponds to: | This corresponds to: | ||
<math> | |||
2000 | 2000\ \mu s = 2\ ms | ||
</math> | |||
If another pulse | If another pulse is detected before this interval has elapsed, it is ignored. | ||
== Motor control == | |||
The motor is controlled through the L293D. | |||
The PWM value is defined as: | |||
<syntaxhighlight lang="cpp"> | |||
int motorPWM = 150; | int motorPWM = 150; | ||
</syntaxhighlight> | |||
The PWM | The PWM signal is applied to EN1: | ||
<syntaxhighlight lang="cpp"> | |||
analogWrite(EN1, motorPWM); | analogWrite(EN1, motorPWM); | ||
</syntaxhighlight> | |||
The motor direction is set using: | The motor direction is set using IN1 and IN2: | ||
<syntaxhighlight lang="cpp"> | |||
digitalWrite(IN1, HIGH); | digitalWrite(IN1, HIGH); | ||
digitalWrite(IN2, LOW); | digitalWrite(IN2, LOW); | ||
</syntaxhighlight> | |||
--- | {| class="wikitable" | ||
! Signal | |||
! Arduino pin | |||
! Function | |||
|- | |||
| EN1 | |||
| D5 | |||
| Motor speed | |||
|- | |||
| IN1 | |||
| D7 | |||
| Direction | |||
|- | |||
| IN2 | |||
| D8 | |||
| Direction | |||
|} | |||
== Arduino program == | |||
<syntaxhighlight lang="cpp"> | |||
/* | /* | ||
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 | ||
| Line 334: | Line 451: | ||
} | } | ||
} | } | ||
</syntaxhighlight> | |||
== Serial Monitor == | |||
The Serial Monitor should be configured for '''115200 baud'''. | |||
115200 baud | |||
Example output: | Example output: | ||
<syntaxhighlight> | |||
RPM | RPM | ||
Pulses 80,RPM 240.00 | Pulses 80,RPM 240.00 | ||
| Line 354: | Line 465: | ||
Pulses 81,RPM 243.00 | Pulses 81,RPM 243.00 | ||
Pulses 83,RPM 249.00 | Pulses 83,RPM 249.00 | ||
</syntaxhighlight> | |||
{| class="wikitable" | |||
! Output | |||
! Meaning | |||
|- | |||
| <code>Pulses 80</code> | |||
| 80 encoder pulses detected during the measurement interval | |||
|- | |||
| <code>RPM 240.00</code> | |||
| Calculated gearbox output-shaft speed | |||
|} | |||
== Program parameters == | |||
--- | {| class="wikitable" | ||
! Parameter | |||
! Value | |||
! Description | |||
|- | |||
| <code>ENCODER_PIN</code> | |||
| 2 | |||
| Encoder input | |||
|- | |||
| <code>EN1</code> | |||
| 5 | |||
| Motor PWM output | |||
|- | |||
| <code>IN1</code> | |||
| 7 | |||
| Motor direction | |||
|- | |||
| <code>IN2</code> | |||
| 8 | |||
| Motor direction | |||
|- | |||
| <code>SLOTS_PER_REV</code> | |||
| 20 | |||
| Encoder slots per revolution | |||
|- | |||
| <code>MIN_PULSE_INTERVAL_US</code> | |||
| 2000 | |||
| Minimum pulse interval | |||
|- | |||
| <code>SAMPLE_TIME_MS</code> | |||
| 1000 | |||
| Measurement interval | |||
|- | |||
| <code>motorPWM</code> | |||
| 150 | |||
| PWM value | |||
|} | |||
== Result == | |||
The system controls a geared DC motor using the L293D and measures the rotational speed of its gearbox output shaft using a 20-slot LM393 encoder. | |||
The encoder provides: | |||
<math> | |||
20\ pulses = 1\ output\ revolution | |||
</math> | |||
The Arduino counts the encoder pulses for one second and converts the count into RPM. | |||
RPM | |||
'''Measured output: RPM of the gearbox output shaft.''' | |||
== See also == | |||
* [[Arduino]] | |||
* [[L293D]] | |||
* [[Rotary encoder]] | |||
* [[Pulse counting]] | |||
* [[Pulse-width modulation]] | |||
[[Category:Arduino]] | |||
[[Category:Motor control]] | |||
[[Category:Rotary encoders]] | |||
[[Category:Embedded systems]] | |||
[[Category:Electronics]] | |||
``` | ``` | ||
Revision as of 11:59, 3 September 2026
```wiki
| Arduino Motor Speed Measurement | |
|---|---|
| Controller | Arduino |
| Motor driver | L293D |
| Encoder | LM393 optical encoder |
| Encoder disc | 20 slots |
| Encoder position | Gearbox output shaft |
| Encoder output | Digital (DO) |
| Encoder input | Arduino D2 |
| Motor PWM | Arduino D5 |
| Motor direction | Arduino D7, D8 |
| Measurement period | 1 second |
| Output | RPM |
Arduino Motor Speed Measurement Using L293D and LM393 Encoder is an embedded motor-control system that controls a geared DC motor using an L293D motor driver and measures the rotational speed of the gearbox output shaft using an LM393 optical encoder.
The encoder disc contains 20 slots. Because the encoder is mounted on the gearbox output shaft, 20 encoder pulses correspond to one complete output-shaft revolution.
Objective
- Control a geared DC motor using an L293D motor driver.
- Measure the rotational speed of the gearbox output shaft.
- Count encoder pulses using an Arduino external interrupt.
- Calculate and display the speed in revolutions per minute (RPM).
Hardware
| Component | Quantity |
|---|---|
| Arduino | 1 |
| Geared DC motor | 1 |
| L293D motor driver | 1 |
| LM393 optical encoder module | 1 |
| 20-slot encoder disc | 1 |
| Jumper wires | As required |
| Motor power supply | 1 |
Pin connections
Encoder
| LM393 | Arduino | Purpose |
|---|---|---|
| DO | D2 | Encoder pulse signal |
| VCC | 5V | Power |
| GND | GND | Ground |
L293D
| L293D | Arduino | Purpose |
|---|---|---|
| EN1 | D5 | PWM speed control |
| IN1 | D7 | Motor direction |
| IN2 | D8 | Motor direction |
The motor direction used by the program is:
<syntaxhighlight lang="cpp"> IN1 = HIGH IN2 = LOW </syntaxhighlight>
The PWM signal applied to EN1 controls the motor speed.
System diagram
<syntaxhighlight>
ARDUINO
┌────────────────┐
│ │
D5 ────┼───────────────►│ EN1
D7 ────┼───────────────►│ IN1
D8 ────┼───────────────►│ IN2
│ │
D2 ◄───┼────────────────┤ LM393 DO
│ │
└────────────────┘
│
│ PWM + Direction
▼
┌───────────┐
│ L293D │
└─────┬─────┘
│
▼
┌───────────┐
│ DC MOTOR │
│ + GEARBOX │
└─────┬─────┘
│
▼
┌───────────┐
│ ENCODER │
│ 20 SLOTS │
└─────┬─────┘
│
│ 20 pulses / revolution
▼
Arduino D2
</syntaxhighlight>
Working
The geared motor rotates the gearbox output shaft. The encoder disc is attached to this output shaft.
As the disc rotates, its slots pass the LM393 optical sensor. The sensor generates digital pulses at its DO output.
The Arduino receives these pulses on D2 using an external interrupt.
The basic sequence is:
<syntaxhighlight> Motor rotation
↓
Gearbox output shaft
↓
20-slot encoder disc
↓
LM393 optical sensor
↓
Digital pulses
↓
Arduino D2 interrupt
↓
Pulse counting
↓
RPM calculation
↓
Serial Monitor </syntaxhighlight>
Encoder resolution
The encoder disc has:
<math> 20\ slots/revolution </math>
Therefore:
<math> 20\ pulses = 1\ revolution </math>
Since the encoder is located on the gearbox output shaft, the calculated RPM represents the gearbox output-shaft speed.
RPM calculation
The program measures the number of encoder pulses received during a fixed time interval.
The general equation is:
<math> RPM = \frac{Pulses \times 60} {Slots\ per\ revolution \times Measurement\ time\ (seconds)} </math>
For this implementation:
<math> Slots\ per\ revolution = 20 </math>
and:
<math> Measurement\ time = 1\ second </math>
Therefore:
<math> RPM = \frac{Pulses \times 60}{20} </math>
Example
If the Arduino detects 100 pulses during one second:
<math> RPM = \frac{100 \times 60}{20} </math>
<math> RPM = 300 </math>
Thus, 100 pulses per second correspond to an output-shaft speed of 300 RPM.
Interrupt-based pulse counting
The encoder is connected to Arduino D2 and configured to generate an interrupt on a rising edge.
<syntaxhighlight lang="cpp"> attachInterrupt(
digitalPinToInterrupt(ENCODER_PIN), encoderISR, RISING
); </syntaxhighlight>
When a rising edge is detected, the interrupt service routine is executed.
<syntaxhighlight lang="cpp"> void encoderISR() {
unsigned long currentTime = micros();
if ((currentTime - lastPulseTime) >= MIN_PULSE_INTERVAL_US)
{
pulseCount++;
lastPulseTime = currentTime;
}
} </syntaxhighlight>
Each accepted pulse increments the variable pulseCount.
Pulse filtering
A minimum pulse interval is defined as:
<syntaxhighlight lang="cpp">
- define MIN_PULSE_INTERVAL_US 2000
</syntaxhighlight>
This corresponds to:
<math> 2000\ \mu s = 2\ ms </math>
If another pulse is detected before this interval has elapsed, it is ignored.
Motor control
The motor is controlled through the L293D.
The PWM value is defined as:
<syntaxhighlight lang="cpp"> int motorPWM = 150; </syntaxhighlight>
The PWM signal is applied to EN1:
<syntaxhighlight lang="cpp"> analogWrite(EN1, motorPWM); </syntaxhighlight>
The motor direction is set using IN1 and IN2:
<syntaxhighlight lang="cpp"> digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); </syntaxhighlight>
| Signal | Arduino pin | Function |
|---|---|---|
| EN1 | D5 | Motor speed |
| IN1 | D7 | Direction |
| IN2 | D8 | Direction |
Arduino program
<syntaxhighlight lang="cpp"> /*
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);
// Motor direction digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
// Motor speed analogWrite(EN1, motorPWM);
// Encoder interrupt 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; }
} </syntaxhighlight>
Serial Monitor
The Serial Monitor should be configured for 115200 baud.
Example output:
<syntaxhighlight> RPM Pulses 80,RPM 240.00 Pulses 82,RPM 246.00 Pulses 81,RPM 243.00 Pulses 83,RPM 249.00 </syntaxhighlight>
| Output | Meaning |
|---|---|
Pulses 80
|
80 encoder pulses detected during the measurement interval |
RPM 240.00
|
Calculated gearbox output-shaft speed |
Program parameters
| Parameter | Value | Description |
|---|---|---|
ENCODER_PIN
|
2 | Encoder input |
EN1
|
5 | Motor PWM output |
IN1
|
7 | Motor direction |
IN2
|
8 | Motor direction |
SLOTS_PER_REV
|
20 | Encoder slots per revolution |
MIN_PULSE_INTERVAL_US
|
2000 | Minimum pulse interval |
SAMPLE_TIME_MS
|
1000 | Measurement interval |
motorPWM
|
150 | PWM value |
Result
The system controls a geared DC motor using the L293D and measures the rotational speed of its gearbox output shaft using a 20-slot LM393 encoder.
The encoder provides:
<math> 20\ pulses = 1\ output\ revolution </math>
The Arduino counts the encoder pulses for one second and converts the count into RPM.
Measured output: RPM of the gearbox output shaft.
See also
```