Help, Suggestions, and Advice

Hello,

I am pretty new to all this but learning fast on this steep learn but enjoying what I see and hope you guys have the knowledge to help me with my project.

I am looking to build a kind of servo motor using a BLDC, Its main requirement will be to take a PWM signal (standard RC spec or similar) and control a motors angle (less than 1 turn) at a fairly high speed ( full movement ideally less than 90ms) at a fairly high torque (not sure yet until I start testing)

As I said I am new here, but do have electrical and electronic knowledge (20 years working in Formula 1) and a small amount of coding knowledge ( done a few projects with Arduino Uno’s and Mega’s )

Any help, suggestions, and advice will be gratefully appreciated

Best Regards

Rollmop

Hello @Rollmop,

I think your idea should be possible! Especially with your experience!

The PWM input can be done and bldc motor can be controlled at an certain angle with SimpleFOC. The only thing is how much torque do you need! Because maybe you need a certain gearbox to reach the desired torque and then your speed will not be fast enough. Maybe you can tell us a bit more about the project because I am getting curious now! :slight_smile:

Also are weight and costs a relevant factor?

That is a very good and I believe achievable goal. Your best starting point may be checking out the existing body of work done by the MIT Cheeta v3, which updated their BLDC actuator to :

Gear Ratio 7.67
Max Torque 230 Nm
Max Joint Speed 21 Rad/s

The paper was published couple years ago and has all technical drawings and details inside.


One thing you may wish to reconsider however is using RC PWM as a servo control. At 50Hz frequency the signal density is way too low for such high speed servo you want to build. Usually the preferred comm protocols are ethercan, can, spi, usb or even high speed uart will be a lot faster than the 20ms rc pwm. The other issue with rc pwm is you get no feedback, its one direction only and you cannot receive telemetry.

thanks for the reply, The project is to control air pressure 2 to 3 bar hence the quick response is required

At the moment weight and cost are not major constraints but I am sure they will be factors later in the project. So lets say the total assembly should be sub 1 KG and be below $500.

Thanks for the replay,

Yes interesting what you say about RC PWM. I at the moment I am planning for feedback on another channel. A later development will be to have it on CAN but that is the next step

Thanks, that’s a bit clearer. So your use case is controlling an air pressure valve with a signal sending the angle to a bldc servo? Do you have the valve angular resistance torque force ? I mean N-m required to turn the valve ? Have you built the valve or you are building the valve yourself? Also is the motion just to turn the valve once and sit there for a prolonged time or the pressure must be controlled continuously to produce some pressure curve controlling something else?

hi there, yes we a producing a BLDC servo to control the position of the valve. At this stage, I am only getting to grips with the world of BLDC motor control (something which is new to me). We will be producing our own valve but the design is not finalised yet but we think the force will be around 0.5Nm.
our task is just to produce a valve to will open and close to setpoints give by the signal applied. The will be an outer control loop the will do the air pressure control but that is currently not part of this project.
it will be fairly dynamic as air flows and pressure requirements will be constantly changing.

I have one question, what is hindering you from using a normal rc servo for your valve?

True. An off-shelf fast DC servo might be sufficient, and RC PWM is OK for that.

1 Like

Hi
I’m trying do open loop control. While I’m using this code with values inside motor.move(), motor is running perfectly. But I cant control with serial monitor. I have to maintain the motor.move(target_postion) and change position values in the serial monitor. While I’m using the code with serial monitor the current is changing without motor running. What should I do for that? Can anyone help. I’m attaching the code below.

// Open loop motor control example
#include <SimpleFOC.h>

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(2);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);

//target variable
float target_position = 0;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_position, cmd); }
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }
void doVelocity(char* cmd) { command.scalar(&motor.velocity_limit, cmd); }

void setup() {

// driver config
// power supply voltage [V]
driver.voltage_power_supply =12;
// limit the maximal dc voltage the driver can set
// as a protection measure for the low-resistance motors
// this value is fixed on startup
driver.voltage_limit =6 ;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);

// limiting motor movements
// limit the voltage to be set to the motor
// start very low for high resistance motors
// currnet = resistance*voltage, so try to be well under 1Amp
motor.voltage_limit = 3; // [V]
// limit/set the velocity of the transition in between
// target angles
motor.velocity_limit = 5; // [rad/s] cca 50rpm
// open loop control config
motor.controller = MotionControlType::angle_openloop;

// init motor hardware
motor.init();

// add target command T
command.add(‘T’, doTarget, “target angle”);
command.add(‘L’, doLimit, “voltage limit”);
command.add(‘V’, doLimit, “movement velocity”);

Serial.begin(115200);
// motor.useMonitoring(Serial);
Serial.println(“Motor ready!”);
Serial.println(“Set target position [rad]”);

_delay(1000);
}

void loop() {
// open loop angle movements
// using motor.voltage_limit and motor.velocity_limit

motor.move(target_position);

// user communication
command.run();
}