GetAngle Problem

Hello all,
I am a newbie to SimpleFoc and coding and right now I’m exploring the functionalities. Currently I am watching the Tuning guide Part 1 from SimpleFOC on youtube (Not sure if I am allowed to post Links here; It’s at the time stamp 5:20 - 7:20) and I am trying to reproduce it.
In the video he sets up the Hall sensors and then he reads out the Angle and Velocity of the rotor. But unfortunately I always get a 0 on my Angle Read. The velocity works fine, when I turn the rotor by hand I get positive and negative values depending on in which direction I spin the rotor. Pretty sure the hardware is fine, because I already managed to turn the Motor in Velocity Control Mode with different set velocities.

Hardware used:
ESP32S3
DriverBoard with TMC6200 (Standalone, no SPI)
BLDC Motor (3 Phases, 8 Poles, 24V, 4.41±5% Back EMF, Hall Sensors)

Thank you in advance! I hope my Newbiness does not annoy you.

#include <SimpleFOC.h>

#define HALLU_PIN 6
#define HALLV_PIN 7
#define HALLW_PIN 15
#define POLE_PAIRS 8 // Number of poles divided by two

//hall sensor instance
HallSensor sensor = HallSensor(HALLU_PIN, HALLV_PIN, HALLW_PIN, POLE_PAIRS);


//Interrupt routune init
//Channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}


float target = 1.0;

void serialLoop() {
  static String received_chars;

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

void setup() {


  Serial.begin(115200);
  delay(1000);

  // initialize sensor sensor hardware
  sensor.init();
  sensor.enableInterrupts(doA, doB, doC);

  Serial.println("setup");

}

void loop() {
  serialLoop();

  Serial.print(sensor.getAngle());
  Serial.print("\t");
  Serial.println(sensor.getVelocity());
}

You need to call sensor.update(). Normally it’s done automatically in motor.loopFOC(), but for a test like this you’ll have to call it directly.

It’s my fault that it’s necessary :slight_smile: Previously we had some trouble where the variables could get modified by interrupt in the middle of the calculation in getAngle, resulting in a bad value. I changed it to disable interrupts and copy the volatile variables into non-volatile ones in update, but I wasn’t aware of that video being dependent on the old behavior. There are other potential solutions to the problem, but of course they have their own pros and cons.

P.S. Another relatively new thing in HallSensor (added by @Candas1) is that it can be used without interrupts at all. If you don’t call enableInterrupts, then the update function will poll the sensors and update the angle. It results in sightly less accurate velocity readings, but otherwise works just as well. Better in some cases, if you get multiple interrupts from a single sensor change. Theoretically it could lose track of the position if the motor is spinning super fast, but it would have to be spun by something else since you can’t drive it faster than one state change per update, and you have to miss two state changes in a row to actually lose position.

Just to give the pointer to the docs.

It’s true that we did not explicitly said that it’s needed.
But the sensor.update() is in all our standalone examples and has the IMPORTANT comment next to it. :smiley:

  // IMPORTANT - call as frequently as possible
  // update the sensor values 
  sensor.update();

We should add a more explicit statement about it.

Wow thank you dekutree!

Where did you learn that? I was checking all the docs and I did not find it anywhere.