Space Vector Modulation(SVM) Konusu

Başlatan Mucit23, 16 Mart 2018, 11:48:28

Cemre.

Alıntı yapılan: bulut_01 - 11 Nisan 2018, 17:04:49bu yöntem ile ne kdr hassas acı hesabı yapılabilir? enkoder çözünürlüğüne bu yöntemle ulaşmak ne kdr gerçekci olur?

Hall effect sensör uygulamasındaki gibi bemf'in zero cross anlarında komutasyon yaptırmak için kullanılıyor. Bu konuyla alakalı çok fazla makale var ieeexplore'da.

bulut_01

Alıntı yapılan: Cemre. - 11 Nisan 2018, 17:18:08Hall effect sensör uygulamasındaki gibi bemf'in zero cross anlarında komutasyon yaptırmak için kullanılıyor. Bu konuyla alakalı çok fazla makale var ieeexplore'da.
üstad komutasyon için kullanıldıgını biliyorum çözünürlük anlamında sormustum ne kadar hassas konum ölçebilir diye bemf ile?
YENİLMEZ..

spirtless

Arkadaşlar merhaba,
Bir süredir PMSM motor sürücüsü için uğraşıyorum. Şuana kadar pcb donanımı hazır ancak yazılım konusunda bir noktada tıkandım. Yapacağım uygulama pozisyon kontrolü olacaktır.  Daha o noktaya gelemeden pwm konusunda tıkandım. Vektör kontrolü yapmaya çalışıyorum. Pwm duty nin hiç durmadan %8-%92 arasında değişmesi lazım.Ben arada pwm in 0 olduğunu da görüyorum. Ayrıca kodun açıklamasına göre pwm değerlerini girdiğimde çok farklı değerler görüyorum. Mesela %92 duty oranına göre değer verdiğimde %15 gibi duty görüyorum. Muhtemelen kod diziliminde bir hata yapıyorum. Bu konuda yorumlarınız nedir?
Bunu çözdükten sonra pozisyon bilgisi alt programını ekleyeceğim.


#include<18F4431.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=200000000)

setup_oscillator(OSC_20MHZ); 

  #include <math.h>
  #include "float.h"
  #include "math.h"
  #include "stdlib.h" 
  #include "stdio.h" 
  

#define POWER_PWM_PERIOD 332
/*********************************** 
freq= Fosc / (4*(period + 1) * postscale) 
or 
period = (Fosc /( 4 * freq * postscale)) -1 

if we want 15khz 
period =( 20mhz /(4 * 15khz * 1) -1 
peroid = 332; 
*****************************************/ 


double U_faz_aci=(0), V_faz_aci=((180)/3), W_faz_aci=((2*180)/3);
float motor_frekans=50,max_motor_frekans=50,pwm_frekansi=15000; 
double aci_artis, ornek_sayisi=50, duty_kazanc=1;
double sin_U, sin_V, sin_W,duty_U,duty_V,duty_W;
float32 rad=PI/180.0;
 
void main()
{
  
// Setup the 4 Power PWM channels as ordinary pwm channels.
//setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
//  setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY, PWM_COMPLEMENTARY, PWM_OFF);
  setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY, PWM_COMPLEMENTARY, PWM_COMPLEMENTARY);
// Mode = Free Run 
// Postscale = 1  (1-16) Timebase output postscaler
// TimeBase = 0  (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0    (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

  setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0); 
//  setup_power_pwm(PWM_CLOCK_DIV_4 | PWM_FREE_RUN |  PWM_DEAD_CLOCK_DIV_16,1,10000,1000,0,1,30);
    set_power_pwm0_duty(0);
    set_power_pwm2_duty(0);
    set_power_pwm4_duty(0);
          
  while(TRUE)
  {
        
                                                                      //Hız düştükçe V/f oranını sbit tutmak için basılan gücü düşür
        duty_kazanc=(motor_frekans/max_motor_frekans)*(0.92)*1;    // kazanç sabitleyici (V/f sabit tutmak için)

                                                                    // Belli bir orandan sonra artık V/f sabit değil. Duty ratio değerini sabitle
        if(duty_kazanc<(0.2))
        {
        duty_kazanc=0.2;
        }
            //Duty ratio değerini limitle
      if(duty_kazanc>(0.92))
      {
      duty_kazanc=0.92;
        }
                                                                  // anahtarlama frekansını ulaşılmak istenilen hız değerine bölerek örnekleme sayısını bul
      ornek_sayisi=(pwm_frekansi/motor_frekans);                //örnekleme sayısı
      aci_artis = ((180)/ornek_sayisi);                          // örnwkleme sayısını kullanarak oluşturulacak sinüs değerinin açısal artışını bul

      u_faz_aci=u_faz_aci+aci_artis;                            // fazlardaki sinüsün açısını arttır
      if(u_faz_aci>(180))
      {
      u_faz_aci=u_faz_aci-(180);                                // fazlardaki sinüsün açısını baştan başlat
      }
 
      if(u_faz_aci<(180/3))
      {
      v_faz_aci=(180/3)+u_faz_aci;
      w_faz_aci=((2*180)/3)+u_faz_aci;
      }

      else if ((u_faz_aci>=(180/3)) && (u_faz_aci<((2*180)/3)))
      {

      v_faz_aci=(180/3)+u_faz_aci;
      w_faz_aci=u_faz_aci-(180/3);
      }

      else if ((u_faz_aci>=((2*180)/3)) && (u_faz_aci<=(180)))
      {

      v_faz_aci=u_faz_aci-((2*180)/3);
      w_faz_aci=u_faz_aci-(180/3);
      } 
                                  
      sin_U=(sin(u_faz_aci*rad))*duty_kazanc;                // pwm genlik değeri(U)
      sin_V=(sin(v_faz_aci*rad))*duty_kazanc;                //  pwm genlik değeri(V)
      sin_W=(sin(w_faz_aci*rad))*duty_kazanc;                //  pwm genlik değeri(W)
 
      if(sin_U<(0.08))
      {
        sin_U=0.08;
      } 
      if(sin_U>(0.92))
      {
        sin_U=0.92;
      }
      if(sin_V<(0.08))
      {
        sin_V=0.08;
      } 
      if(sin_V>(0.92))
      {
        sin_V=0.92;
      }
      if(sin_W<(0.08))
      {
        sin_W=0.08;
      } 
      if(sin_W>(0.92))
      {
        sin_W=0.92;
      }
 
        duty_U=4*POWER_PWM_PERIOD*sin_U;
        duty_V=4*POWER_PWM_PERIOD*sin_V;
        duty_W=4*POWER_PWM_PERIOD*sin_W; 
        
        set_power_pwm0_duty(duty_U);
        set_power_pwm2_duty(duty_V);
        set_power_pwm4_duty(duty_W);            
  }  
  }

spirtless

Yorum yapacak veya yardımcı olabilecek kimse yok mudur?

devrecii

#79
Kimse cevap vermemiş diye yazayım dedim.

Programcılıkta adım adım ilerleme kuralı vardır öyle kodu yazayım hop hemen çalışsın yok, bunu 50 senelik koderler bile başaramaz.

İlk başta sana tavsiyem basit pwm çıkışını al ve osiloskopda incele , daha sonra belli zamanda değişken pwm yap izle ,daha sonra herhangi pswm filan yapmadan 0-360derece sinus pwm yap ve bunu osiloskpda gözlemle dha sonr 3 faz sinus üret ve osklopda incele . 6 çıkış mı olacak 3 çıkışmı bu da var.

Daha sonra vektör kontrol yapabilirsin. Mikroişlemciye sinus hesaplatmak ,double float işlemleri vs mikroişlemciyi çok yorar.

Sinus tablosu oluşturabilirsin. Tabi bu en son ki iş.


spirtless

Bu kod dizilimini daha önce TI C2000 ve ARM core 9 serisi AM4379 idk board üzerinde denedim. Güzel bir sinüs elde ettim fakat başka sorunlar yaşadığım ve teknik desteği kısıtlı olduğu için basic seviyede bir işlemci ile adım adım ilerliyorum. Ancak pic18F4431 8 kanal power pwm çıkışı olduğu işe bu noktadan başladım fakat kod dizilimim uygun olarak çalışmıyor. Bir yerlerde eksik bilgi var veya atladığım bir nokta var. Zaten ilk olarak pwm sonra geri besleme en son olarak haberleşme ünitesi olarak konuyu böldüm.Kontrol konusunda bilgi sahibiyim ancak bunu koda döktüğümde sorunla karşılaştım. Uygun çalışmayan yer burası;
 
       set_power_pwm0_duty(duty_U);      //U fazı H-side
        set_power_pwm2_duty(duty_V);     //V fazı H-side
        set_power_pwm4_duty(duty_W);     //W fazı H-side

normalde beklenen  set_power_pwm0_duty(min) ise en düşük %duty  , set_power_pwm0_duty(max) ise en yüksek %duty
olması gerekir. Ama sanki bazı değerler de yine min ve max duty görülüyor. Hatta gördüğüm kadarı ile pwm sürekli olması gerekirken bazen pwm çıkısı arada bir 0 oluyor. Temel problemim budur. Kodun eksik ve hatalı kısımlarını görerek iyileştirme yapmak istiyorum.