Motor not spinning, only vibrating... hall sensor interrupt not working?

Hi all!

I have a problem concerning my setup with a BLDC motor and an Arduino Due running the SimpleFOC lib (V2.2.2).
Here is a block diagram of my setup:
Block diagram setup_V2_tmp

My problem now is, that the initialization fails. It says “Failed to notice movement”. The motor shaft is moving about a quarter revolution forth and back multiple times and then stops. On each motor phase I can measured a PWM signal with varying duty cycle and the hall encoders are working perfectly (high or low depending on the rotor position directly measured at the Arduino input). When skipping the initialization the motor is still just vibrating forth and back.
I also tried to turn the shaft manually while initializing, which also fails most of the time. It looks like the hall sensor can’t be read in…

This is my main code:

#include <SimpleFOC.h>

#define PIN_PWM1  2
#define PIN_PWM2  3
#define PIN_PWM3  4
#define PIN_HALL1 7
#define PIN_HALL2 5
#define PIN_HALL3 6 

#define NUM_POLES 4

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(NUM_POLES);
BLDCDriver3PWM driver = BLDCDriver3PWM(PIN_PWM1, PIN_PWM2, PIN_PWM3);

// hall sensor instance
HallSensor sensor = HallSensor(PIN_HALL1, PIN_HALL2, PIN_HALL3, NUM_POLES);

// Interrupt routine intialisation
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}

// velocity set point variable
float target_velocity = 0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }


void setup()
{
  sensor.pullup = Pullup::USE_INTERN;                 // use internal pullup for hall inputs
  sensor.enableInterrupts(doA, doB, doC);             // initialize sensor sensor hardware
  motor.linkSensor(&sensor);                          // link the motor to the sensor

  driver.voltage_power_supply = 24;                   // power supply voltage [V]
  motor.voltage_sensor_align = 8;                     // motor align procedure voltage [V]

  motor.linkDriver(&driver);                          // link the motor and the driver

 // motor.foc_modulation = FOCModulationType::SinePWM;  // use sinusoidal PWM modulation
  motor.foc_modulation = FOCModulationType::Trapezoid_120;  // use sinusoidal PWM modulation

  
  motor.controller = MotionControlType::velocity_openloop;  // set motion control loop to be used
  motor.torque_controller = TorqueControlType::voltage;     // set torque control loop to be used

  // velocity PI controller parameters
/*  motor.PID_velocity.P = 0.2f;
  motor.PID_velocity.I = 2;
  motor.PID_velocity.D = 0;*/
  
  motor.voltage_limit = 10;                           // default voltage_power_supply

//  motor.PID_velocity.output_ramp = 300;               // jerk control using voltage voltage ramp (default value is 300 volts per sec  ~ 0.3V per millisecond)

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

                                 // use monitoring with serial
  motor.useMonitoring(Serial);

  // INITIALIZATIONS
  driver.init();
  sensor.init();
  motor.init();
  motor.initFOC();

  command.add('T', doTarget, "target velocity");      // add target command T
  motor.useMonitoring(Serial);

  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target velocity using serial terminal:"));
  _delay(500);
}


void loop()
{
  motor.loopFOC();

  motor.move(target_velocity);

  command.run();
}

I also tried to add this code to the FOClib (HallSensor.cpp):

void HallSensor::updateState() {
  SIMPLEFOC_DEBUG("!!!");
  .
  .
  .

But the serial output does not show this line when rotating the rotor!
(Of course i tried the debugging line on another place in the code, which works)

This test code works flawlessy:

#include <Arduino.h>

#define PIN_HALL1 7
#define PIN_HALL2 5
#define PIN_HALL3 6 

void doA();

void setup()
{
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(PIN_HALL1), doA, CHANGE);
}

void loop() {
  // put your main code here, to run repeatedly:

}

void doA()
{
  Serial.println("!!");
}

What can cause that type of problem? How do I find out?

I would be glad for any help!

Best wishes,
Florian

Do you have pull-ups on the hall lines ?

No not externally. Should I cativate sensor.pullup = Pullup::USE_INTERN;?
As far as I rember I also tried that without success…

I believe it will work with external pull-ups. Try 3.3k

Arduino Pullup 20kΩ

Be careful when using internal pullups, Arduino has relatively high valued pullups around 20kΩ, which means that you might have some problems for higher velocities (for shorted impulse durations). Recommended pull-up values are in between 1kΩ and 5kΩ.

If your wires are in order.

I just tried 3k3 pull-ups first on the Arduino side of the level shifter to 3V3 and then on the hall sensor side to 5V.
Same faulty behavior…

What’s with the level shifter ?

You pull up to Arduino 3.3v right ?

Correct me if I’m wrong, but usually hall’s are floating when not pulled down by the magnet.

They are there because the hall sensors need 5V supply and therefore also have an output of 5V which is then translated to 3V3 of the Arduino.

Yes, of course

Hmm :thinking: which hall’s are in the motor. I think you might be wrong in that assumption

I only have that datasheet informations of the motor: https://docs.rs-online.com/e4cd/A700000008879715.pdf

Your hall’s are most likely open-drain

Ok, I understand, but I already tried pull-ups on the 5V side of the level shifter so directly at the hall sensors.

And as mentioned with the other short test code I could produce a log output when rotating with exact the same hardware…

Is there something software wise I can test?

You don’t need the level shifter, just embrace it. One less component :+1:

If in doubt, take a look at some schematic for a bldc controller with hall input. Does it use a level shifter?

Ok, that could be an enhancement you are right!

But how do I solve the primary problem with the not working hall sensor read-in?

Did you try without the level shifter and the hall lines pulled up to Arduino 3.3v ?

I just tried, same behavior…

Maybe a software problem? Do you see any problem in my code above?

Run this code, it will work. You were initialisation at wrong sequence.

Hi, thanks or the suggestions! I see what you did, looks more logical!

But still the motor shaft is only rotating very short and the serial shows the following:

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.
MOT: Monitor enabled!
Motor ready.
Set the target velocity using serial terminal:

You need Pull up resistors, Add pull-up resistors than the Hall sensor will work.

You mean externally on the Arduino side to 3.3V? I already did with 3.3k…

Is this initialization behavior normal?
Motor_movement_init