C/C++教程

手写最简单的simplefoc的svpwm算法(便于理解)

本文主要是介绍手写最简单的simplefoc的svpwm算法(便于理解),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

此帖子用于记录学习过程中写的程序(半成品)。

1.arduino代码:

test.ino

//      (010)U2   II   U6(110)
//             *********
//      III   * *     * *   I
//           *   *   *   *
//  (011)U3 ***************  U4(100)
//           *   *   *   *
//       IV   * *     * *   VI
//             *********
//      (001)U1    V     U5(101)
//author:liuzhitong
//mail:953598974@qq.com

#include "svpwm.h"
#include <SimpleFOC.h>

#define sl 500
#define pi 3.1415926
#define f 30

Motor motor1;

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);
long t;

void setup() {
  Serial.begin(115200);
  motor1.init();
  I2Cone.begin(18, 5, 400000); 
  sensor.init(&I2Cone);
  t=millis();
}


void loop() {
  //if((motor1.angle_c!=motor1.angle_go)&&((millis()-motor1.old_time)>1))
  if((millis()-motor1.old_time)>25)
  {
    motor1.calculate();
  }
  if((millis()-t)>200)
  {
    sensor.update();
    Serial.println(sensor.getVelocity()); 
    t=millis();
  }
  motor1.svpwm(); 
  
}

svpwm.cpp

#define sqrt_3 1.7320
#define pi 3.1415926
#define T 200

#define enable_pinA 33
#define enable_pinB 32
#define enable_pinC 23

#define piA 25
#define piB 19
#define piC 22

class Motor{
  public:
    double angle_c=0.0;//默认开头是0度,电机角度在U4处
    double velocity_m=10.0;
    long angle_go=41400;//目标角度
    int T0=0,T1=0,T2=0,T7=0;
    int sector;//sector为扇区
    float U_dc=12.0,U_ref=6.0;
    float oumiga=pi;
    int cal_flag=1;//计算扇区和T0,T1,T2,T7的标志位,需要计算时为1,不需要计算时为0
    long old_time=0;//用于判断速度
    
    void init();
    void calculate();
    void svpwm();
};
//计算标志位的函数
void Motor::init()
{
  pinMode(22,OUTPUT);
  digitalWrite(22,HIGH);
  pinMode(32,OUTPUT);
  pinMode(33,OUTPUT);
  pinMode(25,OUTPUT);
  //默认开启的时候在第一区间
  digitalWrite(32,1);
  digitalWrite(33,0);
  digitalWrite(25,0);
  delay(1000);
  old_time=millis();
}
//T=1ms=1us;
//计算标志位的函数
void Motor::calculate()
{
  int angleInSector=int(angle_c)%60;
  sector=(int(angle_c)%360)/60+1;
  T1=sqrt_3*U_ref/U_dc*T*sin(pi*(60-angleInSector)/180);
  T2=sqrt_3*U_ref/U_dc*T*sin(pi*angleInSector/180);
  T0=(T-T1-T2)/2;
  T7=T0;
//  if(angle_c<angle_go)
//  {
    velocity_m=396.0*oumiga/(10.0*pi);
    angle_c=angle_c+2.5*velocity_m;
//  }
  old_time=millis();
//  Serial.println("-");
//  Serial.println(angle_c);
//  Serial.println(sector);
//  Serial.println(T0);
//  Serial.println(T1);
//  Serial.println(T2);
//  Serial.println(T7);
}

void Motor::svpwm()
{
  switch(sector)
  {
    case 1:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
    case 2:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
    case 3:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,0);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
    case 4:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,0);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
    case 5:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T2/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
    case 6:
    {
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,1);
      digitalWrite(25,1);
      delayMicroseconds(T7);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T2/2);
      digitalWrite(32,1);
      digitalWrite(33,0);
      digitalWrite(25,1);
      delayMicroseconds(T1/2);
      digitalWrite(32,0);
      digitalWrite(33,0);
      digitalWrite(25,0);
      delayMicroseconds(T0/2);
      break;
    }
  }
}

2.改进一下

我们上面直接用delay生成的pwm波,这样精确性很差,这里我们使用esp32的mcpwm控制器来产生pwm波。

这篇关于手写最简单的simplefoc的svpwm算法(便于理解)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!