pwm ile step motor kontrolü

Başlatan isoment01, 18 Mayıs 2017, 14:56:13

isoment01

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 ?

matador

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.

isoment01

19 Mayıs 2017, 03:16:17 #2 Son düzenlenme: 20 Mayıs 2017, 01:01:54 isoment01
Kod Seç
Alıntı yapılan: matador - 19 Mayıs 2017, 00: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.

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 ?

isoment01

19 Mayıs 2017, 15:43:36 #3 Son düzenlenme: 20 Mayıs 2017, 01:01:05 isoment01
Kod Seç
uint16_t sayac 0hedef 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

mehmet

Mesajınıza kod eklemek için "KOD" düğmesini kullanınız.
Mesajlarınızı buna göre yeniden düzenleyiniz.

nothing

isoment01

20 Mayıs 2017, 01:03:02 #5 Son düzenlenme: 20 Mayıs 2017, 13:57:37 isoment01
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 0hedef 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);




}

Zoroaster

20 Mayıs 2017, 07:57:15 #6 Son düzenlenme: 20 Mayıs 2017, 07:59:22 Zoroaster
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ı
חור השטן יוצא

isoment01

Alıntı yapılan: Zoroaster - 20 Mayıs 2017, 07: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ı

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.

isoment01

Yardımcı olabilecek arkadaşlar varsa kodlarımı büyük ölçüde tamamladım bazı hususlarda eksiklerim var onları sorabilirim.

Zoroaster

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.





חור השטן יוצא

isoment01

22 Mayıs 2017, 19:26:13 #10 Son düzenlenme: 23 Mayıs 2017, 02:23:39 isoment01
Alıntı yapılan: Zoroaster - 22 Mayıs 2017, 19: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.

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 0hedef 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 0hedef_ileri 0hedef_geri=0yon=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
   
}

}