Weird current pattern

Here is a useful bit of code to help debugging such things:

float target = 0;
char printVariable = 0;

void loop() {
  unsigned long loopTime = _micros();

  motor.loopFOC();
  motor.move(target);

  loopTime = _micros() - loopTime;
  static unsigned long lastPrintTime = 0;
  unsigned long t = millis();
  if (printVariable && t >= lastPrintTime + 50)
  {
    lastPrintTime = t;
    char string[256];
    switch(printVariable)
    {
    case 's': sprintf(string, "%i\n", (int)(motor.shaft_velocity*1000)); break;
    case 'a': sprintf(string, "%i\n", (int)(motor.shaft_angle*1000)); break;
    case 'l': sprintf(string, "%i\n", loopTime); break;
    case 't': sprintf(string, "%i\n", (int)target); break;
    default: string[0] = 0;
    }
    if(string[0]) Serial.print(string);
  }

  switch(Serial.read())
  {
  case '!': delay(2); printVariable = Serial.available() ? Serial.read() : 0; break;

  case 'N': motor.controller = (MotionControlType)(int)Serial.parseInt(); Serial.print("Set ");
  case 'n': Serial.print("controller "); Serial.println(motor.controller); break;
  case 'U': motor.foc_modulation = (FOCModulationType)Serial.parseInt(); Serial.print("Set ");
  case 'u': Serial.print("foc_modulation "); Serial.println(motor.foc_modulation); break;
  case 'Q': motor.torque_controller = (TorqueControlType)Serial.parseInt(); Serial.print("Set ");
  case 'q': Serial.print("torque_controller "); Serial.println(motor.torque_controller); break;
  case 'K': motor.KV_rating = Serial.parseFloat(); Serial.print("Set ");
  case 'k': Serial.print("KV_rating "); Serial.println(motor.KV_rating); break;
  case 'R': motor.phase_resistance = Serial.parseFloat(); Serial.print("Set ");
  case 'r': Serial.print("phase_resistance "); Serial.println(motor.phase_resistance); break;
  case 'L': motor.phase_inductance = Serial.parseFloat(); Serial.print("Set ");
  case 'l': Serial.print("phase_inductance "); Serial.println(motor.phase_inductance); break;
  case 'Z': motor.zero_electric_angle = Serial.parseFloat(); Serial.print("Set ");
  case 'z': Serial.print("zero_electric_angle "); Serial.println(motor.zero_electric_angle); break;
  case 'T': target = Serial.parseFloat(); Serial.print("Set target "); Serial.println(target); break;
  case 't': Serial.print("target "); Serial.println(target); break;

  case 'V': motor.voltage_limit = motor.P_angle.limit = motor.PID_current_q.limit = motor.PID_current_d.limit = Serial.parseFloat(); Serial.print("Set ");
  case 'v': Serial.print("voltage_limit "); Serial.println(motor.voltage_limit); break;
  case 'C': motor.current_limit = motor.PID_velocity.limit = Serial.parseFloat(); Serial.print("Set ");
  case 'c': Serial.print("current_limit "); Serial.println(motor.current_limit); break;

  case 'O': motor.PID_velocity.output_ramp = Serial.parseFloat(); Serial.print("Set ");
  case 'o': Serial.print("PID_velocity.output_ramp "); Serial.println(motor.PID_velocity.output_ramp); break;
  case 'F': motor.LPF_velocity.Tf = Serial.parseFloat(); Serial.print("Set ");
  case 'f': Serial.print("LPF_velocity.Tf "); Serial.println(motor.LPF_velocity.Tf); break;
  case 'E': motor.LPF_angle.Tf = Serial.parseFloat(); Serial.print("Set ");
  case 'e': Serial.print("LPF_angle.Tf "); Serial.println(motor.LPF_angle.Tf); break;
  case 'P': motor.PID_velocity.P = Serial.parseFloat(); Serial.print("Set ");
  case 'p': Serial.print("PID_velocity.P "); Serial.println(motor.PID_velocity.P); break;
  case 'I': motor.PID_velocity.I = Serial.parseFloat(); Serial.print("Set ");
  case 'i': Serial.print("PID_velocity.I "); Serial.println(motor.PID_velocity.I); break;
  case 'D': motor.PID_velocity.D = Serial.parseFloat(); Serial.print("Set ");
  case 'd': Serial.print("PID_velocity.D "); Serial.println(motor.PID_velocity.D); break;
  }
}

You can add more variables as needed, although eventually you run out of letters to represent them :slight_smile:

In serial monitor, you type things like V1.5 to set voltage limit 1.5, or v to print out the current voltage limit, and !s to print velocity to the serial monitor 20 times per second, and ! alone to cancel the continuous printing.

The continuous printing is done with a single call to Serial.print, which as I said before will not block the CPU. And you can close serial monitor and open serial plotter to see the variable in graphical form.

Note: STM32’s implementation of sprintf does not support floating point, so you have to multiply by 1000 and cast to int to see the decimal portion.

You might try adding a printVariable case for motor.voltage.Ua to see what voltage it thinks it’s outputting, and compare the shape of the wave to what you see on the oscilloscope when probing phase A.

:thinking: serial plotter??? whatza?

It’s a very useful feature in Arduino IDE. Are you using a different development environment?

There’s also something called SimpleFOC Studio for similar data plotting, though I’ve never tried it, and it probably wouldn’t work on STM32 due to the serial blocking problem.

ah, okay, thx. I’m actually using visual studio code.

you know, I’m really puzzled, the code is very straight, the configuration is also straigh, totally open loop , my µc is running “orrocho” (clockwork orange : ) ) … what’s wrong…..