BLDC motor as a spiral spring

Hello everybody, I have just discovered simpleFOC, and I think it could be very useful for my project. I’m planning to build a small roller shutter and considering using a BLDC motor to roll it up and apply a constant torque to keep it taut. Currently, I’m using a spiral spring, but I require precise and constant torque over the entire travel, and it would be ideal if this torque could be adjusted based on the weight of the shutter.

My question is, can this be achieved with a BLDC gimbal motor and simpleFOC? Or are there potential problems with motor overheating or control difficulties? I would appreciate any feedback before I start purchasing all the required components.

Welcome to the forum.

Yes it is possible. Yes overheating would be an issue.

As @Valentine said, this is possible. I do something similar for an application I have. You should ensure you can have closed loop current control working, as being able to decouple speed and torque while limiting current may be needed, depending on your exact setup.

Thank you @wrcman555 and @Valentine for your response.
@wrcman555 did you experience any overheating issues? I would love to learn more details about your application, if you are able to share, such as the driver and motor being used and the level of complexity involved in achieving the desired control.

I’m fairly inexperienced with electronics, but I just wanted to add that it’s possible that overheating might not be an issue depending on various factors. If the amount of torque the motor needs to apply while motionless is very small, it’s possible that it’ll be able to dissipate the heat just fine.

You might be assuming it’ll generate a lot of heat because that’s what happens with other setups when motors stall, but that doesn’t apply with FOC. Simpler setups depend on back EMF for regulation, which goes away when the motor stalls, so they draw full power and burn out motors. With FOC the power is being measured and regulated even while stalled, so the heat it generates will be proportional to the torque generated. So if you’re trying to hold a garage door open with a tiny gimbal motor, it’s not going to work, but something like a tiny fabric shutter seems totally possible.

If aliexpress sellers actually listed detailed specs for their motors, you’d be able to calculate how much heat you’d be generating in Watts and then select a motor capable of that heat dissipation rate, but instead you’ll probably have to experiment with different motors.

1 Like

@super

I used the DRV8302 board from AliExpress in conjunction with a Nucelo F401RE board to control a moderate size industrial AC servo motor. I used an AS5048A magnetic position sensor for closed loop feedback, and controlled the Iq (torque producing current) as a function of the motor shaft angle. The code is quite simple - you can dynamically set the motor torque in the main loop as a function of shaft angle. I was able to produce several Nm of torque using the setup, and the DRV8302 board is capable of ~15 A of current, which was plenty for me.

Thank you @bob for your explanation. I will investigate the overheating of the motor experimentally, as the torque requested to keep the shutter taut is small.

@wrcman555
Thank you. The setup is similar to what I have in mind. I’m planning to use a Teensy 4.1 (which has 35 PWM pins) to control four DVR8302 boards. I’m currently calculating the torque needed so I can choose a motor to test with. The motors will probably have integrated hall sensors, but I’m wondering if that will be enough for this control, or if I need an external encoder?

Regarding the programming, in my application the shaft needs to complete three revolutions and the torque needs to increase continuously as the shutter unrolls (in order to keep it taut), and increase by 2-3 times when the shutter changes direction to roll up. Is this obtainable controlling the torque as a function of the shaft angle? It also has to consider direction of the shutter.

For clarity, the shutter is moved manually, the motor just need to keep it taut and facilitate the roll-up

Please keep in mind that running simpleFoc is somewhat computationally intensive and only works properly if the loop is able to run fast enough. The teensy is a pretty powerful board but running four DVR8302 drivers, which means running four instances of simpleFoc, might be too much and loop times might grow too long to be effective. If a board is supported by simpleFoc and has spare capacity the only way to know for sure how many instances it can run is to find someone with the same setup who made it work or to just try yourself.

This doesn’t yet cover the requirements for the boards peripherals, you already said you have enough PWM pins but you should also check if you have enough timers to drive them and (if you use current sensing with the internal ADC) if you have enough ADC capacity (enough pins connected to the ADC and a fast enough ADC or multiple ADCs to read them at a high enough frequency) to do the sensing for four driver boards.

Thank you @bartios for pointing out this possibility.
I’ve already bought the DVR8302 and Teensy 4.1, so I am going to try to see how much I can get from the hardware I have. As for the timers and ADC, the board seems to have plenty, but I am not sure if there are any limitations or incompatibilities when using them all together. Perhaps someone in this forum has already experimented with the Teensy and can provide some advice on its performance and capabilities.

Hello everyone,
I’m currently working on this project and would like to switch to a stepper motor. I’ve set up a test configuration with a Nema17 stepper motor, an L298N driver, an AMT103v incremental encoder, and the Teensy 4.1. Essentially, I followed the stepper motor example project on the SimpleFOC website.

The encoder is working perfectly, but I’m encountering issues with the stepper motor—it remains stationary, and when I try to rotate the shaft, it skips steps.

Is there someone kind enough to help me set up this test project? I’m sure I’m missing something stupid that I can’t find out…

Here is the code I’m using:

#include <SimpleFOC.h>

// Stepper motor instance
StepperMotor motor = StepperMotor(50);
// Stepper driver instance
StepperDriver4PWM driver = StepperDriver4PWM(2, 3, 6, 9,  7, 8);

// encoder instance
Encoder sensor = Encoder(10, 11, 2048);
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}



// commander interface
Commander command = Commander(Serial);
void onMotor(char* cmd){ command.motor(&motor, cmd); }

void setup() {

  // use monitoring with serial for motor init
  // monitoring port
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);

  // initialize encoder sensor hardware
  sensor.init();
  sensor.enableInterrupts(doA, doB); 
  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // choose FOC modulation
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.init();
  // link the motor to the sensor

  Serial.print("Driver init ");
// init driver
if (driver.init())  Serial.println("success!");
   else{
  Serial.println("failed!");
  return;
}
  motor.linkDriver(&driver);

  // set control loop type to be used
  motor.controller = MotionControlType::torque;

  // controller configuration based on the control type 
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 12;

  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;

  // angle loop controller
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 50;


  // initialise motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();

  // set the initial target value
  motor.target = 2;

  // define the motor id
  command.add('M', onMotor, "motor");

  // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
  Serial.println(F("Motor commands sketch | Initial motion control > torque/voltage : target 2V."));
  
  _delay(1000);
}


void loop() {
  // iterative setting FOC phase voltage
  motor.loopFOC();

  // iterative function setting the outter loop target
  // velocity, position or voltage
  // if tatget not set in parameter uses motor.target variable
  motor.move();

  // user communication
  command.run();

If it skips steps, it’s because there is too much torque. It should make a hammering or buzzing sound, if it’s rotating sporadically one of the phases could be not working right. Rememeber you can only accelerate so fast, because the acceleration itsself implies considerable force. Once it starts skipping it tends to continue.

I used a servo motor I got on amazon recently when I needed a substitute for a spring. Brushless 24 volt dc servo motor.

Designing a complete servo motor with printed components etc. would be a good undertaking that I have considered but I never needed to do it as these servo motors did what I needed.

Hello, can you share the setup you built? Which driver, motor, and encoder did you use?

All you have to do is figure out the pinouts of the motor. You just give the motor a PWM signal, and it gives you torque. I found you have to toggle the direction pin every half a second or so or the motor gives up (it detects the stall condition) which I did just by feeding it a very low duty cycle PWM signal.

My code is all in micropython. Also I didn’t bother to read the encoder, but if you wanted to read it and then apply more or less torque depending on the rotational position (including over multiple rotations), then that would be just like a spring. I was able to get quite a range of torque. I smoothed out the cogging of the motor using a spring I printed, I can take a picture in a minute or two.

edit: pics, including the motor pinout, it may be slightly different for some motors but probably not: Shared pics - Google Drive
there is a dir, pwm, encoder a and encoder b and 5 volts and a start/stop and ground. Some are active high, some active low, and you have to supply 5 volts to the 5 volt pin or nothing works quite right. It accepts 3.3 volt logic.

oh you also need the little connector, if you go that route I can dig them up from my digikey history.