Controlling 8 BLDC motor with arduino

So we are building an autonomous underwater vehicle and currently i am writing manuel test code. I wrote the code but i cant try for now bcs of the shipping delay.
I wanna be sure that code is working when components are came.
Can you look at my code please and give feedback, i am new on embedded system programming.
(THIS IS MAIN CODE BLOCK)
int potX= A0;
int potY= A1;
void setup() {
initializeMotor()

Serial.begin(9600);
pinMode(potX, INPUT);
pinMode(potY, INPUT);
initializeMotor();
}
void loop() {
potX=analogRead(A0);
potY=analogRead(A1);
int pwmOutputX=map(potX,0,1023,0,180);
int pwmOutputY=map(potY,0,1023,0,180);

if (pwmOutputY>=95 && pwmOutputY<=180)
{
ileri();
}
if (pwmOutputY<=85 && pwmOutputY>=0)
{
geri();
}
if (pwmOutputX>=95 && pwmOutputX<=180)
{
sag();
}
if(pwmOutputX<=85 && pwmOutputX>=0)
{
sol();
}
if ((pwmOutputY>=86 && pwmOutputY<=94) && (pwmOutputX>=86 && pwmOutputX<=94))
{
dur();
}

Serial.println(pwmOutput);
delay(1000);
}

[THIS IS FUNCTIONS TAB ]
#include <Servo.h>
//fonk içine alınabilir…
Servo escsolOn;
Servo escsagOn;
Servo escsolArka;
Servo escsagArka;
const int solOn=11;
const int sagOn=10;
const int solArka=6;
const int sagArka=5;

void initializeMotor(){
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);

escsolOn.attach(11,1550, 2000);
escsagOn.attach(10,1550, 2000);
escsolArka.attach(6,1550, 2000);
escsagArka.attach(5,1550, 2000);
}

//motorlar ileri
void ileri(){

digitalWrite(solOn,HIGH);
digitalWrite(sagOn, HIGH);
digitalWrite(solArka, HIGH);
digitalWrite(sagArka, HIGH);
analogWrite(solOn,potY);
analogWrite(sagOn,potY);
analogWrite(solArka,potY);
analogWrite(sagArka,potY);
escsolOn.write(pwmOutputY);
escsagOn.write(pwmOutputY);
escsolArka.write(pwmOutputY);
escsagArka.write(pwmOutputY);

}

//motorlar geri
void geri(){

digitalWrite(solOn,HIGH);
digitalWrite(sagOn, HIGH);
digitalWrite(solArka, HIGH);
digitalWrite(sagArka, HIGH);
analogWrite(solOn,-potY);
analogWrite(sagOn,-potY);
analogWrite(solArka,-potY);
analogWrite(sagArka,-potY);
escsolOn.write(pwmOutputY);
escsagOn.write(pwmOutputY);
escsolArka.write(pwmOutputY);
escsagArka.write(pwmOutputY);
}

//motorlar sağa
void sag()
{

digitalWrite(solOn,HIGH);
digitalWrite(sagOn, LOW);
digitalWrite(solArka, HIGH);
digitalWrite(sagArka, LOW);
analogWrite(solOn,potX);
analogWrite(solArka,potX);
escsolOn.write(pwmOutputX);
escsolArka.write(pwmOutputX);

}
void sol()
{
digitalWrite(solOn,LOW);
digitalWrite(sagOn, HIGH);
digitalWrite(solArka, LOW);
digitalWrite(sagArka, HIGH);
analogWrite(sagOn,potX);
analogWrite(sagArka,potX);
escsagOn.write(pwmOutputX);
escsagArka.write(pwmOutputX);
}

void dur()
{
digitalWrite(solOn,LOW);
digitalWrite(sagOn,LOW);
digitalWrite(solArka,LOW);
digitalWrite(sagArka,LOW);
analogWrite(solOn,0);
analogWrite(sagOn,0);
analogWrite(solArka,0);
analogWrite(sagArka,0);

}

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code

I’m surprised to see you using analogWrite on servos. What kind are they?

1 Like

You seem to be doing servo.write()s and digitalWrite()s and analogWrite()s all to the same 4 pins which seem to have 4 ESCs connected (not 8 as your subject suggests). I can’t work out what you are trying to do.

Please post a schematic showing what is actually connected where and how everything is powered.

Steve

1 Like

Thanks for your reply steve,
Yes i am using 4 bldc for testing but just for now, i was thinking if i build 4 bldc once i could write code of the other 4 bldc easily.
I don’t have electric knowledge, my friend is doing all electrical stuff and i am coding.
So these 4 bldc are for forward, backward, right and left movement and the other 4 will using the height motors with PID.

Why? Is that a problem, i am very new on this but it worked on 1 BLDC motor

As @slipstick has pointed out you do some odd things on the servo output pins.

If this works, it is because the last thing you do on the solOn pin (write to the servo object) quickly overrides the first two.

It may work, but at the very least it clutters up your code. It seems like in every case you are doing three things on a servo, the first two of which are unnecessary.

In the cases where you

digitalWrite(solOn,LOW);

It would be clearer to

escsolOn.write(0);

a7

1 Like

Thanks for your reply @alto777 ,
so you guys are saying:
digitalWrite(solOn,HIGH), analogWrite(solOn,potY) and escsolOn.write(pwmOutputY) are doing same thing.
How stupid i am, i will use joystick for control speed and which motor should work so i have to use pwmOutputX and pwmOutputY values, if i just write escsolOn.write(pwmOutputY) for every movement (pwmOutputX when necessary) can code work?

No, they do different things, but only the last one is acted upon if you use them in turn

1 Like

Yes, no.

They are doing three different things.

  1. The digital write HIGH just kills the PWM signal to the servo.

  2. The analog write potY sets up a PWM signal according to the unmapped value

And

  1. the escsolOn.write(pwmOutputY) is using the servo library and results in the mapped value being used for PWM, but you don’t see it explicitly because you use a library.

So the first is useless, the second is wrong and the third is what (and all!) you need.

In all cases of an attached object like a servo, it is usual to talk to it through, and only through, the mechanisms that are offered in the library you are using.

HTH and good luck!

a7

1 Like

Thank you @alto777 ,
i will use that but i have one last question, so i am using servo.h library, i am wandering is it problem to use for BLDC motors. If i don’t use servo.h, can analogWrite(pwmOutputY) work like escsagOn(pwmOutputY) ?

I have used BLDC motors with the Arduino, but in between them there is an ESC. These are common in the r/c hobby and are meant for three wire motors.

Most ESCs respond to old fashioned PWM just fine. I do not recall if I used the (a) servo library but I am thinking that yes, probably I did.

The servo library should provide the correct 50 Hertz signal varying between 1 and 2 millisecond pulse width.

There is a step you should not overlook, and that is calibration. There is a little dance you can perform that will set the upper and lower limits you feed it into the ESC memory.

I’ll look later, I do believe that I supplied some crude but effective code that runs on an Arduino that accomplish this.

Promise? :wink:

No problem ever, keep asking questions!

a7

1 Like

Thank you so much :slight_smile:
You are the best, when i finished my final project i’ll send a message and i will be better than now ahahahah

The forum search tools work…

a7

1 Like

Probably not. Most ESCs expect a specific signal around 50Hz with a duty cycle that only varies between 5% and 10%. Normal PWM works at around 10 times that frequency and with duty cycle between 0% and 100%.

With a lot of fiddling around you might make it work but I can’t imagine why on earth you would want to.

Steve

1 Like

I’ll use this calibration method when my power supply came, and i adjust my code thanks to you :blush:
So can you please take a look? eheheh…`
Addition: i am wandering if i release the joystick, can my motor stops?

**This Tab is for function define**
#include <Servo.h>

void esc(){
Servo escLeftFront;
Servo escRightFront;
Servo escLeftBack;
Servo escRightBack;

//define escs to pins and min, max values (i will calibrate with your method)
escLeftFront.attach(11,1550, 2000);
escRightFront.attach(10,1550, 2000);
escLeftBack.attach(6,1550, 2000);
escRightBack.attach(5,1550, 2000);

//gived min value
escLeftFront.write(0);
escRightFront.write(0);
escLeftBack.write(0);
escRightBack.write(0);
}
//Activating all the motors to going forward or backward for vehicle based on joystick 
void y_axis(){
 escLeftFront.write(pwmY);
escRightFront.write(pwmY);
escLeftBack.write(pwmY);
escRightBack.write(pwmY);
}

//activating left front and left back motors to turn right based on joystick
void right(){
  escLeftFront.write(pwmX);
  escLeftBack.write(pwmX);
}

//Activating right front and right back motors to turn left based on joystick
void left(){
  escRightFront.write(pwmX);
  escRightBack.write(pwmX);
}
**This tab is main**
#include<Servo.h>
//define x,y values for joystick
const int potX=A0;
const int potY=A1;

void setup() {

Serial.begin(9600);

pinMode(potX,INPUT);
pinMode(potY,INPUT);
esc();

}

void loop() {
//wait for values
if (Serial.available() > 0)
{
  potX=analogRead(A0);
  potY=analogRead(A1);
//map for pwmX and pwmY outputs
  int pwmX=map(potX,0,1023,0,180);
  int pwmY=map(potY,0,1023,0,180);
  
// Y axis movement function
  y_axis();
//right movement
  if(pwmX>=95 && pwmX<=180)
  {
  right();
  }
//left movement
  else if (pwmX>=0 && pwmX<=94)
  {
  left();
  }
}
//write pwmX and pwmY values to console
Serial.print(pwmX);
Serial.print(pwmY);
delay(1000);
}

Well, there’s a lot to say, I don’t know where your joysticks end up, I assume in the middle, I’ll look closer.

While I was in there poking around, I see already a number of things to change or fix:

const int potX = A0;

means potX is your name for the A0 pin. It will never change. So this will be an compiler error or warning or simply not work here:

potX = analogRead(A0);

You need an additional non-const variable to collect the analogRead, and the whole point of the potX thing is so you can refer to the pin by a meaningful name, viz:

const int potXPin = A0;
int potXPosition; 
.
.
.
    potXPosition = analogRead(potXPin);

And

What’s going on with this?

if (Serial.available() > 0)

If you are using it to wait until you press a key, at some point you are going to have to Serial read that key or available will be forever true.

And this looks random

escLeftFront.attach(11, 550, 2000);

Usually servos run from 1000 to 2000. Where did you get 1550?

Last problem (!), well, another I see just now is not a problem, but a redundancy that clutters your code

if (pwmX >= 95 && pwmX <= 180)

is the same as

if (pwmX >= 95)

because the map function, as you have called it, will already mean pwmX is <= 180.

Style note: you may have noticed I put spaces into your expressions. They are not required by the syntax, but they can (do!) make code are eye-friendly.

For sure never think that squeezing things together makes them happen differently as far as operator precedence is concerned. The spaces, any whitespace, is not considered by the compiler.

a7

1 Like

I did all what you said and i am so appreciated, maybe you guessed i have a big ADHD :joy: i am laughing to my mistakes but yeah from now i will care my code.
BTW i will pay attention order of my codes.
When it be working on the pool i’ll upload photo :blush: