13. Chapter Motor & Driver

In this chapter, we will learn about DC Motors and DC Motor Drivers and how to control the speed and direction of a DC Motor.

13.1. Project Control a DC Motor with a Potentiometer

In this project, a potentiometer will be used to control a DC Motor. When the Potentiometer is at the midpoint position, the DC Motor will STOP, and when the Potentiometer is turned in either direction of this midpoint, the DC Motor speed increases until it reached the endpoint where the DC Motor achieves its maximum speed. When the Potentiometer is turned “Left” of the midpoint the DC Motor will ROTATE in one direction and when turned “Right” the DC Motor will ROTATE in the opposite direction.

13.1.1. Component List

Breadboard Power Module

  1. Raspberry Pi (with 40 GPIO) x1

  2. GPIO Extension Board & Ribbon Cable x1

  3. Breadboard x1

Jumper Wires x23

jumper-wire

Breadboard Power Module x1

power-module

9V Battery (you provide) & 9V Battery Cable

Battery_cable

ADC module x1

ADC-module-1 or ADC-module-2

L293D IC Chip

L2983_chip

DC Motor x1

DC_Motor_Module

Rotary Potentiometer x1

Rotary-potentiometer

Resistor 10kΩ x2

Resistor-10kΩ

13.1.2. Component knowledge

13.1.2.1. Breadboard Power Module

Breadboard Power Module is an independent circuit board, which can provide independent 5V or 3.3V power to the breadboard when building circuits. It also has built-in power protection to avoid damaging your RPi module. The schematic diagram below identifies the important features of this Power Module:

../../../_images/power-mode.png

Here is an acceptable connection between Breadboard Power Module and Breadboard using a 9V battery and the provided power harness:

../../../_images/power-mode-2.png

13.1.2.2. DC Motor

DC Motor is a device that converts electrical energy into mechanical energy. DC Motors consist of two major parts, a Stator and the Rotor. The stationary part of a DC Motor is the Stator and the part that Rotates is the Rotor. The Stator is usually part of the outer case of motor (if it is simply a pair of permanent magnets), and it has terminals to connect to the power if it is made up of electromagnet coils. Most Hobby DC Motors only use Permanent Magnets for the Stator Field. The Rotor is usually the shaft of motor with 3 or more electromagnets connected to a commutator where the brushes (via the terminals 1 & 2 below) supply electrical power, which can drive other mechanical devices. The diagram below shows a small DC Motor with two terminal pins.

../../../_images/DC-Motor.png

When a DC Motor is connected to a power supply, it will rotate in one direction. If you reverse the polarity of the power supply, the DC Motor will rotate in opposite direction. This is important to note.

../../../_images/DC-Motor-1.png

13.1.2.3. L293D

L293D is an IC Chip (Integrated Circuit Chip) with a 4-channel motor drive. You can drive a Unidirectional DC Motor with 4 ports or a Bi-Directional DC Motor with 2 ports or a Stepper Motor (Stepper Motors are covered later in this Tutorial).

../../../_images/L293D.png

Port description of L293D module is as follows:

Pin name

Pin number

Description

In x

2, 7, 10, 15

Channel x digital signal input pin

Out x

3, 6, 11, 14

Channel x output pin, input high or low level

according to In x pin, getsconnected to +Vmotor or 0V

Enable1

1

Channel 1 and Channel 2 enable pin, high level enable

Enable2

9

Channel 3 and Channel 4 enable pin, high level enable

0V

4, 5, 12, 13

Power Cathode (GND)

+V

16

Positive Electrode (VCC) of power supply, supply voltage 4.5~36V

+Vmotor

8

Positive Electrode of load power supply, provide power

supply for the Out pin x, the supply voltage is +V~36V

See also

For more details, please see the datasheet for this IC Chip.

When using the L293D to drive a DC Motor, there are usually two connection options.

The following connection option uses one channel of the L239D, which can control motor speed through the PWM, However the motor then can only rotate in one direction.

../../../_images/L293D-1.png

The following connection uses two channels of the L239D: one channel outputs the PWM wave, and the other channel connects to GND. Therefore, you can control the speed of the motor. When these two channel signals are exchanged, not only controls the speed of motor, but also can control the direction of the motor.

../../../_images/L293D-2.png

In practical use the motor is usually connected to channel 1 and by outputting different levels to in1 and in2 to control the rotational direction of the motor, and output to the PWM wave to Enable1 port to control the motor’s rotational speed. If the motor is connected to channel 3 and 4 by outputting different levels to in3 and in4 to control the motor’s rotation direction, and output to the PWM wave to Enable2 pin to control the motor’s rotational speed.

13.1.3. Circuit with ADS7830

Use caution when connecting this circuit because the DC Motor is a high-power component. Do not use the power provided by the RPi to power the motor directly, as this may cause permanent damage to your RPi! The logic circuit can be powered by the RPi’s power or an external power supply, which should share a common ground with RPi.

Schematic diagram

Motor-ADS7830-Sc

Hardware connection. If you need any support,please feel free to contact us via:

support@freenove.com

Motor-ADS7830-Fr

13.1.4. Circuit with PCF8591

Use caution when connecting this circuit because the DC Motor is a high-power component. Do not use the power provided by the RPi to power the motor directly, as this may cause permanent damage to your RPi!` The logic circuit can be powered by the RPi’s power or an external power supply, which should share a common ground with RPi.

Schematic diagram

Motor-PCF8591-Sc

Hardware connection. If you need any support,please feel free to contact us via:

support@freenove.com

Motor-PCF8591-Fr

13.1.5. Code

In code for this project, first read the ADC value and then control the rotation direction and speed of the DC Motor according to the value of the ADC.

13.1.5.1. C Code Motor

If you did not configure I2C, please refer to Chapter 7. If you did, please continue.

First, observe the project result, and then learn about the code in detail.

Hint

If you have any concerns, please contact us via: support@freenove.com

  1. Use cd command to enter 13.1.1_Motor directory of the C code.

$ cd ~/Freenove_Kit/Code/C_Code/13.1.1_Motor
  1. Use the following command to compile Motor.cpp and generate the executable file Motor.

$ g++ Motor.cpp -o Motor -lwiringPi -lADCDevice
  1. Then run the generated file Motor.

$ sudo ./Motor

After the program is executed, you can use the Potentiometer to control the DC Motor. When the Potentiometer is at the midpoint position, the DC Motor will STOP, and when the Potentiometer is turned in either direction of this midpoint, the DC Motor speed increases until it reaches the endpoint where the DC Motor achieves its maximum speed. When the Potentiometer is turned “Left” of the midpoint the DC Motor will ROTATE in one direction and when turned “Right” the DC Motor will ROTATE in the opposite direction. You will also see the ADC value of the potentiometer displayed in the Terminal with the motor direction and the PWM duty cycle used to control the DC Motor’s speed.

../../../_images/Motor-value.png

The following is the code:

 1/**********************************************************************
 2* Filename    : Motor.cpp
 3* Description : Control Motor by L293D
 4* Author      : www.freenove.com
 5* modification: 2020/03/09
 6**********************************************************************/
 7#include <wiringPi.h>
 8#include <stdio.h>
 9#include <softPwm.h>
10#include <math.h>
11#include <stdlib.h>
12#include <ADCDevice.hpp>
13
14#define motorPin1    2        //define the pin connected to L293D
15#define motorPin2    0
16#define enablePin    3
17
18ADCDevice *adc;  // Define an ADC Device class object
19
20//Map function: map the value from a range to another range.
21long map(long value,long fromLow,long fromHigh,long toLow,long toHigh){
22    return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow;
23}
24//motor function: determine the direction and speed of the motor according to the ADC 
25void motor(int ADC){
26    int value = ADC -128;
27    if(value>0){
28        digitalWrite(motorPin1,HIGH);
29        digitalWrite(motorPin2,LOW);
30        printf("turn Forward...\n");
31    }
32    else if (value<0){
33        digitalWrite(motorPin1,LOW);
34        digitalWrite(motorPin2,HIGH);
35        printf("turn Back...\n");
36    }
37    else {
38        digitalWrite(motorPin1,LOW); 
39        digitalWrite(motorPin2,LOW);
40        printf("Motor Stop...\n");
41    }
42    softPwmWrite(enablePin,map(abs(value),0,128,0,100));
43    printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);//print the PMW duty cycle
44}
45int main(void){
46    adc = new ADCDevice();
47    printf("Program is starting ... \n");
48
49    if(adc->detectI2C(0x48)){    // Detect the pcf8591.
50        delete adc;                // Free previously pointed memory
51        adc = new PCF8591();    // If detected, create an instance of PCF8591.
52    }
53    else if(adc->detectI2C(0x4b)){// Detect the ads7830
54        delete adc;               // Free previously pointed memory
55        adc = new ADS7830();      // If detected, create an instance of ADS7830.
56    }
57    else{
58        printf("No correct I2C address found, \n"
59        "Please use command 'i2cdetect -y 1' to check the I2C address! \n"
60        "Program Exit. \n");
61        return -1;
62    }
63    wiringPiSetup();
64    pinMode(enablePin,OUTPUT);//set mode for the pin
65    pinMode(motorPin1,OUTPUT);
66    pinMode(motorPin2,OUTPUT);
67    softPwmCreate(enablePin,0,100);//define PMW pin
68    while(1){
69        int value = adc->analogRead(0);  //read analog value of A0 pin
70        printf("ADC value : %d \n",value);
71        motor(value);        //make the motor rotate with speed(analog value of A0 pin)
72        delay(100);
73    }
74    return 0;
75}

Now that we have familiarity with reading ADC values, let’s learn the subfunction void motor (int ADC): first, compare the ADC value with 128 (value corresponding to midpoint). When the current ADC value is higher, motoRPin1 outputs high level and motoRPin2 outputs low level to control the DC Motor to run in the “Forward” Rotational Direction. When the current ADC value is lower, motoRPin1 outputs low level and motoRPin2 outputs high level to control the DC Motor to run in the “Reverse” Rotational Direction. When the ADC value is equal to 128, motoRPin1 and motoRPin2 output low level, the motor STOPS. Then determine the PWM duty cycle according to the difference (delta) between ADC value and 128. Because the absolute delta value stays within 0-128, we need to use the map() subfunction mapping the delta value to a range of 0-255. Finally, we see a display of the duty cycle in Terminal.

 1void motor(int ADC){
 2    int value = ADC -128;
 3    if(value>0){
 4        digitalWrite(motorPin1,HIGH);
 5        digitalWrite(motorPin2,LOW);
 6        printf("turn Forward...\n");
 7    }
 8    else if (value<0){
 9        digitalWrite(motorPin1,LOW);
10        digitalWrite(motorPin2,HIGH);
11        printf("turn Back...\n");
12    }
13    else {
14        digitalWrite(motorPin1,LOW); 
15        digitalWrite(motorPin2,LOW);
16        printf("Motor Stop...\n");
17    }
18    softPwmWrite(enablePin,map(abs(value),0,128,0,100));
19    printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);//print the PMW duty cycle
20}