Hello,
i am very new to SimpleFOC but i think your work is awsome and i want to use SimpleFOC in my new project.
I have a BLDC with 2 polpairs and 3 hallsensors. The resistance is approximatly 5.6 Ohm and the motor is rated vor 24V and 13000 rpm. I have read that the motor needs under 1W if he has no load attached. Unfortunatly i have no other Infos about this motor.
As a controller i use the ESP32-S3 and the SimpleFOC Mini 1.1.
My Problem is, my motor draws 5 to 8 Watt with no load und reaches only 5500 rpm (if my code is correct). Also the motor jerks (i hope this is the right word
) in irregular intervals.
I want to use closed loop (in my project the load varies).
I tried also open loop but the current draw and speed limit is also there.
Because i thought it is a EMC problem, i soldered 4.7k Ohm pullups and 100nF capacitors to make a low pass filter for the hallsensors, but this did not help.
My Code is the following (i played with motor.initFOC(value)):
#include <stdio.h>
#include “freertos/FreeRTOS.h”
#include “freertos/task.h”
#include “esp_log.h”
#include “esp_task_wdt.h”
#include “driver/gpio.h”
#include “driver/gpio_filter.h”
#include “esp_simplefoc.h”
#include “sensors/HallSensor.h”
#define USING_MCPWM
static constexpr int POLE_PAIRS = 2;
static constexpr float GEAR_RATIO = 100.0f;
static constexpr float SPINDLE_PITCH_MM = 5.08f;
static constexpr int PWM_U_PIN = 9;
static constexpr int PWM_V_PIN = 10;
static constexpr int PWM_W_PIN = 11;
static constexpr int EN_PIN = 12;
static constexpr int HALL_A_PIN = 5;
static constexpr int HALL_B_PIN = 6;
static constexpr int HALL_C_PIN = 4;
BLDCMotor motor = BLDCMotor(POLE_PAIRS);
BLDCDriver3PWM driver = BLDCDriver3PWM(PWM_U_PIN, PWM_V_PIN, PWM_W_PIN, EN_PIN);
HallSensor sensor = HallSensor(HALL_C_PIN, HALL_A_PIN, HALL_B_PIN, POLE_PAIRS);
Commander command = Commander(Serial);
float target_velocity = 0.0f;
static void IRAM_ATTR doA() { sensor.handleA(); }
static void IRAM_ATTR doB() { sensor.handleB(); }
static void IRAM_ATTR doC() { sensor.handleC(); }
static void onMotor(char *cmd) { command.motor(&motor, cmd); }
static void onTarget(char *cmd) { command.scalar(&target_velocity, cmd); }
static inline float motorRadPerSecToOutputRpm(float motor_rad_s)
{
float motor_rpm = motor_rad_s * 60.0f / _2PI;
return motor_rpm / GEAR_RATIO;
}
static inline float outputRpmToMmPerSec(float output_rpm)
{
return output_rpm * SPINDLE_PITCH_MM / 60.0f;
}
static void foc_task(void *arg)
{
esp_task_wdt_delete(nullptr);
uint32_t yield_cnt = 0;
while (true) {
motor.loopFOC();
motor.move(target_velocity);
if ((++yield_cnt & 0x3FFu) == 0) {
vTaskDelay(1);
}
}
}
static void monitor_task(void *arg)
{
uint32_t lastPrint = 0;
while (true) {
command.run();
uint32_t now = millis();
if (now - lastPrint > 200) {
lastPrint = now;
float motor_vel = motor.shaftVelocity();
float output_rpm = motorRadPerSecToOutputRpm(motor_vel);
float mm_s = outputRpmToMmPerSec(output_rpm);
printf("target=%.2f rad/s, motor=%.2f rad/s, out=%.3f rpm, "
"v=%.3f mm/s, Uq=%.2f\n",
target_velocity, motor_vel, output_rpm, mm_s,
motor.voltage.q);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
extern “C” void app_main(void)
{
SimpleFOCDebug::enable();
Serial.begin(115200);
vTaskDelay(pdMS_TO_TICKS(1500));
Serial.println();
Serial.println("BLDC Hall Closed Loop");
pinMode(HALL_A_PIN, INPUT_PULLUP);
pinMode(HALL_B_PIN, INPUT_PULLUP);
pinMode(HALL_C_PIN, INPUT_PULLUP);
sensor.init();
sensor.velocity_max = 2000.0f;
sensor.enableInterrupts(doA, doB, doC);
for (int pin : {HALL_A_PIN, HALL_B_PIN, HALL_C_PIN}) {
gpio_pin_glitch_filter_config_t fcfg = {
.clk_src = GLITCH_FILTER_CLK_SRC_DEFAULT,
.gpio_num = static_cast<gpio_num_t>(pin),
};
gpio_glitch_filter_handle_t filter = nullptr;
if (gpio_new_pin_glitch_filter(&fcfg, &filter) == ESP_OK) {
gpio_glitch_filter_enable(filter);
}
}
printf("Initial Hall state: %d%d%d\n",
digitalRead(HALL_A_PIN),
digitalRead(HALL_B_PIN),
digitalRead(HALL_C_PIN));
driver.voltage_power_supply = 24.0f;
driver.voltage_limit = 24.0f;
driver.pwm_frequency = 32000;
#ifdef USING_MCPWM
driver.init(0);
#else
driver.init({0, 1, 2});
#endif
motor.linkDriver(&driver);
motor.linkSensor(&sensor);
motor.controller = MotionControlType::velocity;
motor.torque_controller = TorqueControlType::voltage;
motor.foc_modulation = FOCModulationType::SinePWM;
motor.voltage_limit = 24.0f;
motor.velocity_limit = 800.0f;
motor.PID_velocity.output_ramp = 20.0f;
motor.PID_velocity.P = 0.05f;
motor.PID_velocity.I = 0.4f;
motor.PID_velocity.D = 0.001f;
motor.PID_velocity.limit = motor.voltage_limit;
motor.LPF_velocity.Tf = 0.15f;
motor.useMonitoring(Serial);
motor.monitor_downsample = 100;
motor.init();
Serial.println("Starte initFOC...");
motor.voltage_sensor_align = 6.0f;
motor.initFOC(2.7);
command.eol = '\r';
command.add('M', onMotor, const_cast<char *>("motor"));
command.add('T', onTarget, const_cast<char *>("target velocity rad/s"));
Serial.println();
Serial.println("Fertig.");
Serial.println();
xTaskCreatePinnedToCore(foc_task, "foc_task", 8192, nullptr,
configMAX_PRIORITIES - 2, nullptr, 1);
xTaskCreatePinnedToCore(monitor_task, "monitor", 4096, nullptr,
5, nullptr, 0);
}
Thank you very much for your help
Best regards