# Position Control for BLDC motors

Hi,

I'm working on a project where I would like to drive a geared dc motor with hall sensors.

The material I have is the following:

If possible I would like to send angles as position commands. The motor driver takes an analog input range of 0 -10V and I want to map this to a range of angles (0° - 360°). I want to write a routine where it goes through different positions. For example, start at 0° then drive forward to 60°, then wait for 1 s then drive 30° in the backward direction and so on.

Unfortunately, I have no clue how to translate this into code. I have looked all over but all I can find is speed related. I know for servos there's a servo library where you can do a write() function to specify angles but I have seen this used with DC motors and there it translates to speed like in a continuous servo motor.

I'm grateful for any help!

brunnese:
If possible I would like to send angles as position commands. The motor driver takes an analog input range of 0 -10V and I want to map this to a range of angles (0° - 360°).

it sounds like you expect a specific voltage to move the motor to a specific anglular position. i don't believe that is how this motor works. the motor voltage controls motor torque and speed depending on the load.

i'm guessing that the hall sensor will pulse once for each rotation of the motor. with a 50:1 gearbox, this means every 7.2 degrees of the output shaft. the sensor doesn't indicate an absolute position, just relative changes. it would also be useful for measuring rpm.

for positioning the motor at a particular angle, some mechanism is needed to determine the starting position. a common approach would be to rotate the device to a zero position at startup. once at the starting position, sensor pulse can be used to track the output shaft position knowing the direction of the motor.

a stepper-motor would be much better suited for positioning.

What is the maximum torque and the maximum rpm that you need for this project?

Stepper-motordrivers can do 1/16 steps.
With 200 fullsteps per revolution this means 3200 steps/revolution.

A servomotor can do the job too. Professional servomotors have a rotaryy-encoder with 1000 up to 160.000 ! pulses per rotation. JMC has servomotors with a good price-perfomance ratio.

mech01 has some quite expensive but very precise continous rotation-servos

best regards Stefan

gcjr:
for positioning the motor at a particular angle, some mechanism is needed to determine the starting position. a common approach would be to rotate the device to a zero position at startup. once at the starting position, sensor pulse can be used to track the output shaft position knowing the direction of the motor.

Thank you for your help. I agree I somehow need to define a zero (e.g. mark a position) and always start from there. how do you translate that to code though? I couldn't find a function that lets you write a number of pulses to a pin...

brunnese:
I couldn't find a function that lets you write a number of pulses to a pin...

what do you mean "pulses to a pin"? do you mean PWM?

you would provide a voltage (PWM) to slowly rotate the motor back to a zero sensor and immediately stop when the sensor becomes active. this would presumably only be done once at startup.

do you expect to find a library with functions to do control this motor? these are that complicated.

StefanL38:
a stepper-motor would be much better suited for positioning.

What is the maximum torque and the maximum rpm that you need for this project?

Stepper-motordrivers can do 1/16 steps.
With 200 fullsteps per revolution this means 3200 steps/revolution.

A servomotor can do the job too. Professional servomotors have a rotaryy-encoder with 1000 up to 160.000 ! pulses per rotation. JMC has servomotors with a good price-perfomance ratio.

mech01 has some quite expensive but very precise continous rotation-servos
https://www.01mechatronics.com/product/hitec-hs-422-super-sport-supermodified-servo
https://www.01mechatronics.com/product/hitec-hs-311-standard-supermodified-servo

best regards Stefan

I can't change the motor because I need the acceleration which a stepper can't give me.
I need 70 rpm at 25 Nm and I need a motor that I can drive a 60 ° back and forth but can also rotate continuously at a speed of 70 rpm. That's why I chose a BLDC.

gcjr:
what do you mean "pulses to a pin"? do you mean PWM?

you would provide a voltage (PWM) to slowly rotate the motor back to a zero sensor and immediately stop when the sensor becomes active. this would presumably only be done once at startup.

do you expect to find a library with functions to do control this motor? these are that complicated.

I mean something like this:
BLDC_Motor::DC_Motor(int pin1,int pin2)
{
pinMode(pin1,OUTPUT);
pinMode(pin2,OUTPUT);
digitalWrite(pin1,LOW);
digitalWrite(pin2,LOW);
pin_1 = pin1;
pin_2 = pin2;
}
void BLDC_Motor::forward()
{
digitalWrite(pin_1,HIGH);
digitalWrite(pin_2,LOW);
}
this can be used to drive the motor forward. but I don't know how to tell it to which position. How do I tell the motor an angle and set pin 1 and 2 high and low and it knows it is an angle that I want and not a speed

consider the following code.

it demonstrates only some of the things i believe your code needs to do. it doesn't consider reversing the direction of the motor. it doesn't consider how to specify a position (presumable thru the serial interface).

presumably you're using an H-bridge and direction and enable signals.

i'm simulating using a button to simulate a pulse from a hall sensor LED brightness to simulate motor voltage.

moveToTarget() is a conventional approach using a routine that it repeatedly called with a target value that does what is necessary to reach that target. it simulates a pulse to a motor by pulsing an LED on for 1msec and off for 10 msec as long as the target and "hallCnt" are not the same.

monitorHall() simply increments hallCnt for each button press.

``````// motor controller with hall sensor

enum { On = LOW, Off = HIGH };

#define PinMotorDir 13
#define PinMotorEn  12

#define PinHall     A1

int  hallCnt = 0;

// -----------------------------------------------------------------------------
void  setup (void)
{
Serial.begin (9600);

digitalWrite (PinMotorDir, Off);
digitalWrite (PinMotorEn , Off);

pinMode (PinMotorDir, OUTPUT);
pinMode (PinMotorEn , OUTPUT);

pinMode (PinHall,    INPUT_PULLUP);
}

// -----------------------------------------------------------------------------
// simulates hall pulse used to increment hallCnt
void
monitorHall (void)
{
static byte hallLst = Off;

if (hallLst != hall)  {
hallLst = hall;

//      Serial.println (hall);
if (On == hall)  {
hallCnt++;      // +/- depends on motor direction
Serial.println (hallCnt);
}
}
}

// -----------------------------------------------------------------------------
// move motor until target reaches hallCnt
void
moveToTarget (
int   targ )
{
if (hallCnt < targ) {
digitalWrite (PinMotorEn, On);
delay (1);
digitalWrite (PinMotorEn, Off);
delay (10);
}
}

// -----------------------------------------------------------------------------
void loop (void)
{
monitorHall();
moveToTarget (2);
}
``````

Do you have a datasheet of the BLDC-motor?

how many pulses were created per revolution?

25 Nm at the output of the 1:50 gearbox means

25 / 50 ) 0.5 Nm on the motor-shaft. That is not too much

quite common steppermotors do have 3 Nm.
So a gearbox of 1:10 would create 30Nm.
for 70 rpm this means the stepper-motor runs at 700 rpm which is quite doable.
So what is the acceleration that you need for the 60 degree turns?

The question is: how much torque does the BLDC create when rotating at a lower speed for your 60 degree turns
A stepper-motor has the highest torque at low RPM.

a closed loop stepper-motor can do fast acceleration

best regards Stefan

brunnese:
Hi,

I'm working on a project where I would like to drive a geared dc motor with hall sensors.

The material I have is the following:

With 50:1 gearbox you'll get 12*50 = 600 steps per revolution (12 steps for the 4-pole motor, x50 for
the gearbox).

However note that the specs saying "50:1" doesn't guarantee that the ratio is exact, in fact its likely not
to be due to how gears are typically designed and specified - this may matter if you want to repeatedly

If possible I would like to send angles as position commands. The motor driver takes an analog input range of 0 -10V and I want to map this to a range of angles (0° - 360°). I want to write a routine where it goes through different positions. For example, start at 0° then drive forward to 60°, then wait for 1 s then drive 30° in the backward direction and so on.

Firstly you'll need to read the controller manual carefully to figure out the various ways to drive it,
note it mentioned 0-5V control as well as 0-10V which may be useful. Its programmed over MODBUS
so you'll probably need to use that to configure it. Not a simple project really.

Unfortunately, I have no clue how to translate this into code. I have looked all over but all I can find is speed related. I know for servos there's a servo library where you can do a write() function to specify angles but I have seen this used with DC motors and there it translates to speed like in a continuous servo motor.

I'm grateful for any help!

MODBUS libraries you will find I believe, and outputing analog is done using an RC filter on an
analogWrite pin.

gcjr:
it sounds like you expect a specific voltage to move the motor to a specific anglular position. i don't believe that is how this motor works. the motor voltage controls motor torque and speed depending on the load.

Rather than guess (wrong?) about the controller, I'd suggest reading its manual which clearly mentions position mode driven from a control voltage...

StefanL38:
Do you have a datasheet of the BLDC-motor?

The specs are linked to in the OP...

how many pulses were created per revolution?

Its a 4 pole 3-phase BLDC - that means 12 per motor revolution, so 600 per gearbox
output shaft revolution

25 Nm at the output of the 1:50 gearbox means

25 / 50 ) 0.5 Nm on the motor-shaft. That is not too much

No it doesn't quite mean this, it means the gears are rated to 25Nm for momentary periods,
and its 15Nm continuous (given in the specs). The efficiency of the gears may be
as low as 60% or so for a multistage planetary gear, so expect less performance than
naive calculation suggests.

For large reduction ratios the mechanical limits of the gears often dominate the output
torque rating, in fact its not impossible to destroy a gearmotor if the motor torque isn't
limited by the controller for whats safe for the geartrain. Here the gears appear to be
well matched and will handle the nominal output of the motor (just). They may not
handle motor stall torque though - a trap for the unwary.

The motor itself is 220W, 0.6Nm, 3500rpm, clearly given in the specs in that link.

220W is a lot more power than any stepper I've seen, if you need that torque at speed,
a stepper won't be a plausible substitute to this servomotor.

quite common steppermotors do have 3 Nm.

That's hold-in torque, dynamic torque is much less, perhaps 10 times less at full speed.
That's a large NEMA23 or more likely NEMA34 too.

So a gearbox of 1:10 would create 30Nm.

Not at speed though, only for holding fast.

for 70 rpm this means the stepper-motor runs at 700 rpm which is quite doable.
So what is the acceleration that you need for the 60 degree turns?

The question is: how much torque does the BLDC create when rotating at a lower speed for your 60 degree turns
A stepper-motor has the highest torque at low RPM.

DC motors, brushed or brushless, have the basically same torque at any speed as its set by the current.

a closed loop stepper-motor can do fast acceleration

If you need high acceleration a proper industrial servomotor (long thin rotor) is the way to
go as these have the lowest inertia to torque ratio.

best regards Stefan

MarkT:
With 50:1 gearbox you'll get 12*50 = 600 steps per revolution (12 steps for the 4-pole motor, x50 for
the gearbox).

However note that the specs saying "50:1" doesn't guarantee that the ratio is exact, in fact its likely not
to be due to how gears are typically designed and specified - this may matter if you want to repeatedly
return to the same angle after turning revolutions.Firstly you'll need to read the controller manual carefully to figure out the various ways to drive it,
note it mentioned 0-5V control as well as 0-10V which may be useful. Its programmed over MODBUS
so you'll probably need to use that to configure it. Not a simple project really.MODBUS libraries you will find I believe, and outputing analog is done using an RC filter on an
analogWrite pin.

i read the manual of the driver very carefully and from what I understood I can either do analog input via a voltage or modbus. So I only want to do analog input as modbus sounds too complicated. I just don't know how I can send an actual position command, like the precise code for it or if it would work with the servo library.