跳至主要內容

FOC算法实现过程记录:13.锁相环实现

丁毅桂2024年12月2日小于 1 分钟

13.使用锁相环实现对转子位置和速度的计算

具体实现

PLL.h
#ifndef _PLL_H_
#define _PLL_H_
#include "LowPassFilter.hpp"
#include "PIDControler.hpp"
#include "Timer.hpp"
#include "config.h"
#include "foc_utils.h"

class PLL
{
private:
    Timer *timer = new ConcreteTimer();

public:
    PIDControler pid_speed_controller{500, 250, 0, 1e10, 0};
    LowPassFilter lpf{5};
    float speed = 0;
    float value = 0;
    float update(float target)
    {
        // PLL=鉴相=>低通滤波=>压控振荡器
        speed = pid_speed_controller(lpf(_sin(_normalizeAngle(target - value))));
        value += speed * timer->dt_s();
        return value;
    }
};

#endif

实现效果

alt text

代码

#include <Arduino.h>
#include <Wire.h>
#include "BLDCMotor.hpp"
#include "BLDCDriver.hpp"
#include "Sensor.hpp"
#include "foc_utils.h"
#include "communication.hpp"
#include "arduino/ArduinoBLDCDriver.hpp"
#include "arduino/ArduinoCurrentSensor.hpp"
#include "arduino/AS5600Sensor.hpp"
#include "Pll.h"

BLDCMotor motor = BLDCMotor(7, 12);
AS5600Sensor *sensor = new AS5600Sensor();
BLDCDriver *driver = new ArduinoBLDCDriver(5, 9, 6, 8);
CurrentSensor *currentSensor = new ArduinoCurrentSensor(A0, A2, 0.01f, 50);

void setup()
{
  Serial.begin(115200);
  motor.connectDriver(driver);
  motor.connectSensor(sensor);
  motor.connectCurrentSensor(currentSensor);
  motor.initFOC();
  motor.setMode(BLDCControlMode::Current);
}
void decode_message();
Timer *tim = new ConcreteTimer();
void loop()
{
  motor.loopFOC();
  decode_message();
  send_message();
  static uint8_t cnt = 0;
  if (++cnt % 15 == 0 && buffer_empty())
  {
    cnt = 0;
    buf_len += sprintf(buffer, "0,%.2f,%.2f\n", sensor->position_now, _normalizeAngle(sensor->pll.value));
  }
}

void decode_message()
{
  if (Serial.available())
  {
    uint8_t cmd = Serial.read();
    float val = Serial.parseFloat();
    while (Serial.read() != '\n')
      ;
    switch (cmd)
    {
    case 'm':
      motor.setMode((BLDCControlMode)val);
      break;
    case 't':
      motor.setTarget(val);
      break;
      case 'l':
      sensor->pll.lpf.Tms=val;
      break;
    case 'p':
      sensor->pll.pid_speed_controller.Kp=val;
      sensor->pll.pid_speed_controller.reset();
      break;
    case 'i':
      sensor->pll.pid_speed_controller.Ki=val;
      sensor->pll.pid_speed_controller.reset();
      break;
    case 'd':
      sensor->pll.pid_speed_controller.Kd=val;
      sensor->pll.pid_speed_controller.reset();
      break;
    // case 'l':
    //   motor.current_d_filter.Tms = val;
    //   motor.current_q_filter.Tms = val;
    //   break;
    // case 'p':
    //   motor.pid_id_controller.Kp = val;
    //   motor.pid_iq_controller.Kp = val;
    //   motor.pid_id_controller.reset();
    //   motor.pid_iq_controller.reset();
    //   break;
    // case 'i':
    //   motor.pid_id_controller.Ki = val;
    //   motor.pid_iq_controller.Ki = val;
    //   motor.pid_id_controller.reset();
    //   motor.pid_iq_controller.reset();
    //   break;
    // case 'd':
    //   motor.pid_id_controller.Kd = val;
    //   motor.pid_iq_controller.Kd = val;
    //   motor.pid_id_controller.reset();
    //   motor.pid_iq_controller.reset();
    //   break;
    default:
      break;
    }
  }
}