Sabit mesafede değişken hızlı ivmelenme Algoritması

Başlatan Mucit23, 08 Temmuz 2014, 18:13:38

kralsam

Alıntı yapılan: Mucit23 - 10 Temmuz 2014, 23:44:38
Peki Hocam IR2101 lere direk STM32 ile sinyal uyguluyorum. Araya ek bir koruma gereklimidir?
Selamlar hocam,
Frekansına göre uygun bir optocoupler takmanda fayda var. Ama çalışma frekansına dikkat et. Beni bir ara çok uğraştırmıştı. Ben ayrıca MCU kısmınıda DC-DC konvertor ile yalıtıp topraklarıda ayırmıştım. Tavsiye ederim.

İyi çalışmalar.

Erol YILMAZ

Alıntı yapılan: Mucit23 - 10 Temmuz 2014, 23:44:38
Peki Hocam IR2101 lere direk STM32 ile sinyal uyguluyorum. Araya ek bir koruma gereklimidir?

Sinyalleri bozmayacak şekilde araya 2k2 lık bir direnç olabilir.

Mucit23

2K2  Direnç güzel olur. Ekleyeceğim.

Dün saat 15:00 da verdiğim IR2101 siparişim bugün saat 12:00 civarı kapıma geldi.  Kargocuları alkışladım.  :D Ben yetişirse yarın yoksa pazartesi anca alırım diye umut ediyordum.

hasankara

Direnç olarak ben her kanala 120 ohm seri bağladım. Tepki suresi gecikmeye başlayabilir fazla değer takarsan. Çok farkını goremeyebilirsin belki uç noktalarda yani ilk başta veya en sonda pwm uygularken farklılık görülebilir diye düşünüyorum. Ama minimum bir 100 ohm civarı takmak gerekiyor. Denetleyici çok fazla gurultu alabiliyor çünkü ben bizzat yaşadım. Denetleyici 5 Sn de bir reset atabiliyordu direk bağlayınca.

Bende istanbula geldiğim için şimdi gördüm yazını.

Mucit23

Mosfet sürücü için kartımı hazırladım.

Akşama çalışmalara devam edeceğim

Mucit23

Arkadaşlar konuya herhangi bir çözüm getiremedim. Sorumu tekrarlamak istiyorum.

iki adet değişken değerim var.

1. PWM duty değerim, 0-1000 arası bir değer alabiliyor.
2. Encoderden gelen pals'ların sayısının tutulduğu Enc_Count. Bu değerde motor döndüğü sürece sürekli artıyor.

Amacım tam olarak öyle

Bir start butonum var. Bu butona bastığım zaman Duty artmaya başlayacak. Motor dönmeye başladığı zaman Encoder değeride artmaya başlıyor. Bu duty arttırma işlemini Enc_Count değerine göre yapmalıyım. Yani arada Duty Değerini öyle bir arttırmalıyımki Duty değeri 800 olduğunda Enc_Count Değerim 2000 olsun.

Bu dediğim değerler örnektir ve Artışın lineer veya logaritmik olması önemli değil.

Ağır matematiksel işlemler kullanamam.

Belki Encoderin Anlık değeriyle Set değeri arasındaki fark'dan yola çıkarak birşeyler yapılabilir fakat nasıl yaparım bilmiyorum. Sabahtan beri kağıt kalemle karalama yapıyorum Arada bir bağıntı kuramadım bir türlü. Değişik fikirlere ihtiyacım var.

ete

Bu iş bilmece gibi bir şey. Aklıma bir yol geliyor ama bu yolu uygulayabilmek için bazı şeylerin bilinmesi gerekiyor.
Encoder 2000 sayında duty değeri 800 olacak ise birim duty değeri başına encoderin 2,5 sayması yada enocderin 2,5 değeri karşısında duty değerinin 1 artması gerekecektir. Bu durumda duty=1 değerini verip encoderin 2,5 saymasını beklemek yada duty=2 değerini verip encoderin 5 saymasını beklemek gerekecektir.
Önce elimizdekilere bakmamız gerekiyor. Motor sıfır duty ile kalkışa geçmeyecektir. O halde motorun dönmesi için min duty değerini kendimiz verelim. Sonuçta Enc_Count=2000 olunca Duty=800 olması gerektiği için aralarındaki ilişki Enc_Count değeri duty değerinin 2,5 katı diyebiliriz. O halde ,
Duty değerini 2 ile başlatıp belirli bir noktaya kadar bu duty değerini biz artıralım. Adımlar şöyle olabilir;
- Duty=2 , ile başlayıp Enc_Count=5 oluncaya kadar bekleyelim, olunca
- Duty=4 yapalım ve Enc_Count=10 oluncaya kadar bekleyelim, olunca
- Duty=6 yapalım ve Enc_Count=15 oluncaya kadar bekleyelim, olunca
- Bu şekilde duty değerini 2 şerli olarak artıralım ve Enc_Count değeri (Duty*2,5 ) oluncaya kadar bekleyelim.
Motor belirli bir hıza ulaşınca artık duty için biz değer belirlemeyelim ve Enc_Count değerinden değer alalım. Kısaca Duty=Enc_Count/2,5 şeklinde hesaplansın.

Bu açıklamaya göre işi 3 safhalı bir iş olarak görebiliriz.
1. Safhada , Duty değerini sen belirleyecek ve buna karşılık Enc_Count değerinin Duty*2,5 olmasını bekleyeceksin.
2. Motor belirli bir hıza ulaşınca  artık Enc_Count değerine bakılarak karşılığında Duty=Enc_Count/2,5 formülüne göre duty değeri belirlenecektir. Bu işin 2. safhasını oluşturacak ve ,
3. Sonuçta Enc_Count değerinin 2000 değerine ulaşıp ulaşmadığı kontrol edilerek ulaşınca işlem tamamlanacaktır.

Ete

Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Mucit23

Hocam bu yöntem üzerinde biraz çalıştım ama şöyle bir sıkıntı yaşadım. Bunu çözersem olur.

Duty Değerim 0-1000 arası bir değer alıyor ama motor ilk kalkışı ortalama 80-90 ile yapıyor. Ben genellikle motora %10 duty yani sayısal olarak 100 vererek kaldırıyorum.

Hatırlarsanız daha önceden 4000 ile örnek vermiştim ve 4000 puls'lık mesafe içerisinde %80 duty'ye ulaşmak için 4000/80=50 yani encoder'deki her 50 puls'lık bir artışın sonunda duty değerimi 1 arttırmam gerekiyordu.

Bunu denedim şöyle bir sıkıntı yaşadım.

Motor yavaş dönüyorkan enkoderdeki 50'lik artışları tespit edebiliyorum. Fakat motor hızlandıkça encoder değerini bir okumamla diğer bir okumam arasında bakıyorum enkoder değeri 120 artmış. Motor birazdaha hızlanıyor bakıyorum bir önceki okumamla yeni okumam arasında 355 fark var.
İşlemci 72Mhz'de çalışmasına rağmen bu sonuçları aldım.

Yukarıdaki değerler örnek fakat işin aslı şudurki kullandığım mcu hızından dolayı bu işi takip edemiyor.


Şöyle birşey aklıma geldi.

Farzedelim Encoder Set değerimiz 2000 olsun ve Hedeflenen duty değerimizde 800 olsun. O halde 2000/800'den 2,5 artışta duty değerini 1 veya her 5 artışta duty değerini 2 arttırmak gerekli. 

Dedimki bir önceki okuduğum encoder değerini bir değişkende tutayım ve yeni encoder değerinden çıkartarak aradaki artış miktarını bulayım. Buna fark diyelim.

Fark Değerini ilk kez okuyoruz ve baktık Fark değerimiz 30 oldu. Bu durumda (30/5)*2=12 yapar. Yani duty değerine 12 ekledik.

Bir sonraki okumamızda fark değerini 67 bulduk.  67 değeri 5'e tam bölünmez. Ama biz 5'e tam bölünen kadar bir artış yapmamız gerekli. Yani (65/5)*2=26 değer arttırdık. Fakat 67 değerinin 5'e bölümünden kalan 2 puls'lık bir elde değeri var. Bu değer Sonuç olarak kayıptır. Bunu nasıl değerlendiririm? Bu işlemi tekrar denemek istiyorum.

hasankara

#38
if(timer_flg)
{
duty++;
timer=0;
timer_flg=0;
}
else if(enc_flg&&duty>50)
{
duty=(enc*8)/20;
timer=0;
enc_flg=0;
}


duty değerine direk hüküm edebildiğin için kontrol algoritmalarına ihtiyacın olmayabilir, belki ilk kısım için kontrol algoritması kurulabilir, zaten ilk kısmı ilk anda harekete başlayabilmesi için gerekiyor. motorun yükü değişkenlik göstermeyecekse ve problemin bundan ibaretse bu ufak kod işini görebilir. motor yükü değişkenlik gösterecekse, duty fullemene rağmen motorun dönmemesi bile ihtimaller arasında olmalı.

enc_flg bayrağı, enc değerinin güncellenmesiyle birlikte sürekli set edilir. timer hızını ve duty>50 kısmını kendin, motora göre ayarlaman gerekir. yinede bi tutarsızlık var gibi, özellikle ilk parça ile ikinci parçanın arasında bir uyumsuzluk olabilmesi muhtemel gibi ama bu problemin için aklıma pek fazla bir şey gelmiyor.

rotanı duty-enc yerine hız-zaman şeklinde belirler isen daha sağlıklı bir hedefin olmuş olabilir. her şey güllük gülistanlık olabilir. hayattan daha çok zevk alabilirsin.



mesaj birleştirme:: 20 Temmuz 2014, 16:57:11

else if(enc_flg&&enc>200&&duty>50)
bu satır böyle olsun. 200 değerini yine motora göre kurcalayacaksın.

Mucit23

Hasan hocam sizin kodları inceliyorum. Fakat sizin kodlardan önce ete hocamın bahsettiği yöntem üzerine çalışıyordum.

yaptım oldu

int old_counter=0,carry=0,increment=0,fark=0;
	 uint16_t duty=100;
	 set_adc_pwm(duty);
   while(Encoder_GetCounter()<2000)
	 {
		  fark=(Encoder_GetCounter()-old_counter)+carry;
		  old_counter=Encoder_GetCounter();
		  carry=fark%25;
		  increment=fark/25;
		  duty+=increment*10;
		  set_adc_pwm(duty);
   }


Böyle birşey oldu.

Fakat aklıma yatmayan bir iki nokta var. 1. Bu yöntemde duty arttırımı tamamiyle encoderin artmasına bağlı. Mesela ilk başta Duty değerini 100 veriyorumya motor boştaken dönüyor. Döndüğü zaman hızlanıyor ve max hıza ulaşıyor.

Fakat start işlemi yapmadan elimle motor biraz milini sıkıştırıyorum motor duty değeri 100 olduğu için hafif bir sıkışma ile dönemiyor. Dönmeyince encoder artmıyor ve motorun duty değeri artmıyor.

Pek aklıma yatmadı bu yöntem. Bu işi ters yapıyorum gibime geliyor. Bence duty değeri ne olursa olsun artacak. Yani encoderden bağımsız olarak Hedefe yani 800'e doğru artacak. Fakat artım oranı değişmesi gerekiyor sanırım. Yani Encoderin Set değeriyle arasındaki fark çok fazla ise duty'değeri onar onar artacak. Fark az ise birer birer artacak. Tam olarak emin değilim ama bunun üzerindede düşünmek lazım.

Hasan hocam Timer değişiklik kesmesini kullanmıyordum ama sizin mesajınızı okuyunca aklıma geldi. Biraz bakayım bu konuya

Valla işi gücü bırakıp basit bir for döngüsü kurasım var.

RaMu

Program yeterince hızlı çalışmıyorsa
aslında asmde yazmalısın
ama asmye gelene kadar
algoritmanı daha hızlı çalışacak hale getirebilirsin,
misal
Encoder_GetCounter() fonksiyonunun aldığı değer 3 defa kullanılmış
ve her seferinde fonksiyon çalıştırılarak bu değer öğrenilmiş,
bu şuna benziyor
lcd nin 2,1 karakterini kullanmam lazım
bunun için 3 defa lcd den bu değeri okuyorum
bunun yerine bir defa okuyup bu değeri bir değişkene atsam ve 3 defa kullansam
programım daha hızlı çalışır,
yani şöyle

//   Encoder_GetCounter() fonksiyonunda bu fonksiyonun döndüreceği değer
//encoder_deger değişkenine yazılır.

   while(Encoder_GetCounter()<2000)
     {
          fark=(encoder_deger-old_counter)+carry;
          old_counter=encoder_deger;
          carry=fark%25;
          increment=fark/25;
          duty+=increment*10;
          set_adc_pwm(duty);
   }


Ayrıca çarpma işlemini varsa denetleyicinin donanımsal çarpma ünitesi yapıyormu
yani derleyici bunu sağlıyormu kontrol etmek lazım,
donanımsal çarpma tek komut çevriminde yapılabiliyor,
aksi halde donanımsala nazaran çok uzun sürebilir, kaydırma ile çarpma yapılıyor.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html