Yazılımsal pwm+timer1

Başlatan ziyaretci, 20 Mayıs 2015, 12:29:13

ziyaretci

Merhaba, fırçasız motor sürücü için 50Hz periyotta yazılımsal pwm oluşturdum. Analog girişten pot ile sürüyorum.

  Sorun şu ki, 4.55V 'dan sonra saçmalıyor. 4.55V'a kadar her şey normal.
  Şunuda denedim, yazılımda 4.60V 'un dijital karşılığını işleme aldım, yine sorun oluşuyor. 4.50V 'un dijital karşılığını işleme aldım herşey normal.

Kullandığım işlem şu şekilde;
unsigned int16 okunan=0,x=0;
x =  65535-(okunan * 19.55034213098729227761485826002); /*"okunan" değişkeni 950 olduğunda sorun yok, 960 olduğunda sanki "(okunan * 19.55034213098729227761485826002)" sonucu 65535 'den fazla oluyor gibi çıkış sapıyor.*/
 

 

Gökhan BEKEN

Hocam benim bildiğim onun adı PWM değil PPM oluyor. Voltaj 4volt da olsa 3 volt da olsa birşey değişmiyor.
Önemli olan sizin verdiğiniz kare dalga. Yanlış mı biliyorum?
Özel mesaj okumuyorum, lütfen göndermeyin.

tekosis

virgülden sonraki haneleri azaltıp deneseniz. mesela çarpan 19.55 olsa ne olacak bakar mısınız?
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

ziyaretci

#3

Alıntı yapılan: Gökhan BEKEN - 20 Mayıs 2015, 12:34:30
Hocam benim bildiğim onun adı PWM değil PPM oluyor. Voltaj 4volt da olsa 3 volt da olsa birşey değişmiyor.
Önemli olan sizin verdiğiniz kare dalga. Yanlış mı biliyorum?
Haklısınızdır hocam ben yanlış biliyorumdur, kusura bakmayın. Hani işlevleri benzer o yüzden o şekilde bir ibare kullandım. Değiştiriyorum.

mesaj birleştirme:: 20 Mayıs 2015, 12:45:12

Alıntı yapılan: tekosis - 20 Mayıs 2015, 12:41:30
virgülden sonraki haneleri azaltıp deneseniz. mesela çarpan 19.55 olsa ne olacak bakar mısınız?

Aynı hocam değişen birşey yok.

Ek olarak math.h dosyasındaki ceil ve floor 'u da denedim sonuç yine aynı.

mesaj birleştirme:: 20 Mayıs 2015, 12:50:37

Tam sayı oldumu sıkıntı olmuyor. Fakat çözünürlük düşüyor.

mesaj birleştirme:: 20 Mayıs 2015, 12:56:28

Neyse artık olacak o kadar 19 olarak işleme alacağım. Yine bir çözüm bulan olursa sevinirim.

RaMu

x =  65535UL- (unsigned int16) ( (float) okunan * 19.55034213098729227761485826002)  ;

Şeklinde kullanabilirsin daha garanti olur.
Ama programın bu kısmında sorun olduğunu düşünmüyorum,
programın devamında yapılan işlemlerde problem olabilir.

Birde 19.55034213098729227761485826002
bu değerin bu kadar virgülden sonrasının bir işe yarayacağını düşünmüyorum,
hatta problem çıkarıyorda olabilir.
19.55034 şeklindede denenebilir.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

Alıntı yapılan: erkantr67 - 20 Mayıs 2015, 12:42:56
Haklısınızdır hocam ben yanlış biliyorumdur, kusura bakmayın. Hani işlevleri benzer o yüzden o şekilde bir ibare kullandım. Değiştiriyorum.
Hocam kusura bakmayın, çok özür dilerim, ppm'i araştırdım da yanlış kalmış aklımda.
Özel mesaj okumuyorum, lütfen göndermeyin.

ziyaretci

#6
Alıntı yapılan: RaMu - 20 Mayıs 2015, 13:00:04
x =  65535UL- (unsigned int16) ( (float) okunan * 19.55034213098729227761485826002)  ;

Şeklinde kullanabilirsin daha garanti olur.
Ama programın bu kısmında sorun olduğunu düşünmüyorum,
programın devamında yapılan işlemlerde problem olabilir.

Birde 19.55034213098729227761485826002
bu değerin bu kadar virgülden sonrasının bir işe yarayacağını düşünmüyorum,
hatta problem çıkarıyorda olabilir.
19.55034 şeklindede denenebilir.

Hocam yazılımın bundan sonrasında timer1 kesmesi içerisinde sırayla lojik 1 ve lojik0 süresini ayarlıyorum. Hatta timer1 kesme içeriğini vereyim.

Void analog_oku(){  
okunan = read_adc();
if(okunan==0)okunan=1;
sayi = okunan * 19;
talep_duty_high  = 65535-sayi; 
talep_duty_low = 45535+sayi;
s=1;
}


#int_timer1
Void kesme(){
if(s==1){ 
if(g==0){output_high(sinyal_ucu);set_timer1(talep_duty_high); g=1;}else
if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0; s=0;}
 }
}


Ana menüdede sonsuz döngü içerisinde ilk ve her periyot tamamlanınca analog okuma alt programına gidiyorum.

Hatta acaba dijital veri maksimum değer olmuyor mu diye düşündüm, o da oluyor, analog veriyi okuduktan sonra if(okunan==1023) ise pini lojik1  değilse lojik sıfıra çekiyorum. Bu sağlamada da sorun oluşmadı güzel okuyor.

Programda başka birşey yok işlem sorun oluşturuyor gibi.
Vediğinizi deniyorum birazdan sonuç bildiririm.

Belki simülasyondan da kaynaklanabilir.

mesaj birleştirme:: 20 Mayıs 2015, 14:30:01

Denedim hocam değişmedi durum.

mesaj birleştirme:: 20 Mayıs 2015, 14:32:46


Void main(){    
setup_timer_2(T2_DISABLED,0,1);  // t2 kapatıldı.
setup_CCP1(CCP_OFF);   // ccp1 kapatıldı.
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 ayarları yapılıyor
set_timer1(0); // TMR1 değeri belirleniyor 
enable_interrupts(INT_timer1); // int_timer1 kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
SETUP_ADC(ADC_CLOCK_INTERNAL | VSS_VDD); 
SETUP_ADC_PORTS(sAN0); // ANALOG GİRİŞ UCU 
SET_ADC_CHANNEL(0);
delay_us(20);

For(;;){

if(s==0)analog_oku();

 }
}


PIC16f690

RaMu

#7
Hocam  projeyi simulasyonla beraber zipleyip gönderin inceleyeyim,
böyle parça bölük zor oluyor.

mesaj birleştirme:: 20 Mayıs 2015, 15:17:43

sayi = okunan * 19;
...
talep_duty_low = 45535+sayi;

65 535-45 535=20 000
20 000 / 19 = 1052.6

yani okunan 1053 veya daha büyük olursa
sayi = okunan * 19;                 //sayi=1053*19=20 007
...
talep_duty_low = 45535+sayi;  //talep_duty_low = 45535+20 007 = 65542 
                                                  //oda taşma yapıp  (65542-65535=7) 7 olur.

Yani okunan 960 değil 1060 olunca sorun oluyor bence.

mesaj birleştirme:: 20 Mayıs 2015, 15:28:31

projenin .h dosyasında
#device ADC=16 ise
#device ADC=10

yapıp deneyebilir misin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

ziyaretci

#8
1023 den fazla olamaz ki, 10 bitlik adc ayarlı.

mesaj birleştirme:: 20 Mayıs 2015, 17:49:55

Ki ek olarak yukarıda biraz deyindim, adc okuduktan sonra if(okunan==1023) ise b6 pinini high yaptım. Pwm pini olarak b7 ayarlı.

Ve ben potansiyo metreyi sona dayadığımda(5V) b6 pini high oldu. Onun sağlaması tamam sorun yok orada.

sayi = okunan *19 iken maksimum duty oranı aşağıdaki gibi. Sadece 600us açık oluyor.


#include <16f690.h>
#device ADC=10
#fuses XT,NOPROTECT,NOBROWNOUT,NOMCLR,NOCPD,NOWDT,NOPUT,NOIESO,NOFCMEN
#use delay(clock=4M)

// analog giriş ucu an0
#define sinyal_ucu  pin_b7

unsigned int16 okunan=0,talep_duty_high=0,talep_duty_low=0,sayi=0;  
          int1 s=0,g=0;

   
  
Void analog_oku(){  
okunan = read_adc();
if(okunan==0)okunan=1;
sayi = okunan * 19;
talep_duty_high  = 65535-sayi; 
talep_duty_low = 45535+sayi;
s=1;
}

#int_timer1
Void kesme(){
if(s==1){ 
if(g==0){output_high(sinyal_ucu);set_timer1(talep_duty_high); g=1;}else
if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0; s=0;}
}else{ set_timer1(0);}
}

Void main(){    
setup_timer_2(T2_DISABLED,0,1);  // t2 kapatıldı.
setup_CCP1(CCP_OFF);   // ccp1 kapatıldı.
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer0 ayarları yapılıyor
set_timer1(0); // TMR0 değeri belirleniyor 
enable_interrupts(INT_timer1); // int_timer0 kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
SETUP_ADC(ADC_CLOCK_INTERNAL | VSS_VDD); 
SETUP_ADC_PORTS(sAN0); // ANALOG GİRİŞ UCU 
SET_ADC_CHANNEL(0);
delay_us(20);

For(;;){

if(s==0)analog_oku();

 }
}


mesaj birleştirme:: 20 Mayıs 2015, 18:39:44

Şimdi aklıma bir şey geldi, çok kuvvetli bir şüphe duyuyorum hatta.

----
Biz uç noktaya yaklaştığımızda low duty oranı için ayarladığım timer süresi kısaldığında muhtemelen analog okuma işlemi yarıda kalıyor. Veya işlem(hesap) yarıda kalıyor. Bundan dolayı olabilir. Şimdi yazarken düşünüyorum dahada bir kuvvetlendi bu şekilde olması.
  Çözümü her periyot bittiğinde timer 'ı pasif yapıp işlem tamamlandığında tekrar aktif yapmak gerekecek galiba.
  En kısa süre içerisinde deneyip sonucu yazarım.

RaMu

#9
s i devre dışı bırak.

main de
//if(s==0)analog_oku();  //yerine
analog_oku();


kesmede
//if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0; s=0;}  //yerine
if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0;}


mesaj birleştirme:: 20 Mayıs 2015, 18:57:03

Alıntı yapılan: erkantr67 - 20 Mayıs 2015, 17:46:02
sayi = okunan *19 iken maksimum duty oranı aşağıdaki gibi. Sadece 600us açık oluyor.
(Resim gizlendi görmek için tıklayın.)
Bu açık oluyor dan kasıt nedir?
Fotoya göre pin_b7 neredeyse tüm süre boyunca high 1 oluyor zaten.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

ziyaretci

Alıntı yapılan: RaMu - 20 Mayıs 2015, 18:47:22
s i devre dışı bırak.

main de
//if(s==0)analog_oku();  //yerine
analog_oku();


kesmede
//if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0; s=0;}  //yerine
if(g==1){output_low(sinyal_ucu); set_timer1(talep_duty_low); g=0;}


mesaj birleştirme:: 20 Mayıs 2015, 18:57:03
Bu açık oluyor dan kasıt nedir?
Fotoya göre pin_b7 neredeyse tüm süre boyunca high 1 oluyor zaten.

Hocam açık oluyordam kastım, normalde hesaplamalara göre 5V girişte 20ms boyunca lojik 1 olması. Katsayıyı 19 olarak alırsam 5V girişte 19.4ms lojik 1 'de kalıyor, 600us hesabın dışında kalıyor o yüzden.

Ek olarak kaldırmamı söylediğiniz "s" anahtarını kaldırmak bir sonuç vermez. Ben onu her periyot analog okusun diye koydum.

RaMu

Tamam şimdi anladım problemi,
sen istiyorsun ki max dereceye (pot 5V)
gelindiğinde us bile şaşmadan çıkış sürekli high olsun.

Evet s in pek bir etkisi olmaz bu durumda.

Biraz düşüneyim yazarım tekrar.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

ziyaretci

#12
Alıntı yapılan: RaMu - 20 Mayıs 2015, 22:09:19
Tamam şimdi anladım problemi,
sen istiyorsun ki max dereceye (pot 5V)
gelindiğinde us bile şaşmadan çıkış sürekli high olsun.

Evet s in pek bir etkisi olmaz bu durumda.

Biraz düşüneyim yazarım tekrar.
Hocam bu "us" mutlaka olacak gibi geliyor bana, çünkü 65535-19 olsa, 4MHz için 19us ' de analog okumada veya duty hesaplaması bitmez gibi geliyor. Her ne kadar bütün hesaplamalar bittikten sonra sayıcıyı başlatsam bile yine yetişmiyor maksimum değer için.

Son çare 19.4ms 'den üssü değerleri direk lojik 1 olarak kabul edeceğim, veya böyle kalır yine iş görür.

mesaj birleştirme:: 20 Mayıs 2015, 22:21:36

Ama düşünmeye devam edeceğim.