## Introduction: DC Motor Speed Control With ESP32

We’ll discuss today about the H Bridge, and how to control the speed of a DC motor with an ESP32 LoRa with display. I'll introduce you to an H-bridge speed control using MOSFET, and then we’ll apply that control to an engine to evaluate its behavior. I specifically like the car glass engine, as it consumes a reasonable current of around 2 amps. However, it has a lot of torque force. It also has an endless thread with a gear that gives it good mechanical resistance.

If you haven’t seen it yet, watch this video now: Super Driver from 1 to 200 amps for DC Motor. Here, I teach about Bridge H with MOSFETs.

## Step 2: Resources Used

• One ESP WiFi LoRa 32

• Four IRF1404s

• Three BC337s

• One CD4011

• Resistors

• Two 1uF electrolytic capacitors

• Two diode 1N4148s

• USB cable for ESP

• 12V source for the load used

• Charging (we use an electric glass motor)

• Protoboard

• Wires

• Tachometer or other method to measure RPM

## Step 3: Scheme

• This is the scheme used in this example, and it is the same as shown in the H-bridge video with MOSFET

## Step 4: Scheme - Bridge H

• The H-bridge will have four IRF1404s arranged so that the activation of a pair will allow current flow in one direction, and the activation of the opposite pair will reverse the direction.

• We indicate the torque that must be activated at the same time by the DIR A and DIR B inputs, indicating the change of direction of the motor.

## Step 5: Diagram - the Voltage Folder

• This is a circuit based on diodes and capacitors that are well-known in electronics.

• It functions primarily as an electron "pump,” pushing electrons through the capacitors to create a higher voltage due to the accumulation of charges.

• At first, a voltage doubler must deliver twice the input voltage at its output.

• In practice, due to voltage drops, the value obtained was approximately 21.5V. But it was enough for the MOSFET.

## Step 6: Schema - Activation - Hardware

• Unlike the last video, this time we have included the control circuit of the states of the H bridge. This is to expand the previous example and guarantee a physical stage of protection against the prohibited state.

• Control inputs will be named:

 EN (from the ENABLE term), connected to the GPIO17 of the ESP.

 DIR, connected to ESP GPIO4.

• We will use a PWM applied to the EN pin to control the amount of energy delivered to the motor and consequently its speed.

• REMEMBER: THERE SHOULD NOT BE SIMULTANEOUS ACTIVATION OF DIR A AND DIR B

## Step 8: ​Procedure

 We’ll write a code that allows us to obtain the RPM value for several PWM values.

 For this, we measure the RPM using a digital tachometer.

 For each PWM value, we’ll measure the engine RPM for 20 seconds

## Step 11: Speed Adjustment Function

• Using the methods that we have already presented on other occasions, we can obtain a mean curve. The mean curve represents the behavior of the motor in question. From there, relate a value of PWM and RPM.

Mode: normal

Polynomial degree 6, 25 x,y data pairs

Correlation coefficient (r^2) = 9,999194679032e-01

Standard error = 1,643952462530e-01

Output form: C/C++ function:

double f(double x) {

return -5,900718562093e+01

+ 1,080432239400e-01 * x

+ 8,360068942087e-06 * pow(x,2)

+ -4,690449122452e-08 * pow(x,3)

+ 2,352218983798e-11 * pow(x,4)

+ -4,810573531109e-15 * pow(x,5)

+ 3,614465424238e-19 * pow(x,6);

}

## Step 12: Source Code

#Includes and #Defines

```//Bibliotecas para utilização do display OLED#include <Wire.h>  // Necessário apenas para o Arduino 1.6.5 e posterior
#include "SSD1306.h" // o mesmo que #include "SSD1306Wire.h"

//Os pinos do OLED estão conectados ao ESP32 pelos seguintes GPIO's:
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16

#define SDA    4
#define SCL   15
#define RST   16 //RST pode ser ajustado por software```

Objects, Constants, and Variables

```SSD1306  display(0x3c, SDA, SCL, RST); //Instanciando e ajustando os pinos do objeto "display"
const int freq_osc = 1000; //Frequencia do PWM
const int canal_osc = 0; // canal do PWM oscilador
const int pin_osc = 21; //GPIO utilizada para o oscilador
const int ciclo = 2048; //ciclo de trabalho de 50%

const int freq_vel = 200; //Frequencia do PWM do controle de velocidade
const int canal_vel = 1; // canal do PWM controle de velocidade
const int pin_EN = 17; //Habilita ou desabilita a ponte (controla a velocidade)
const int pin_DIR = 2; //Controla direção

//Resolução dos PWM's
const int resolucao = 12; // Resolução (4096 estados)

//Intervalo para mudança do PWM
const int intervalo = 200;

//Constante que determinar o valor mínimo para o PWM
const int min_vel = 0;

// Variável usada para alternar a direção
boolean dir = false;

// variável para armazenar a velocidade atual
int velocidade = 0;```

Setup ()

```void setup(){
//seta a direção dos GPIO
pinMode(pin_osc, OUTPUT);
pinMode(pin_DIR, OUTPUT);
pinMode(pin_EN, OUTPUT);

// Ajusta o PWM do oscilador do dobrador
ledcSetup(canal_osc, freq_osc, resolucao);
ledcAttachPin(pin_osc, canal_osc);
ledcWrite(canal_osc, ciclo);

// Ajusta o PWM de controle de velocidade
ledcSetup(canal_vel, freq_vel, resolucao);
ledcAttachPin(pin_EN, canal_vel);

//Ajusta a direção para LOW inicialmente
digitalWrite(pin_DIR, dir);

// Inicia o display
display.init();

display.flipScreenVertically(); //Vira a tela verticalmente
display.clear();
//ajusta o alinhamento para a esquerda
display.setTextAlignment(TEXT_ALIGN_LEFT);
//ajusta a fonte para Arial 16
display.setFont(ArialMT_Plain_16);
}```

Loop ()

```void loop(){
//Varia os estados do PWM do máximo até o valor mínimo em passos de 136.5 unidades
//para que todo o intervalo tenha 30 valores (4095 / 30 = 136.5 )
{

ledcWrite(canal_vel, velocidade);//ajusta o PWM para o novo valor de velocidade
display.clear(); //limpa o buffer do display
display.drawString(0, 0, String(velocidade)); //escreve a velocidade no buffer
display.display(); ///mostra no display
delay(intervalo); //aguarda o intervalo
}

dir = !dir; //inverte a variável de controle de direção
digitalWrite(pin_DIR, dir); // ajusta o pino de direção com o novo valor

//Varia os estados do PWM do mínimo até o valor máximo em passos de 136.5 unidades
//para que todo o intervalo tenha 30 valores (4095 / 30 = 136.5 )
{
ledcWrite(canal_vel, velocidade); //ajusta o PWM para o novo valor
display.clear();//limpa o buffer do display
display.drawString(0, 0, String(velocidade)); //escreve a velocidade no buffer
display.display(); //mostra no display
delay(intervalo); //aguarda o intevalo
}
}```