Introduction: ESP32 LoRa Controlled Drone Engine

About: Do you like technology? Follow my channel on Youtube and my Blog. In them I put videos every week of microcontrollers, arduinos, networks, among other subjects.

Today we’re discussing drone engines, frequently called “brushless” motors. They’re widely used in aeromodelling, mainly in drones, due to their power and high rotation. We’ll learn about controlling a brushless motor using ESC and ESP32, performing an analogic actuation on the ESC using the internal LED_PWM controller, and using a potentiometer to change the motor speed.

Step 1: Demonstration

Step 2: Resources Used

  • Jumpers for connection
  • Wifi LoRa 32
  • ESC-30A
  • Brushless A2212 / 13t Engine
  • USB cable
  • Potentiometer for control
  • Protoboard
  • Power supply

Step 3: Wifi LoRa 32- Pinout

Step 4: ESC (Electronic Speed Control)

  • Electronic Speed Controller
  • Electronic circuit to control the speed of an electric motor.
  • Controlled from a standard 50Hz PWM servo control.
  • It varies the switching rate of a network of field effect transistors (FETs). By adjusting the switching frequency of the transistors, the motor speed is changed. The motor speed is varied by adjusting the timing of the supplied current pulses to the various windings of the motor.
  • Specifications:

Output current: 30A continuous, 40A for 10 seconds

Step 5: ESC Electronic Speed Control (ESC)

Step 6: PWM Servo Motor Control

We will create a PWM servo to act on ESC data input by directing channel 0 of the LED_PWM for the GPIO13, and use a potentiometer to control the modulation.

For the capture, we will use a potentiometer of 10k as a voltage divider. The capture will be done on channel ADC2_5, accessible by GPIO12.

Step 7: Analog Capture

Analog to digital conversion

We’ll convert the values of AD to the PWM.

The PWM of the servo is 50Hz, so the pulse period is 1/50 = 0.02 seconds or 20 milliseconds.

We need to act in at least 1 millisecond to 2 milliseconds.

When the PWM is at 4095, the pulse width is 20 milliseconds, meaning we should reach the maximum at 4095/10 to reach 2 milliseconds, so PWM should receive 410 *.

And after at least 1 millisecond, therefore 409/2 (or 4095/20), the PWM should receive 205 *.

* Values must be integers

Step 8: Circuit - Connections

Step 9: Source Code


#include <Wire.h> // Necessário apenas para o Arduino 1.6.5 e posterior
#include "SSD1306.h" // o mesmo que #include "SSD1306Wire.h" //OLED_SDA -- GPIO4 //OLED_SCL -- GPIO15 //OLED_RST -- GPIO16 #define SDA 4 #define SCL 15 #define RST 16 SSD1306 display(0x3c, SDA, SCL, RST); //Instanciando e ajustando os pinos do objeto "display"


const int freq = 50;
const int canal_A = 0; const int resolucao = 12; const int pin_Atuacao_A = 13; const int Leitura_A = 12; int potencia = 0; int leitura = 0; int ciclo_A = 0;


void setup()
{ pinMode(pin_Atuacao_A, OUTPUT); ledcSetup(canal_A, freq, resolucao); ledcAttachPin(pin_Atuacao_A, canal_A); ledcWrite(canal_A, ciclo_A); 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); }


void loop() {
leitura = analogRead(Leitura_A); ciclo_A = map(leitura, 0, 4095, 205, 410); ledcWrite(canal_A, ciclo_A); potencia = map(leitura, 0, 4095, 0, 100); display.clear();//limpa o buffer do display display.drawString(0, 0, String("AD:")); display.drawString(32, 0, String(leitura)); display.drawString(0, 18, String("PWM:")); display.drawString(48, 18, String(ciclo_A)); display.drawString(0, 36, String("Potência:")); display.drawString(72, 36, String(potencia)); display.drawString(98, 36, String("%")); display.display(); //mostra no display }

Step 10: Files

Download the files