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 1: Demonstration
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 7: Capture of Control Circuit Output States
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 9: Evaluating the Behavior of the Engine
Step 10: Source Code: Mean Curve
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);
}
Copyright © 2012, P. Lutus -- http://www.arachnoid.com. All Rights Reserved.
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"
//PWM usado como oscilador do dobrador de tensão 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% //PWM usado para controle de velocidade 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); ledcWrite(canal_vel, velocidade); //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 ) for (velocidade = 4095; velocidade >= min_vel ; velocidade = velocidade - 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 ) for (velocidade = min_vel; velocidade <= 4095 ; velocidade = velocidade + 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 } }