A direct current (DC) motor is a type of electric machine that converts electrical energy into mechanical energy. Absorbs electricity through direct current and converts it into mechanical rotation. The windings, once powered by electric current, create magnetic fields that set in motion the magnets connected to the rotor (a rotating part of a machine that generates or transmits power is defined as a rotor). The rotor then converts and transmits the movement of the magnets to the motor shaft. The rotation speed depends on both the electrical input and the motor design. Here we are going to control the direction and speed of a DC Motor with Arduino using L298N and PWM

1. CONCEPTS

Working of a DC Motor

A normal dc motor produces torque using electromagnetic forces using the principle that when a current-carrying conductor is placed in a magnetic field it experiences a mechanical force. When a current-carrying conductor is placed in a magnetic field, it experiences a torque and tends to move. In other words, when a magnetic field and an electric field interact, a mechanical force is produced. The DC motor or direct current motor works on that principle. This is known as motoring action.

Figure 1: Cross-section of a DC motor

Structurally and construction-wise, a direct current motor is exactly similar to a DC generator, but it is electrically the opposite. Here we unlike a generator we supply electrical energy to the input port and derive mechanical energy from the output port. The direction of rotation of this motor is given by Fleming’s left-hand rule, which states that if the index finger, middle finger, and thumb of your left hand are extended mutually perpendicular to each other and if the index finger represents the direction of the magnetic field, middle finger indicates the direction of the current, then the thumb represents the direction in which force is experienced by the shaft of the DC motor.

L298N Motor Driver IC

The current required by the motors which we are using is quite high as compared to the maximum output current of the Arduino pins (40mA). Moreover, motors draw a lot of current due to their mechanical motion. So even if the program is correct, motors will still not work correctly if you connect them directly with the Arduino board. Therefore we have to use a motor driver IC like L298N to drive our motors using the signal from Arduino.

Interfacing L298N Motor Driver IC with Arduino
Interfacing L298N Motor Driver IC with Arduino

Figure 4: Connecting IR sensor with Arduino

This motor driver IC has four input pins (IN1, IN2, IN3 and IN4) from where you can feed the signal, four output pins (OUT1, OUT2, OUT3 and OUT4) to connect two motors on both sides and two Enable pins (ENA and ENB) to control the speed of motors. As a bonus, it can also control a stepper motor. Here are the specs of the L298N Motor Driver IC.

  • Operating supply voltage up to 46V
  • Total DC current up to 4A
  • Maximum motor supply current: 2A per motor.
  • Integrated 5V power regulator
  • Low saturation voltage
  • Overtemperature protection
  • Logical “0” Input Voltage up to 1.5 V (High noise immunity)

Controlling Rotation Direction of Motors using H-Bridge

The purpose of an H-bridge is to allow the reversal of the direction of the current in a load. It is used to set the rotation of a DC motor in a clockwise rather than anti-clockwise direction. For its operation, unlike other solutions, a single power supply is required. An H-bridge uses 4 transistors, two of the NPN type and two of the PNP type connected, as shown below.

What is H Bridge and working in Motor driver
Case 1: H Bridge; Rotation to the right of the rotor
What is H Bridge and working in Motor driver
Case 2: H Bridge; Rotation to the left of the rotor

The input signal is applied to the T1, T2, T3 and T4 terminals of the H-bridge. When T1 and T2 are HIGH and T3 and T4 are LOW (Case 1), then T2 and T3 start conducting current, causing the motor to rotate to the left. In the same way, when T1 and T2 are LOW and T3 and T4 are HIGH (Case 2), then T1 and T4 start conducting current, causing the motor to rotate to the right. Using this principle inside the L298N motor driver IC we can control the direction of two motors because of dual H-Bridge circuits inside it. Therefore, by using the L298N driver(Figure 4) we can control Motor A using IN1, IN2 and Motor B using IN3, IN4. Table 1 below shows all the possible directions of both motors according to the signal provided.

Input Signal
(IN1, IN2)
Motor Direction
(MOTOR A)
Input Signal
(IN3, IN4)
Motor Direction
(MOTOR B)
0, 0stop0, 0stop,
1, 0clockwise1, 0clockwise
0, 1anticlockwise0, 1anticlockwise
1, 1stop1, 1stop
Table 1: Motor directions according to the input signal

Both pins of a dc motor are non-polar so you have to make sure manually that when IN1, IN2 and IN3, IN4 are 1, 0 and 1, 0 respectively, both the motors should rotate in the clockwise direction.

Controlling Speed of DC Motor with Arduino using PWM

By varying the input voltage at Enable pin A (ENA) and Enable pin B (ENB), we can control the speed of motor A and B respectively. This can be done using PWM or Pulse Width Modulation

PWM is a technique used to create a rectangular pulse wave, a signal switched between ON and OFF. This ON and OFF pattern can simulate voltages in between full ON(5V) and Full OFF(0V). The resultant Voltage is called Duty Cycle. In Arduino, this can be done by calling the analogWrite() function. A call to analogWrite() is on a scale of 0 – 255, such that analogWrite(255) requests a 100% duty cycle (always on), and analogWrite(127) is a 50% duty cycle (on half the time).

You have to check the lowest PWM value for your motor where it will start rotating. (refer to FAQ section)

2. COMPONENTS

3. CONNECTIONS

Figure Driving DC Motor with Arduino using L298N and controlling its speed using PWM
Figure Driving DC Motor with Arduino using L298N and controlling its speed using PWM

Figure 3: Connecting Motors using L293D Motor Driver IC with Arduino

4. PROGRAMS

Program 1: Controlling the direction DC Motor with Arduino using L298N Motor Driver IC

/*UNCIA ROBOTICS | www.unciarobotics.com
  PROGRAM:CONTROLLING DIRECTION OF MOTORS USING L298N
  Control direction of two motors using L298N Motor Driver IC

  Connections:
  Arduino       L298N     Arduino       L298N
  3             ENA       9             ENB
  4             IN1       5             IN2
  6             IN3       7             IN4
*/

const int ENA = 3, ENB = 9;   //PWM pins for controlling speed
const int IN1 = 4, IN2 = 5, IN3 = 6, IN4 = 7;   //INPUT pins
void setup() {
  pinMode(IN1, OUTPUT);     //Make IN1,IN2,IN3,IN4 as OUTPUT pins
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  analogWrite(ENA, 255);    //set speed to maximum
  analogWrite(ENB, 255);
}

void loop() {
  digitalWrite(IN1, HIGH);  //rotate both motors
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  delay(2000);              //wait for some time
  digitalWrite(IN1, LOW);   //change direction of rotation
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  delay(2000);              //wait for some time
}

Program 2: Controlling the speed of DC Motor with Arduino using L298N Motor Driver IC

/*UNCIA ROBOTICS | www.unciarobotics.com
  PROGRAM:CONTROLLING SPEED OF MOTORS USING L298N
  Control speed of two motors using L298N Motor Driver IC

  Connections:
  Arduino       L298N     Arduino       L298N
  3             ENA       9             ENB
  4             IN1       5             IN2
  6             IN3       7             IN4
*/

const int ENA = 3, ENB = 9;   //PWM pins for controlling speed
const int IN1 = 4, IN2 = 5, IN3 = 6, IN4 = 7;   //INPUT pins
void setup() {
  pinMode(IN1, OUTPUT);     //Make IN1,IN2,IN3,IN4 as OUTPUT pins
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}

void loop() {
  for (int i = 0; i <= 255; i = i + 5)    //increase the speed
  { analogWrite(ENA, i);
    analogWrite(ENB, i);
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(10);
  }
  for (int i = 255; i >= 0; i = i - 5)    //decrease the speed
  { analogWrite(ENA, i);
    analogWrite(ENB, i);
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(10);
  }
}

Program 3: Accelerate and Decelerate DC motor with Arduino using L298N linearly using millis()

/*UNCIA ROBOTICS | www.unciarobotics.com
  PROGRAM: ACCELERATE AND DECELERATE MOTORS LINEARLY
  Accelerate and Decelerate DC motors using L298N linearly 
  using PWM(Pulse WIdth Modulation) and millis() function

  Connections:
  Arduino       L298N     Arduino       L298N
  3             ENA       9             ENB
  4             IN1       5             IN2
  6             IN3       7             IN4
*/

const int ENA = 3, ENB = 9;   //PWM pins for controlling speed
const int IN1 = 4, IN2 = 5, IN3 = 6, IN4 = 7;     //INPUT pins
unsigned long currentTime;    //variable to store current time
unsigned long prevTime = 0;   //variable to store prev time
int threshold = 30;           //time threshold in milliseconds
int acc = 0;                  //variable to store acc value
int accDirection = 1;         //to store acceleration direction
void setup() {
  pinMode(IN1, OUTPUT);       //IN1,IN2,IN3,IN4 as OUTPUT Pins
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);         //Start Serial Communication
}

void loop() {
  currentTime = millis(); //save the value millis() function
  if ((currentTime - prevTime) >= threshold)
  { Serial.print("Threshold: ");  //print calculated value
    Serial.print(currentTime - prevTime);
    Serial.print('\t');
    if (acc < 255 || acc > 0)     //if acc is between limits
    { Serial.print("Acc: ");      //print acceleration value
      Serial.print(acc);
      Serial.println("");
      analogWrite(ENA, acc);      //write acc value on ENA
      analogWrite(ENB, acc);      //write acc value on ENB
      acc = acc + accDirection;   //increment/decrement acc
      prevTime = currentTime;
    }
    if (acc == 255 || acc == 0)   //if acc reaches end points
    { Serial.println("direction change");
      accDirection = accDirection * (-1); //change direction
    }
  }
  digitalWrite(IN1, HIGH);        //rotate both motors
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

Program 4: Accelerate and Decelerate DC motor with Arduino using L298N exponentially using millis()

/*UNCIA ROBOTICS | www.unciarobotics.com
  PROGRAM: ACCELERATE AND DECELERATE MOTORS EXPONENTIALLY.
  Accelerate and Decelerate DC motors using L298N
  exponentially using PWM and millis() function.

  Connections:
  Arduino       L298N     Arduino       L298N
  3             ENA       9             ENB
  4             IN1       5             IN2
  6             IN3       7             IN4
*/

const int ENA = 3, ENB = 9;   //PWM pins for controlling speed
const int IN1 = 4, IN2 = 5, IN3 = 6, IN4 = 7;     //INPUT pins
unsigned long currentTime;    //store current time
unsigned long prevTime = 0;   //store previous time
int threshold = 200;          //time interval in milliseconds
int acc = 0;                  //initial acceleration
int power = 0;                //exponential power
int accDirection = 1;         //initial direction of acc
void setup() {
  pinMode(IN1, OUTPUT);       //IN1,IN2,IN3,IN4 as OUTPUT Pins
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);         //start Serial Communication
}

void loop() {
  currentTime = millis(); //save the value millis() function
  if ((currentTime - prevTime) >= threshold)
  { Serial.print("Threshold: ");  //print Threshold value
    Serial.print(currentTime - prevTime); Serial.print('\t');
    if (power < 8 || power > 0)   //power is between limits
    { Serial.print("Power: ");      //print acceleration value
      Serial.print(acc); Serial.print('\t');
      analogWrite(ENA, acc);
      analogWrite(ENB, acc);
      power = power + accDirection; //increment/decrement power
      acc = pow(2, power);          //vary acc exponentially
      Serial.print("Acc: ");
      Serial.print(acc); Serial.println("");
      prevTime = currentTime;
    }
    if (power == 8 || power == 0)   //power reaches end points
    { Serial.println("direction change");
      accDirection = accDirection * (-1); //change direction
    }
  }
  digitalWrite(IN1, HIGH);        //rotate both motors
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

5. FUNCTIONS USED



6. FAQ’s

What are the uses of DC Motors?

Robots
DC motors in robots operate something like rails, arms or cameras. DC motors are particularly convenient for their efficiency and high torsion, ideal for robotics.
Toys
DC motors are very popular among children’s toy manufacturers. Small DC motors are used in remote-controlled cars and model trains. Their popularity is due to the ease of use and their robustness. The availability of different voltage varieties allows the use of DC motors in toys that require the most disparate speeds to perform different movements. Some of them are also connected to a controller.
Electric cars
Among the different types of motors that are installed in electric cars, DC motors are considered to be among the most efficient and durable. In addition to large production houses, mechanics and DIY enthusiasts also prefer DC motors, especially the series type.
Electric bicycles
Electric bicycles owe their success to the fact that they do not require a particular driving license. The maximum speed is, in fact, less than 25 km/h. The motor is compactly incorporated into the rear or front wheel hub, or mounted in the centre of the bike and connected to the pedal pinion.

Why Motors are not working at lower PWM Values? (Beeping sound)?

Motors require a minimum Threshold Duty Cycle or PWM Signal after which they will start working. So you have to check manually, what is minimum Threshold PWM value is at which your motor will start working.

This can be done by uploading the following program:

/*SAMPLE PROGRAM TO CHECK MINIMUM THRESHOLD VALUE FOR WORKING OF
  DC MOTOR*/
const int ENA = 3, ENB = 9;   //PWM pins for controlling speed
const int IN1 = 4, IN2 = 5, IN3 = 6, IN4 = 7;   //INPUT pins
void setup() {
  pinMode(IN1, OUTPUT);     //Make IN1,IN2,IN3,IN4 as OUTPUT pins
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i <= 255; i = i + 5)    //increase the speed
  { Serial.print("PWM Value: "); Serial.println(i);
    Serial.println("");
    analogWrite(ENA, i);    //write PWM value on Enable PIN A
    analogWrite(ENB, i);
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(1000);
  }
}

After Uploading the Program press Ctrl + shift + M in windows to open Serial monitor and look for the minimum PWM values at which the Motors will start rotating. Note down these values and use them as minimum PWM values in all the programs accordingly.

Can we use a potentiometer instead of a PWM signal to vary the speed of the Motors L298N Motor Driver Module?

Yes, in both ways it will work. You can use a PWM signal from Arduino or you can use a potentiometer on those Enable Pins to vary the motors speed. The only difference will be that a Potentiometer will reduce power by throwing it away as heat so it’s not a good solution for driving motors where the current requirement is More.

Pulse Width Modulation (PWM) on the other hand controls power by turning it on and off rapidly. So rapidly that the load consuming the power doesn’t notice. So say you have a 12v motor that draws 1 Amp max. Instead of trying to find a 1A pot that will get very hot, you can instead use PWM to rapidly switch from 0V to 12V more than 10,000 times a second.

The motor lumbers along only seeing the average power which depends only on the duty cycle. This is the percentage of on-time vs off-time. Half on and half off is 50%. The higher per cent will give you more average power and faster speed. Lesser Duty Cycle will give you a less average power and a slower speed. All this time your PWM power transistor is only going from completely off to completely on and barely breaking a sweat. This is because transistors are very efficient when totally on or totally off, less so in between.

So the thing to note is that a potentiometer is good for small loads but not efficient. PWM is great and really required for larger loads.

Still, Having Doubts?

Ask your questions regarding DC Motor with Arduino using L298N and PWM in the comments section below or Contact Us.

DC Motor with ArduinoDC Motor with Arduino using L298N and PWM

Leave a Reply