10/05/2024

Running Bi-Directional ESC with Arduino (Forward & Reverse)

How to control bidirectional ESC with Arduino? With these codes and links, you can use Brushed and Brushless ESC (Electronic Speed controller) and motors.

 

Code (No Oled Screen):

 #include <Servo.h> //Arduino Servo Library 

Servo ESC;  // ESC için bir obje tanımlanıyor. 

float value;    // Analog pin A1 den veri okuma için değişken tanımlaması. 
void setup()
{
  Serial.begin(9600);
  ESC.attach(3);  // Pin 3 den PWM sinyal çıkışı.
}

void loop() { 
  
   for(int i = 0; i < 50; i++)
     {
      value=value+analogRead(A1); // Potansiyometreden gelen değeri daha kararlı veriye çevirmek için 50 kez toplanıp ortalamasının alınması.
      delay(1);
     }  
     
  value=value/50; // Ortalama değer
  value=map(value, 0, 1023, 0, 180); // Analog girişten okunan değerin ESC nin anlayacağı değerlere çevrilmesi. 
  ESC.write(value);                    // Potansiyometreden gelen değere göre ESC / servo konumunu ayarlar. 
  Serial.print("Değer= ");
  Serial.println(value);
  }

he servo.h library of the arduino is used to run ESC. The operating principles of ESC and servos are the same. Both are controlled by PWM signal.
The value provided by the potentiometer from the analog input is between 0 and 1023. If we use these values ​​directly, we get inconsistent results. Therefore, with the “map” command, we convert this value minimum 0 and maximum 180 values ​​that the ESC will understand. This is the same for servo motors.

Bidirectional ESCs operate with a different value range than unidirectional. The level at which the motor stops is the midpoint. So 180/2 = 90 is theoretically the center point. Operation is provided in one direction between 90 and 180 and in the other direction between 90 and 0. Although its center point is 90 in theory, it may be slightly different in practice. For example, for the ESC and Motor combination seen in the picture above, the midpoint is between 72 and 82 and the motor will not operate between these values. This point can be easily detected since we can see the current value in the Serial Monitor when the potentiometer is turned right and left.

There is a “for” loop in the code. Operation is also provided without this cycle. However, with this cycle, the value from the analog input is summed 50 times and averaged and this results in a more stable study. The motor can make tiny movements on its own due to the occasional small data splashes, especially when the standby is at the mid-point, where the motor should not start. Since the average value obtained with the for loop is sent to the motor, we get rid of these tiny jumps. The reason for doing the cycle 50 times is that I have found it to be the most reasonable value as a result of the tests I have done. If more, I observed delays and interruptions in the command to the motor.

Arduino Bidirectional DC Motor Speed Control With Oled Screen Code:

#include <Servo.h>                       // Arduino Servo Library
#include <Wire.h>                        // Include Wire library
#include <Adafruit_GFX.h>                // Include Adafruit graphics library
#include <Adafruit_SH1106.h>             // SH1106 library
#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);
#if (SH1106_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SH1106.h!”);
#endif

int y;
String Durum;
Servo ESC;         // Object identification for esc

int long value;    // Variable for A1 pin data
void setup()
{
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);  
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.display();
  ESC.attach(3);  // Sending PWM signals from pin 3
}

void loop() { 
  
   for(int i = 0; i < 50; i++)
     {
      value=value+analogRead(A1); // To obtain a more stable result from the potentiometer data, collect 50 times and get the average
      delay(1);
     }  
     
  value=value/50; // Avarage value
  value=map(value, 0, 1023, 0, 180); // Converting the value read from the analog input to the values that the ESC will understand
  ESC.write(value); // ets the ESC / servo position according to the value from the potentiometer.

if(value<92) Durum = "< REVERSE";
if(value>102) Durum = "FORWARD >";
if(value>92 && value<104) Durum = "  CENTER";

if (value<100) y=55; else y=49;
 
  //display.setTextSize(1);
  display.setCursor(14,9);
  display.print(Durum);
  display.setCursor(y,39);
  display.print(value);
  display.display();
  display.clearDisplay();
  }