Motor with harmonic drive gets very hot!

Hi, first of all thank you so much for creating SimpleFOC. We started from zero and learned a lot from the resources provided, as well as from this forum. And we are still learning…

Our application is for knee exoskeleton for post-operation rehab. There will be times where the motor needs to lift the leg (angle mode) or the patient moves the leg independently (torque mode). Thus, backdrivability and the ability to change from mode to mode is important. Initially, we just use a small BLDC motor to get used to simplefoc, learn the codes to change in between modes etc. and we successfully did that. Our hardware: Arduino Mega + DRV8301 + AS5600 Magnetic encoder.

Then we bought a harmonic drive with custom-made motor from China, because we thought harmonic drive can increase the torque and able to be back-driven, suitable for our case. The harmonic drive has 1:50 reduction ratio. So with the new motor, we know we need to re-calibrate, finding PID and whatnot. This is where we faced the problem. The motor gets very hot, and draws 10A current in open-loop. Here is the video:

This is the motor spec (i tried to attach file but new user can only upload one):
rated voltage: 24V, rated current: 8A, rated peak current: 20A, rated power: 135W, no. of poles: 6

This is our code:

#include <SimpleFOC.h>
#define INH_A 9
#define INH_B 10
#define INH_C 11
#define EN_GATE 8
#define M_PWM 6
#define M_OC 5
#define OC_ADJ 7

BLDCMotor motor = BLDCMotor(5);
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);
MagneticSensorI2C sensor = MagneticSensorI2C(0x36, 12, 0x0E, 4);

float target = 10.0;

void serialloop() {
  static String received_chars;

  while (Serial.available()) {
    char inChar = (char);
    received_chars += inChar;
    if (inChar == '\n') {
      target = received_chars.toFloat();
      Serial.print("Target = ");
      received_chars = "";

void setup() {
  pinMode(M_OC, OUTPUT);
  digitalWrite(M_OC, LOW);
  pinMode(M_PWM, OUTPUT);
  digitalWrite(M_PWM, HIGH);
  pinMode(OC_ADJ, OUTPUT);
  digitalWrite(OC_ADJ, HIGH);
  driver.voltage_power_supply = 18;
  motor.voltage_limit = 5;
  motor.velocity_limit = 100;
  motor.voltage_sensor_align = 1;
  motor.torque_controller = TorqueControlType::voltage;
  motor.controller = MotionControlType::torque;

void loop() {



Also, we’re really disappointed to know that the harmonic drive has really high backdrive torque… the user won’t be able to move the leg independently. so we cannot use it for our knee exoskeleton =(… If anyone can suggest a better gear suitable for our case, that would be wonderful. Thanks in advance!

Openloop will use as much current as it can up to your voltage limit and i suspect the winding resistance of your motor is less than 0.5 ohms Try:
driver.voltage_limit = 2.0f;
motor.voltage_limit = driver.voltage_limit / 2.0f;
When you switch to closed loop, you’ll want to increase these limits (closed loop uses what it needs).

1 Like

Thanks for your prompt reply, Owen! We’ll try this and let you know the outcome

The number of poles from the motor spec is 6, but you set BLDCMotor(5)
It’s either 3 or 6 IMHO, depending if the specced no of poles refers to actual magnet count or pole_pairs. (Must be an inrunner then?)
You also set MagneticSensorI2C(0x36, 12, 0x0E, 4); which doesn’t make sense either. Why 4?

" If anyone can suggest a better gear suitable for our case, that would be wonderful."

I’m surprised to hear you can backdrive a 50:1 gear at all. To my knowledge, a ratio above 30:1 is considered selflocking.
IMHO, your only way out is to use a motor with higher pole count (pancake-style preferably) and lower gear ratio.

Hello back everyone!

Using Owen’s suggestion, the motor runs smoothly now without overheating! And we’re able to find the PID and do angle control (closed-loop).BTW, I tried pp 3 and 6 but somehow only pp 5 works. I’m guessing they had it wrong on the specs =/

Oh man… we need to go back to the drawing board then.

Thanks again everyone!

Harmonic gears aren’t good for back-driving, as you’ve found out…

Since you need a reduction for the torque, you could take a look a cycloidal gears, these are generally back-drivable, and yield high gear ratios, but mechanically a bit complicated and hard to make compact.

Planetary gears are probably the classic way to do it, and you can in fact buy pancake style BLDC motors with integrated planetary gearing. These are sometimes also called “quasi-direct-drive” actuators. Unfortunately they tend to be on the expensive side.

If you can change the orientation of the motor by 90°, there are also in-runner BLDCs with integrated gearing and also integrated encoders. Maxon, Portescap and Faulhaber would be companies that produce high-end products of this type, but you’ll also find less expensive models.

Since you’re already ordering custom motors from China I’m sure you’ll find what you need :slight_smile:

You may also be interested in capstan drives.

Please let us know how it goes, it sounds like a very cool project you’re working on!

Inrunners usually have a lower pole count and therefor high(er) kV than outrunners. Which means the gear ratio would have to be even higher ( maybe 2-3 gear stages required)
There’s also a catch regarding angled gears: Don’t go for worm drives if you want backdriveability and a decent efficiency.

Hi! I’m really learning a lot from this discussion. Wish i had it before going with the harmonic gears… the pancake motor did come to our mind initially. But the ones we found mostly use CAN bus communication which we have limited knowledge of. So back then we just decided to go with a ‘normal’ bldc and build up from there. But now it seems like better to straightaway start with a good expensive motor rather than wasting time and resources by buying different things when they did not work =( .

Nevertheless, we are learning a lot from this experience. thanks again for the suggestions… i will post more questions in future. A very supportive group here!