BLDC fazı ters çevirmek

Başlatan bulut_01, 01 Ocak 2013, 12:26:41

bulut_01

s.a picproje ailesi öncelikle yeni yılınızı kutlarım.sorunum bldc sürücü yapdım kodu tamamladım sayılır yanlız motor yönünü değiştirmek için swich case döngüsü tersden döngü kurmam lazım
söyle bişe yazdım ama işe yaramadı.
a4 port yön bilgisi için kullandım low oldugunda motor saga hıgh oldugunda sola dönmesi lazım.
(not: proteusda bldc motor similasyonunda yönü hep saga dönüyor fazını değiştirdiğim halde bende mi hata yoksa proteus bldc motor similasyonu tek yönemi döner sadace ?)

#int_RB
void RB_kesme()
{
x=input(pin_a4);
if(x==0)
hall  = input_a()& 0b00000011 ;
hall |= input_b()& 0b00001000 ;
if(x==1)
hall  = input_a()& 0b00000011^input_b()& 0b00001000 ;
hall |= input_b()& 0b00001000^input_a()& 0b00000011 ;


kodun tamamı burda normal hali tek yön.
#include <18f1330.h> 
#fuses INTRC_IO,NOWDT,NOMCLR,H4
#use delay(clock=40M)
#use fast_io(a)
#use fast_io(b) 

int16 duty1;
int16 duty2;
int16 duty3;
int16 p=100;
int8 hall=0;


#int_RB
void RB_kesme()
{

hall  = input_a()& 0b00000011 ;
hall |= input_b()& 0b00001000 ;

switch (hall)
{
case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;
default:
}
}
 
      void main()
{
setup_power_pwm_pins(PWM_odd_on,PWM_odd_on,PWM_odd_on,PWM_odd_on);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,1,0,4095,0,1,0); 
setup_adc_ports(NO_ANALOGS); 
setup_adc( ADC_OFF );
setup_comparator(NC_NC_NC); 

set_tris_a(0b000000011);
set_tris_b(0b000001100);
OUTPUT_B(0x00);

enable_interrupts(GLOBAL);
enable_interrupts(int_RB);


while(TRUE)
{
}
}
YENİLMEZ..

Mucit23

Proteustaki BLDC motorun dönmesi için fazlardan herhangi birine 12V vermek yetiyor. :D

marecrisium

Motoru ters yönde döndürmek için ikinci bir switch-case içinde PWM anahtarlamalarını tersten başlayarak yaz.Yani sağa dönerken 1. adımda gönderilen sinyali, sola dönerken 6. sırada olacak şekilde 6 adım için tekrar yaz. İf ile yön şartı belirle ona göre istediğin yöndeki switch-case işletilsin.

bulut_01

söyle bir kod çıkdı meydana uzunluk bakımından ve gereksizlik bakımında neler söylenebilir ? en sade biçimde yazmaya çalışdım yanlız proteus similasyonda bldc motor hep saga dogru döndüğü için scopla bakdıgımda 2 fazın bazen aynı anda aktif oldugunu gördum sebebi motor yön değiştirmediği için olabilir mi ? bu kod gerçekde nasıl çalısır yada verimli sekilde çalısır mı ?

#include <18f1330.h> 
#fuses INTRC_IO,NOWDT,NOMCLR,H4
#use delay(clock=40M)
#use fast_io(a)
#use fast_io(b) 

int16 duty1;
int16 duty2;
int16 duty3;
int16 p=100;
int8 ileri=0;
int8 geri=0;
int1 x=0;

#int_RB
void RB_kesme()
{
x=input(pin_a4);

if(x==1)
ileri  = input_a()& 0b00000011 ;
ileri |= input_b()& 0b00001000 ;

if(x==0)
geri  = input_a()& 0b00000011 ;
geri |= input_b()& 0b00001000 ;

switch (ileri)
{
case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;
default:
p=0;
}

switch (geri)
{
case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;
default:
p=0;

}
}

 
      void main()
{
setup_power_pwm_pins(PWM_odd_on,PWM_odd_on,PWM_odd_on,PWM_odd_on);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,1,0,4095,0,1,0); 
setup_adc_ports(NO_ANALOGS); 
setup_adc( ADC_OFF );
setup_comparator(NC_NC_NC); 

set_tris_a(0b000000011);
set_tris_b(0b000001100);
OUTPUT_B(0x00);

enable_interrupts(GLOBAL);
enable_interrupts(int_RB);


while(TRUE)
{
}
}
YENİLMEZ..

marecrisium

switch case yapılarını ayrı ayrı iki if şartı ile işletsen daha iyi olabilir.Çünkü her durumda hem geri hem ileri yöndeki swich case işletiliyor.Bu hataya neden olabilir.
if (ileri yönde){ ileri yönde swith case adımları}
 if(geri yönde){geri yönde switch case adımları }

şeklinde düzenlersen daha doğru sonuç alabilirsin.

necati

[email]entegreterbiyecisi@yahoo.com[/email]

bulut_01

Alıntı yapılan: marecrisium - 01 Ocak 2013, 22:00:12
switch case yapılarını ayrı ayrı iki if şartı ile işletsen daha iyi olabilir.Çünkü her durumda hem geri hem ileri yöndeki swich case işletiliyor.Bu hataya neden olabilir.
if (ileri yönde){ ileri yönde swith case adımları}
 if(geri yönde){geri yönde switch case adımları }

şeklinde düzenlersen daha doğru sonuç alabilirsin.

yukardakı verdiğin örnegi benım yazdıgım kodun uzerınden dırek yazarak örnek verırmısın.
YENİLMEZ..

marecrisium

Kodlarına göre şöyle yazılması gerekir.
#include <18f1330.h> 
#fuses INTRC_IO,NOWDT,NOMCLR,H4
#use delay(clock=40M)
#use fast_io(a)
#use fast_io(b) 

int16 duty1;
int16 duty2;
int16 duty3;
int16 p=100;
int8 alg=0;

int1 x=0;

#int_RB
void RB_kesme()
{
x=input(pin_a4);

alg  = input_a()& 0b00000011 ;
alg |= input_b()& 0b00001000 ;

if(x==1)    //ileri yönde
{

switch (alg)
{
case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;
default:
p=0;
}
}
if(x==0)
{
switch (geri)  // geri yönde
{
case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;
default:
p=0;
}
}
}

 
      void main()
{
setup_power_pwm_pins(PWM_odd_on,PWM_odd_on,PWM_odd_on,PWM_odd_on);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,1,0,4095,0,1,0); 
setup_adc_ports(NO_ANALOGS); 
setup_adc( ADC_OFF );
setup_comparator(NC_NC_NC); 

set_tris_a(0b000000011);
set_tris_b(0b000001100);
OUTPUT_B(0x00);

enable_interrupts(GLOBAL);
enable_interrupts(int_RB);


while(TRUE)
{
}
}

Saruman

16F877 ile bu iş olur.
Ayrıca size XC8 ya da Hitech C tavsiye ederim.
Derin bir işle uğraşıyorsunuz fakat CCS kullanıyorsunuz, saç baş yoldurur böyle.

3 faza ihtiyaç yok.
Ben de fırçasız motor kontrolüyle ilgileniyorum bu aralar.
PWM'i 16F877 ya da benim kullandığım 16F887 nin CCP2 bacağından alın ve 4lü AND kapısı ile PWM adedini 3'e çıkarın.

Örnek, PWM'i AND kapılarının her birinin 1.girişine bağlayın.
AND kapılarının 2.girişlerini ise her hangi bir port'a bağlayın ve aktif olmasını istediğiniz pwm çıkışını and kapısının ilgili bacağını lojik-1'e çekerek aktif edersiniz.

Hall sensor değişimlerini PORTB değişim kesmesiyle algılarsanız hem yazılıma binen yükü hafifletmiş hem de sensör değişimlerini kaçırmamış olursunuz.

18F serisini sadece hızı için tercih edebilir ve motor sürücü modülü olan bir PIC kullanmak zorunda kalmayarak maliyeti azaltırsınız.

İyi Çalışmalar

teknikelektronikci

Kaan sen hem bize stm leri organize et, sat hemde kendin pic ile calis olmadi :D birak artik pici mici :) yok saka

her ne kadar dedigin dogruda olsa birincisi 18f serisi 16 serisinden ucuz ollabiliyor ikincisi gelecekde kodun ve projenin büyüyecegini düsünürsen 18 serisini kullanmak daha mantikli geliyor tabiyki hw Motor pwm i olanlar pahalli ama yarin öbür gün hem kod yükünü azaltir hemde zamandan tasaruf ki belki amcam bu projeyi yarin öbür gün bir otomasyon firmasina satma sansini yakalayacak bu duurmda 2 gün bekleyinde ben bunu bir üst modelle uyarlayayim demek olmaz, zaten marecrisium arkadasimiz bir ise girismis ve uzun zamandir ugrasiyor sanirim maddi durumu düsünecek durumda degildir :D kolay gelsin
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

z

Bahsettiğiniz yöntemde herhangi bir anda tek fazı on yapabilirsiniz ve sinus yada trapez akım oluşturamazsınız.

BLDC de faz farklı 3 PWM ihtiyacınız var. Vektor kontrol yapmak istemiyorsunuz galiba.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

bulut_01

tek faz pwm bldc motor sürülmez 3 bagımsız pwm fazınızın olmanısı lazım kod tamamladım proteus similasyonunda yön değiştirmiyor gercekde yapıp denemek lazım koda bakarak bişeler söylenebilir yorumlarınızı beklıyorum gercekde nasıl çalışır kurup görmek lazım.
tork ayarı için pwm fazının nasıl modülasyon frekans değiştirebilirim ? motorun ana sürme frekansı 8 khz.

#include <18f1330.h> 
#fuses INTRC_IO,NOWDT,NOMCLR,H4
#use delay(clock=40M)
#use fast_io(a)
#use fast_io(b) 

int16 duty1;
int16 duty2;
int16 duty3;
int16 p=100;
int8 ileri=0;
int8 geri=0;
int1 x=0;

#int_RB
void RB_kesme()
{
ileri  = input_a()& 0b00000011 ;
ileri |= input_b()& 0b00001000 ;

if(x==1)
switch (ileri)
{
case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;
default:
}

geri  = input_a()& 0b00000011 ;
geri |= input_b()& 0b00001000 ;

if(x==0)
switch (geri)
{
case 0b00001000:
set_power_pwm0_duty(duty1=0x00);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b4);
break;

case 0b00001010:
output_low(pin_b6);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b4);
break;

case 0b00000010:
set_power_pwm2_duty(duty2=0x00);
set_power_pwm0_duty(duty1=P*64);
output_high(pin_b6);
break;

case 0b00000011:
output_low(pin_b0);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b6);
break;

case 0b00000001:
set_power_pwm4_duty(duty3=0x00);
set_power_pwm2_duty(duty2=P*64);
output_high(pin_b0);
break;

case 0b00001001:
output_low(pin_b4);
set_power_pwm4_duty(duty3=P*64);
output_high(pin_b0);
break;
default:
}
}
      void main()
{
setup_power_pwm_pins(PWM_odd_on,PWM_odd_on,PWM_odd_on,PWM_odd_on);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,1,0,4095,0,1,0); 
setup_adc_ports(NO_ANALOGS); 
setup_adc( ADC_OFF );
setup_comparator(NC_NC_NC); 

set_tris_a(0b000010011);
set_tris_b(0b000001100);
OUTPUT_B(0x00);

enable_interrupts(GLOBAL);
enable_interrupts(int_RB);


while(TRUE)
{
x=input(pin_a4);
}
}
YENİLMEZ..

Saruman

#12
Murat, arkadaş işe yeni girişiyor, mantığını kavraması açısından pwm barındıran istediği işlemci ile başlayabilir.İçinde motor kontrol modülü bulunduran PIC'ler diğerlerine nazaran pahalı.

@z , "trapez akım oluşturamazsınız" yanıtı eğer bana ise yazdığımı anlamadığınızı düşünüyorum.

Çünkü ben bu yöntemle fırçasız motor çalıştırıyorum. Faz farkını oluşturan zaten hall sensörler.

BLDC Motor Control with 16F887

@bulut_01
Ayrıca sen de farkında değilsin ama tek faz PWM ile sürüyorsun motoru.
DUTY'ler hep aynı.Yine dediğim kapıya çıkıyor.

bulut_01

@silvercopper duty çarpanları aynı evet yanlız atladıgın nokta  pwm fazları birbirinden bagımsız hall bilgisine göre aktif oluyolar senın mantıkla torkunu ayarlayamazsın sadece hız ayarı yapabilirsin.
YENİLMEZ..

z

@silvercopper

Tek PWM'i AND kapılarla seçerek yaptığın uygulamada 3 faz motorun sargı akımlarının dalga şeklini de görseydik.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com