Gönderen Konu: pwm ile step motor kontrolü  (Okunma sayısı 646 defa)

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
pwm ile step motor kontrolü
« : 19 Mayıs 2017, 02:56:13 »
Arkadaşlar merhaba sizlere bir sorum olacak. Ben ilk etapta küçük redüktörlü bir step motoru pals saydırarak ve adımlar arası delay time'ı azaltarak step motorda sınırlı da olsa hız kontrolü yaptım. Şimdi elimde 3nm lik 2 fazlı faz bası 2.7a akım çeken 1.8 step angle a sahip bir motorum ve driverim var. Bunu pwm ile sürmek istiyorum bu motorun pwm ile sürerken adım hesabını nasıl yapacağım ? Belirli bir tur dönmesini istiyorsam bunu nasıl kontrol edebilirim ?

Çevrimdışı matador

  • Kıdemli
  • ****
  • İleti: 308
Ynt: pwm ile step motor kontrolü
« Yanıtla #1 : 19 Mayıs 2017, 12:18:54 »
Sürücünüzün adım ayarlarına göre düşünmek lazım. Micro Step olarak yazacaktır sürücünün üzerinde. Dip switch ile microstep ayarı yaptıktan sonra.

Örneğin; 1/32 ile çalıştırırsanız. 6400 puls de bir tur tamamlar. Siz eğer puls sayısını motora gönderirseniz istediğiniz açıda dönme sağlarsanız. Bunu da çalıştıracağınız sistem müsade ediyorsa for döngüsüyle yapabilirsiniz ama motoru çevirirken program başka bir şeyle ilgilenemez.

Yok ben motor dönerken başka işler de yaptırcam derseniz enkoder en sağlıklı çözüm olacaktır.

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #2 : 19 Mayıs 2017, 15:16:17 »
Kod: [Seç]
Sürücünüzün adım ayarlarına göre düşünmek lazım. Micro Step olarak yazacaktır sürücünün üzerinde. Dip switch ile microstep ayarı yaptıktan sonra.

Örneğin; 1/32 ile çalıştırırsanız. 6400 puls de bir tur tamamlar. Siz eğer puls sayısını motora gönderirseniz istediğiniz açıda dönme sağlarsanız. Bunu da çalıştıracağınız sistem müsade ediyorsa for döngüsüyle yapabilirsiniz ama motoru çevirirken program başka bir şeyle ilgilenemez.

Yok ben motor dönerken başka işler de yaptırcam derseniz enkoder en sağlıklı çözüm olacaktır.
pwm , timer kesmeleri kullanılarak yapılıyor ama ben pulsi nasıl bır kesmeye  çevirecem onu çözemedim.


ben şimdi 20mm yarıçaplı bir teker için 1 metreyi tekerin 8 turda atması gerektiği hesabını yaptım 8sn değil. motorla teker ortak eksenli olduğu için motorumda 8 tur dönecek ve 1 tur yarım adımda 400 pulse ise 8 tur için 3200 pulse eder. bu hesaba göre  motorumun rpmi 60 rpm  çıkıyor.

şöyle bir hesabım var :
Kod: [Seç]

3200 pulse (8 tam tur için): 1/400(1snde) --->2.5 ms yapıyor
tiimer0=10e6x(256)x(256-x)=2.5ms
x burdan 246 cıkıyor
timer0(246)
void timer0_kesme()
{
set_timer0(246);
output_high(pin_b1); // direction belirtttigim pin direk sürücünün direction bacağına bağlayacağım.
i++;
if(i=3200)
output_high(pin_b0);
if(i=6400)
{
output_low(pin_b0);// yön bacagı
output_low(pin_bo);
i=0;
}
hocam doğru mudur ?
« Son Düzenleme: 20 Mayıs 2017, 13:01:54 Gönderen: isoment01 »

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #3 : 20 Mayıs 2017, 03:43:36 »
Kod: [Seç]
uint16_t sayac = 0, hedef = 0;

void timer0_interrupt()
{
TMR0H = 246;
TMR0L = 60;
output_high(pin_b0);
delayu(20); // 20 usec bekle
output_low(pin_b0);
Sayac++;
if (sayac >= hedef)
   T0CON &= 127; //TIMER0 STOP
}

int main()
{
//kesmeleri aktif et.

INTCON |= 0b10100000; //global int ve TMR0 int aktif

output_high(pin_motor_enable);
delayms(100);

output_high(pin_b1);  // direction belirtttigim pin direk surucunun dırectıon bagacagına baglıcagım
//delayu(50);
// yön değiştirirsen kısa bir süre beklemen gerekir.
//Ama burda bir sonraki puls için zaten 2500 usec bekleniyor.

hedef  = 3200; //400*8
sayac = 0;
TMR0H = 246;
TMR0L = 60;
T0CON = 0b00100001; //timer0 16 bit + prescaler 4, 4mhz clock için ayarlı.
T0CON |= 128; //TIMER0 START
while (T0CON >127); // Hareket bitene kadar bekle

//başka hareket varsa aynı şekilde kodlarsın mesela başladığı yere döndürmek için
output_low(pin_b1);  // direction pin low, yön değiştirdik.
hedef  = 3200; //400*8
sayac = 0;
TMR0H = 246;
TMR0L = 60;
T0CON |= 128; //TIMER0 START
while (T0CON >127);// Hareket bitene kadar bekle

output_low(pin_motor_enable);//MOTOR DISABLE
while (1);
}
ve böyle bir kod var fakat bunu nasıl Ccs c ye çevirebilirim bilmiyorum
« Son Düzenleme: 20 Mayıs 2017, 13:01:05 Gönderen: isoment01 »

Çevrimdışı mehmet

  • Global Moderator
  • Profesyonel Üye
  • *****
  • İleti: 2857
  • Modlar da ölümlü...
    • El Feneri
Ynt: pwm ile step motor kontrolü
« Yanıtla #4 : 20 Mayıs 2017, 11:31:08 »
Mesajınıza kod eklemek için "KOD" düğmesini kullanınız.
Mesajlarınızı buna göre yeniden düzenleyiniz.

"Bir mum diğer mumu tutuşturmakla ışığından bir şey kaybetmez.''Mevlânâ
"Kendimiz için yaptıklarımız bizimle birlikte ölür. Dünya ve başkaları için yaptıklarımız ise sonsuza dek yaşar."Albert Pike"
"Kendi kurallarını koymazsan, başkalarının kurallarıyla yaşarsın."M
www.mehmetbilgi.net.tr

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #5 : 20 Mayıs 2017, 13:03:02 »
son olarak kodları  çalışmam sonucu derledim. Fakat doğruluğundan emin olamıyorum.
Kod: [Seç]
#device PIC18F4680
#include <18f4680.h>
#fuses xt,nowdt,noprotect, nobrownout, nolvp, noput, nowrt, nocpd
#use delay (clock=4000000)
#use fast_io(b)
unsigned int16 sayac = 0, hedef = 0;
#int_timer0
void timer0_interrupts()
{
set_timer0(63036);
output_high(pin_b0);
delay_us(20);
output_low(pin_b0);
sayac++;
if(sayac>=hedef)
disable_interrupts(INT_TIMER0);
}
void main()
{
setup_psp(PSP_DISABLED);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_timer_1 (T1_DISABLED);
setup_timer_2 (T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
set_tris_b(0x00);
output_b(0x00);

enable_interrupts(INT_timer0);
enable_interrupts(GLOBAL);
output_high(pin_b3);// motor aktif
delay_ms(100);
output_high(pin_b1);// motor yönü belirlendi
delay_us(50);
hedef=3200; //400*8
sayac=0;
set_timer0(63036);

output_low(pin_b1);
hedef=3200;
sayac=0;
set_timer0(63036);




}
« Son Düzenleme: 21 Mayıs 2017, 01:57:37 Gönderen: isoment01 »

Çevrimdışı Zoroaster

  • Profesyonel Üye
  • *****
  • İleti: 1116
Ynt: pwm ile step motor kontrolü
« Yanıtla #6 : 20 Mayıs 2017, 19:57:15 »
PWM sinyali sadece clock sinyali gibi kullanacağınıza göre PWM parametrelerinin fazla bir önemi yok. PWM duty değerini %50 seçerseniz pals genişliği ne olacaktı sorununu aşmış olursunuz. PWM frekansı ile adımlama hızını ayarlarsınız.

Eğer noktadan noktaya hareket etmek istiyorsanız bu durumda kaç tane pals çıkacağını belirlemek kalıyor. Bunu yazılımla izlemek zorundasınız. İstediğiniz sayıda pals cıktıgında derhal sinyali kesecek yapılandırmayı kurmanız gerekiyor.

Yok motor DC motor gibi dönsün devir sayısını ayarlayayım diyorsanız bu durumda bu kontrolle de işiniz olmayacak pwm palslerin sadece frekansını ayarlama ile uğraşacaksın.

Tam adım modunda 200 clock, 1 tur dönmeye neden olacağına göre M mikrosteplik bir sürücüde motorun 1 deviri  200*M palsde tamamlanır.

Bu durunda devir sayısı N= f/(200*M) dev/sn olur.

Devir Dakika cinsinden devir sayısı N=0.3*f/M dev/dak

F Hz olarak Pwm frekansı
M mikrostep sayısı
N dev/dak olarak devir sayısı
« Son Düzenleme: 20 Mayıs 2017, 19:59:22 Gönderen: Zoroaster »

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #7 : 21 Mayıs 2017, 01:21:11 »
PWM sinyali sadece clock sinyali gibi kullanacağınıza göre PWM parametrelerinin fazla bir önemi yok. PWM duty değerini %50 seçerseniz pals genişliği ne olacaktı sorununu aşmış olursunuz. PWM frekansı ile adımlama hızını ayarlarsınız.

Eğer noktadan noktaya hareket etmek istiyorsanız bu durumda kaç tane pals çıkacağını belirlemek kalıyor. Bunu yazılımla izlemek zorundasınız. İstediğiniz sayıda pals cıktıgında derhal sinyali kesecek yapılandırmayı kurmanız gerekiyor.

Yok motor DC motor gibi dönsün devir sayısını ayarlayayım diyorsanız bu durumda bu kontrolle de işiniz olmayacak pwm palslerin sadece frekansını ayarlama ile uğraşacaksın.

Tam adım modunda 200 clock, 1 tur dönmeye neden olacağına göre M mikrosteplik bir sürücüde motorun 1 deviri  200*M palsde tamamlanır.

Bu durunda devir sayısı N= f/(200*M) dev/sn olur.

Devir Dakika cinsinden devir sayısı N=0.3*f/M dev/dak

F Hz olarak Pwm frekansı
M mikrostep sayısı
N dev/dak olarak devir sayısı
hocam şimdi  hesabımı anlatayım;
1 metrelik bir mesafem var ve 20 mm lik yarıçaplı bir tekerleğim var tekerlek bir turda 0.125m gidiyor o zaman 1 metreyi 8 turda tamamlamış oluyor. motor ve tekerlek eş merkezli bu yüzden motorda 8 tur atacak ve ben bu 8 turu 8 saniyede tamamlamasını istiyor isem 60 rpmlik bir motor elimde olur buradan söyle bir hesap yaptım;
60 rpm x 400 ( half step) / 60 bana saniyedeki puls adedini veriyor.
buradan 1 saniyede 400 pulse üretmen gerektiği belli oluyor.
o zaman 2.5 ms de bir pulse üreteceğim;
frekansımda 400 hz. oluyor.
 şimdi 8 tur attırmam gerek bir timer kullanırsam 3200 üncü pulse kadar timer işlemeli ve kapanmalı sonra ters yönde tekrar 3200. pulse kadar gidip gelmeli ve timer kapanmalı.
bunu kafamda dizayn ettim fakat kodsal olarak timer aç kapa yapmayı bilmiyorum. Yukarda ccs c dilinde bir program yaptım ama doğruluğundan emin değilim. Eger bu noktada kodumdaki hataları bana söylerseniz büyük mutluluk duyarım. Ptesi sunumum var. :(
ek olarak 400 hz lik bir pwm sinyali üretirsem. duty cyle ı %50 cevrımle calıstırmamın bana ne kolaylık sağlayacağını anlamadım hocam.
sorularıma cevap verirseniz duacınız olurum.

Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #8 : 23 Mayıs 2017, 02:44:22 »
Yardımcı olabilecek arkadaşlar varsa kodlarımı büyük ölçüde tamamladım bazı hususlarda eksiklerim var onları sorabilirim.

Çevrimdışı Zoroaster

  • Profesyonel Üye
  • *****
  • İleti: 1116
Ynt: pwm ile step motor kontrolü
« Yanıtla #9 : 23 Mayıs 2017, 07:09:06 »
Pwm frekansi yuksekse ve duty abartili olarak %1 yada %99 yapilirsa Clock sinyali kil gibi incecik olur. Ucuz step motor suruculerin girisinde maliyetten kacip yavas opto kullandiklari icin senin kil gibi incecik clock sinyalin optodan gecemez.

%50 yaparsan bu sorunu dert etmen gerekmez. (Surucunun clock girisi ile ilgili teknik verilere bile bakmana gerek kalmaz.)
Bu %50 meselesi kucuk bir tavsiye sadece. Hele hele 400Hz de %1 duty bile hic sorun olmaz.

PWM Timer 400 Hz de calisacak. Timer Int rutininde Clock Sayici diye bir degiskeni 1 artiracaksin. 3200 oldugunda kullandigin dilde Timeri on/off eden bir fonksiyon kesin vardir onu arastir. Ya da dogrudan PWM timerin registerlerinden on off bitini degistireceksin.

Kullandigin cipin dokumaninda bu registerdan bahsediliyordur. Fakat C/Basic vs dillerde PWM ile ilgili fonksiyonlarda Timer On/Off yapan bir fonksiyon kesin vardir.






Çevrimdışı isoment01

  • Müdavim
  • ***
  • İleti: 56
Ynt: pwm ile step motor kontrolü
« Yanıtla #10 : 23 Mayıs 2017, 07:26:13 »
Pwm frekansi yuksekse ve duty abartili olarak %1 yada %99 yapilirsa Clock sinyali kil gibi incecik olur. Ucuz step motor suruculerin girisinde maliyetten kacip yavas opto kullandiklari icin senin kil gibi incecik clock sinyalin optodan gecemez.

%50 yaparsan bu sorunu dert etmen gerekmez. (Surucunun clock girisi ile ilgili teknik verilere bile bakmana gerek kalmaz.)
Bu %50 meselesi kucuk bir tavsiye sadece. Hele hele 400Hz de %1 duty bile hic sorun olmaz.

PWM Timer 400 Hz de calisacak. Timer Int rutininde Clock Sayici diye bir degiskeni 1 artiracaksin. 3200 oldugunda kullandigin dilde Timeri on/off eden bir fonksiyon kesin vardir onu arastir. Ya da dogrudan PWM timerin registerlerinden on off bitini degistireceksin.

Kullandigin cipin dokumaninda bu registerdan bahsediliyordur. Fakat C/Basic vs dillerde PWM ile ilgili fonksiyonlarda Timer On/Off yapan bir fonksiyon kesin vardir.
hocam pwm i sabit 400 hz e ayarladım 8 sn git gel yaptırıyorum ama nasıl ? :D sayac=0; hedef=80; yapıp hedefe kadar pwm i çalıstıyorum bir yönde sonra diğer yöne gecip diğer yönde de aynısını yaptırıyorum . 0 -80 muhabbetini sadece dene yanıl ile yaptım çok tutarlı birşey gibi durmuyor. Timer ile kurdum onda da timerı kapatmadan sürekli ileri geri 8 sn yaptırıyorum timer'ı saydırıp fakat timer'ı kapatmak istediğimde tekrar nasıl açacağımı bende bilmiyorum. kodlarım da şu şekilde

pwm kod:
Kod: [Seç]
#device PIC18F4680
#include <18f4680.h>
#fuses xt,nowdt,noprotect, nobrownout, nolvp, noput, nowrt, nocpd
#use delay (clock=4000000)
#use fast_io(c)
unsigned int16 sayac = 0, hedef = 0;
int i;

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_2(T2_DIV_BY_16,155,1);      //16,0 us overflow, 16,0 us interrupt
setup_ccp1(CCP_PWM);
set_pwm1_duty(i);
set_tris_c(0x00);
output_c(0x00);
while(1)
{
hedef=80; //400*8
sayac=0;
do
{

i=155;
output_high(pin_c3);// motor aktif
delay_ms(100);
output_low(pin_c1);// motor yönü belirlendi
delay_us(50);
sayac++;
 set_pwm1_duty(i);
}while(sayac<=hedef);
i=0;
set_pwm1_duty(i);
hedef=80; //400*8
sayac=0;
do
{

i=155;
output_high(pin_c3);// motor aktif
delay_ms(100);
output_high(pin_c1);// motor yönü belirlendi
delay_us(50);
sayac++;
 set_pwm1_duty(i);
}while(sayac<=hedef);
i=0;
set_pwm1_duty(i);


}

timer1 kullanarak yaptığım kod:
Kod: [Seç]
#device PIC18F4680
#include <18f4680.h>
#fuses xt,nowdt,noprotect, nobrownout, nolvp, noput, nowrt, nocpd
#use delay (clock=4000000)
#use fast_io(b)
unsigned int16 sayac = 0, hedef_ileri = 0, hedef_geri=0, yon=1;
#int_timer1
void timer1_interrupts()
{

set_timer1(64923);
output_high(pin_c2);
delay_us(20);
output_low(pin_c2);
sayac++;
if(sayac==hedef_ileri)
{
yon=2;
output_low(pin_c1);//motor geri gidiyor
}

if(sayac==hedef_geri)
{

yon=1;
output_high(pin_c1);// motor yönü belirlendi

}
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);      //262 ms overflow      //65,5 ms overflow
setup_timer_2 (T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
set_tris_b(0x00);
output_b(0x00);
set_tris_c(0x00);
output_c(0x00);

enable_interrupts(INT_timer1);
enable_interrupts(GLOBAL);
output_high(pin_c3);// motor aktif
delay_ms(100);
output_high(pin_c1);// motor yönü belirlendi
yon=1;//ileri yon
delay_us(50);
hedef_ileri=3200;//400*8
hedef_geri=6400;
sayac=0;
set_timer1(64923);








   
 


   while(TRUE)
   {
      //TODO: User Code
   }

}





 
« Son Düzenleme: 23 Mayıs 2017, 14:23:39 Gönderen: isoment01 »