Need to make bldc motor neutral when moving from forward to reverse and vice versa

Hi ...
I HOPE THAT YOU ARE DOING WELL.
I just want to add a brake/stop (NEUTRAL) for one or two seconds when the two BLDC motors will move from forward to reverse and vice versa. I tried to make changes but nothing works; Also I am not good in a coding.

Here is the code: Please check it

#include <Servo.h>
const int m_1 = 2; //CHANGE THE PIN TO 5
const int m_2 = 3; //CHANGE THE PIN TO 6
const int LED = 13;

// BATTERY READINGS VARIABLES
const int Battery = A0;
float Voltage = 0.0; // input battery voltage
float Voltage1 = 0.0; // output voltage for analog pin A0
float R1 = 1581; // R1 1581, 1597
float R2 = 1000; // R2 1000, 1000
int readValue = 0;
long previousMillis_battery = 0;
byte Bat_start_timer = 0;
unsigned long battery_wait = 0;
unsigned long currentMillis = 0; // VALID FOR ALL FUNCTIONS(COUNTER)

// BATTERY FUNCTION
void battery() {
  readValue = analogRead(Battery);
  Voltage1 = readValue * (5.0 / 1023.0);
  Voltage = Voltage1 / (R2 / (R1 + R2));
  if (Bat_start_timer == 0)
    battery_wait = 60000;
  if (currentMillis - previousMillis_battery > battery_wait) {
    Serial.print("$ABC,"); Serial.print(Voltage); Serial.print("V"); Serial.print('\n');

    previousMillis_battery = currentMillis;
    battery_wait = 60000;
    Bat_start_timer = 1;
  }
  currentMillis = millis(); // to monitor/print voltages on a serial monitor

} // battery FUNCTION END

String strID = "";
int BaudRate = 4800;
Servo ESC_1; // create servo object to control the ESC 1
Servo ESC_2; // create servo object to control the ESC 2
#define FWD 0
#define BWD 1

unsigned int FORWARD = 2000;
unsigned int NEUTRAL = 1500;
unsigned int REVERSE = 1000;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
unsigned int APwm = NEUTRAL;
unsigned int BPwm = NEUTRAL;

boolean ADirection = FWD;
boolean BDirection = FWD;

int CurrentAPwm = NEUTRAL;
int CurrentBPwm = NEUTRAL;

unsigned int AVelocity = 0; // CURRENT VELOCITY OF M1 in 0-100%
unsigned int BVelocity = 0; // CURRENT VELOCITY OF M2 in 0-100%

String inputString = ""; //a string to hold incoming data
int TaskNumber = 0;

// FOR 2-SECONDS TIMER
uint32_t msgTimeout = 0ul;
uint32_t timeNow;



unsigned int GetValue(void)// fetch three digit number value from received string and convert to INTEGER
{
  unsigned int Val = 0;
  Val = (inputString[3] - 48) * 100;
  Val = Val + (inputString[4] - 48) * 10;
  Val = Val + (inputString[5] - 48);
  return (Val);
}

void setup()
{
  Serial.begin(BaudRate);
  ESC_1.attach(m_1);// (pin, min pulse width, max pulse width in microseconds)
  ESC_2.attach(m_2);// (pin, min pulse width, max pulse width in microseconds)
  pinMode(LED, OUTPUT);
  pinMode(Battery, INPUT);
  Serial.println("ABC System Started");
  ESC_1.writeMicroseconds(APwm);
  ESC_2.writeMicroseconds(BPwm);
}

boolean AFwdFlag = 0; // makes sure that the serial only prints once the state
boolean BFwdFlag = 0;

void loop()
{

  // battery-send
  static int runit;
  if (runit == 1000) {
    battery();
    runit = 0;
  }
  runit++;

  // 2 SECONDS TIMER CODE STARTS
  timeNow = millis();
  serialEvent();

  if (TaskNumber == 0) {
    //  if we've gone 2-seconds...
    if ((timeNow - msgTimeout) >= 2000ul)
    {

      APwm = NEUTRAL;
      BPwm = NEUTRAL;

    } // if
  } // if

  if (TaskNumber) {

    // each pass where we see a non-zero task #, reset the msgTimeout value
    msgTimeout = millis();
    digitalWrite(LED, LOW);


    if (TaskNumber) {
      if (TaskNumber == 1) Serial.println("OK");
      if (TaskNumber == 2 || TaskNumber == 4) {
        ESC_1.writeMicroseconds(NEUTRAL);
      }
      if (TaskNumber == 3 || TaskNumber == 4) {
        ESC_2.writeMicroseconds(NEUTRAL);
      }
      // 2 SECONDS TIMER ENDS

      if (TaskNumber == 5 || TaskNumber == 7) {
        if (ADirection == FWD) {
          APwm = NEUTRAL + (((FORWARD - NEUTRAL) / 100) * AVelocity);
          AFwdFlag = 1;
        }
        else {
          if (AFwdFlag == 1)
          {
            // Need help to make some changes here to make motor A stop for 2 seconds when moving from forward to reverse and vice versa.
            ESC_1.writeMicroseconds(NEUTRAL); delay(100);
            ESC_1.writeMicroseconds(REVERSE); delay(100);
            ESC_1.writeMicroseconds(NEUTRAL); delay(100);
            AFwdFlag = 0;
          }
          APwm = NEUTRAL - (((NEUTRAL - REVERSE) / 100) * AVelocity);

        }
      }


      if (TaskNumber == 6 || TaskNumber == 7) {
        if (BDirection == FWD) {
          BPwm = NEUTRAL + (((FORWARD - NEUTRAL) / 100) * BVelocity);
          BFwdFlag = 1;
        }
        else {
          if (BFwdFlag == 1)
          {
            // Need help to make some changes here to make motor B stop for 2 seconds when moving from forward to reverse and vice versa.
            ESC_2.writeMicroseconds(NEUTRAL); delay(100);
            ESC_2.writeMicroseconds(REVERSE); delay(100);
            ESC_2.writeMicroseconds(NEUTRAL); delay(100);
            BFwdFlag = 0;
          }
          BPwm = NEUTRAL - (((NEUTRAL - REVERSE) / 100) * BVelocity);

        }
      }


      TaskNumber = 0;

    }
  }

  //Increment and Decrement for both motors
  if (APwm > CurrentAPwm)
  {
    CurrentAPwm ++;
    ESC_1.writeMicroseconds(CurrentAPwm);


  }
  if (APwm < CurrentAPwm)
  {
    CurrentAPwm --;
    ESC_1.writeMicroseconds(CurrentAPwm);


  }
  if (BPwm > CurrentBPwm)
  {
    CurrentBPwm ++;
    ESC_2.writeMicroseconds(CurrentBPwm);

  }
  if (BPwm < CurrentBPwm)
  {
    CurrentBPwm --;
    ESC_2.writeMicroseconds(CurrentBPwm);


  } //end


}


// <AN> <A+xxx> <A-xxx>
// <BN> <B+xxx> <B-xxx>
// <CN> <C+xxx> <C-xxx>

void serialEvent() {

  while (Serial.available()) {   //while a char is holding in the serial buffer //get the new char

    char inChar = (char)Serial.read(); //get the character we just received
    inputString += inChar;  //add it to the inputString

    if (inChar == '\r' || inChar == 10)  //if the incoming character is a Carriage Return \ //set the flag
    {

      if (inputString[0] == '<')
      {

        if (inputString[1] == 'A' && inputString[2] == 'T' && inputString[3] == '>' ) TaskNumber = 1; // AT

        if (inputString[2] == 'N' && inputString[3] == '>' )
        {
          if ( inputString[1] == 'A') TaskNumber = 2; // Set Motor A to Neutral
          if ( inputString[1] == 'B') TaskNumber = 3; // Set Motor B to Neutral
          if ( inputString[1] == 'C') TaskNumber = 4; // Set Both Motors to Neutral
        }

        if (inputString[6] == '>' )
        {

          if ( inputString[1] == 'A') {
            if (inputString[2] == '+') ADirection = FWD; else ADirection = BWD;
            AVelocity = GetValue();
            TaskNumber = 5;
          }

          if ( inputString[1] == 'B') {
            if (inputString[2] == '+') BDirection = FWD; else BDirection = BWD;
            BVelocity = GetValue();
            TaskNumber = 6;
          }

          if ( inputString[1] == 'C') {
            if (inputString[2] == '+') {
              ADirection = FWD;
              BDirection = FWD;
            }
            else {
              ADirection = BWD;
              BDirection = BWD;
            }
            AVelocity = GetValue();
            BVelocity = GetValue();
            TaskNumber = 7;
          }

        }

      }
      inputString = "";   //clear the string
    }
  }
}

Nice job on the code. Can you post a schematic, not a frizzy picture showing all the connections including power and ground. Also post technical links to the Hardware devices. I will take a SWAG and say if you actively drive the motor leads high or low it will act as a break.

1 Like

That's a lot of code to try to read through when "nothing works". Perhaps you can say exactly what changes you have made and exactly what nothing works means to you.

Steve

1 Like

you can simply try by uploading this code to the Arduino and run the motors by giving commands in a serial monitor such as <C+010>, ….. <C+100> in a forward direction and , …. in a reverse direction and <C+000> to stop the motors.

Its a simple motors connection; I am using a BLDC motors by connecting their signal pins to the Arduinos pin no 2 and 3 and controlling their speed by giving a commands.

1 Like

I just want to add a BRAKE for one or two seconds when the motors will move from forward to reverse direction and vice versa.

I think you mean you mean you are using BLDC motors and ESCs. What motors? What ESCs?

You need to provide information.The chances of any of us having exactly the same setup as you to do your testing for you is almost zero.

Steve

I am using these BLDC motors with ESCs ....
Its a FATJAY KYO 15T- 24 Volts ....

Please see the following link.

[https://www.aliexpress.com/i/1005001660790311.html]

if you don't have a BLDC motors then maybe you can try with a simple DC motor as well.

I made some changes in a code that works when both the motors moved from forward to reverse but it does not work I mean stop for some instance 300ms when it moved from reverse to forward direction.

Here is the code

if (TaskNumber == 5 || TaskNumber == 7) {
      if (ADirection == FWD) {
        APwm = NEUTRAL + (((FORWARD - NEUTRAL) / 100) * AVelocity);
        AFwdFlag = 1;

      }

      else {
        if (AFwdFlag == 1)
        {

          ESC_1.writeMicroseconds(NEUTRAL);
          delay(300); // After making a motor neutral; this delay works means motor A stops for 300ms when moving from forward to reverse direction
                      // but it does not stop when moving from reverse to forward direction.
          AFwdFlag = 0;
        }


        APwm = NEUTRAL - (((NEUTRAL - REVERSE) / 100) * AVelocity);

      }
    }


    if (TaskNumber == 6 || TaskNumber == 7) {
      if (BDirection == FWD) {
        BPwm = NEUTRAL + (((FORWARD - NEUTRAL) / 100) * BVelocity);
        BFwdFlag = 1;
      }

      else {
        if (BFwdFlag == 1)
        {
          ESC_2.writeMicroseconds(NEUTRAL);
          delay(300);  // After making a motor B neutral; this delay works means motor B stops for 300ms when moving from forward to reverse direction
                      // but it does not stop when moving from reverse to forward direction.

          BFwdFlag = 0;
        }


        BPwm = NEUTRAL - (((NEUTRAL - REVERSE) / 100) * BVelocity);

      }
    }

Best Regards,
Mubashir

did you try the code ?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.