encoder pals okumada bu kod doğru mu?

Başlatan zamzam23, 01 Temmuz 2011, 16:17:03

zamzam23

motoru 16khz pwm ile sürüyorum encoder 150 palslik. sorun pals kacırması değil kacırsın mühim de değil o kdr ama sacmalaması kötü. bazen oluyor ki pic kilitleniyor

iyildirim

Zamzam23,
Senin kesmen hangi kenarda tetikleniyor.  ?

Haklı olabilirsin,  şimdi baktım da düşen kenarda and kullanmak hatalı sonuç üretebilir. Tek yönde sayma yapar.

Genel olarak xor kullanmak çözüm olur.

konunun başında verdiğin programı denemek istersen kesme yükselen kenarda olacak şekilde bir dene.. 
Xor kullanırsan her iki kenarda da çalışması lazım.

Sanmıyorum ama sorun devam ederse, sorunun kaynağı camby'nin dediği gibi kesme kaçırmak olabilir. Filtreleme vs. gerekebilir. Quadrature encoder modülü olan bir işlemcinin encoder modülünü incelersen filtre vs. yapısı hakkında bilgi verebilir.

zamzam23

ben ne xor kullandım ne and. sadece pinlerin durumuna bakarak pals i artırdım yada azalttım. pals zaten kacırıyor 150 lik encoder 1 turda 135 pals veriyor bu muhim değil yeterki sapıtmasın

Tagli

Ben sadece RB0 kesmesi kullanarak sağlıklı bir sonuç elde edilebileceğine inanmıyorum. Çünkü hareket iki bacaktan herhangi birisi değiştiği zaman oluyor. Öyle sanıyorum ki senin yaklaşımında encoder çözünürlüğünü %25'e düşürürsün, yani 4 hareketten sadece 1'ini yakalarsın.

Alıntı yapılan: Tagli...bu durumda hem dusen hem de yukselen kenarlarda kesmeye gitmen gerekir ki yanlis hatirlamiyorsam bu mumkun değil.
Bu konuda yanılmışım. Kesme kodu içinde kenar ayarı yapılabilir, bunda sorun olacağını sanmıyorum. PORTB değişim kesmesi yerine RB0 kesmesi kullanmak istiyorsan, A ve B çıkışlarını bir XOR kapısına sokarsın. kapının çıkışını da RB0 bacağına verirsin. Düşen kenarda kesme geldiğinde örneğin OPTION_REG'i (veya aynı işi yapan neresi varsa) yükselen kenarda kesme oluşturacak şekilde değiştirirsin, diğer durumda da tam tersi. A ve B XOR kapısının yanı sıra PIC'in de 2 bacağına girer. Bundan sonrası zaten daha önce vermiş olduğum mantıkla aynı.

Ama yine tekrar edeyim: Hiç uğraşma, PORTB kesmesi kullan, rahat et.
Gökçe Tağlıoğlu

zamzam23

tamam çıkıs noktam galiba burası. 18F serisinde RB0 kesmesi hem dusen hem de yukselern kenarda olabılıyormu bunu bulmam gerek eger oluyorsa bu ıs olur gibime geliyor.olmazsa mecbur RB kesmesi yapıcaz

iyildirim

#20
Alıntı yapılan: zamzam23 - 02 Temmuz 2011, 02:56:25
ben ne xor kullandım ne and. sadece pinlerin durumuna bakarak pals i artırdım yada azalttım. pals zaten kacırıyor 150 lik encoder 1 turda 135 pals veriyor bu muhim değil yeterki sapıtmasın

Zamzam23,
Darbelerin yapısına, grafiğine bakarsan sende göreceksin.

Eğer düşen kenarda kesme oluştu ise rb0 low olacak anlamına gelir.  Aynı şekilde yükselen kenar da ki kesmede rb0 high anlamına gelir.

Diğer pini kesme içerisinde test etmek de bu iki pini and operatörü ile test etmek anlamına gelir. 

Kesme düşen kenarda oluştuğunda RB0 low olmuş demek. Bu durumda diğer pin ne olursa olsun sonuç doğru yada anlamlı  olmayacak.  0 and xx  = 0 olacak daima..

Hangi işlemciyi kullanıyorsun bilmiyorum. Yapabiliyorsan kesmeyi yükselen kenarda oluştur. kesme içerisinde rb0 high olsun.
İlk verdiğin kodu olduğu gibi kullan..

Kesmeyi yükselen kenarda değilde yalnızca düşen kenarda tanımlayabiliyorsan  rb0 low demektir.
bu durumda ,
if (input(pin_c5) ^ 0)

şeklinde c5 pinini sıfır ile xor larsan istediğini vermeli.

and operatörü kullanmak  bir kaç clock daha az kod üretebileceğinden daha iyi olabilir.


Edit
Tagli'nin son mesajını iletiyi gönderdikten sonra gördüm. Ve kanalların hangi pinlere bağlı olduğu ile ilgili kafam karıştı.
Yukarıda kanalın birinin rb0 diğerinin c5 denilen pinlere bağlı olduğunu varsaydığımı söylemeliyim.

Kanallardan birinin yükselen kenarda kesme oluşturabilecek bir pine bağlı olması gerekli ve x1 modda okuma için de yeterli olmalı.


zamzam23

iyildirim
ext_int_edge(H_TO_L); kesmeyi boyle kullanmısım. terside olsa bişi farketmez diye düşünmüşüm. o halde ext_int_edge(L_TO_H); yapıyorum ve aynı kodu kullanıyorum sonucu yazarım yarın.saolun

zamzam23


mufitsozen

#23
Alıntı yapılan: zamzam23 - 02 Temmuz 2011, 08:59:32
hiçbirşey değişmedi sonuc aynı.

Sayin zamzam23,

rotary bir encoder ile yon ve hiz tesbiti yaparken ortaya cikan problemleri bulmaya calisiyorsunuz anladigim kadari ile. Rotary encoder devrelerinde n-bit gray code kullanilir, bunun nedeni eger iki pulse arasinda bir problem olur ise bunu anlamaktir. Cunki grey-code icinde arka arkaya gelen iki deger sadece bir bit degisiklik gosterir, dolayisi ile bir onceki degeri biliyorsaniz bir sonraki degerden saat yonunde yada saat yonunun aksi yonde donus oldugunu anlarsiniz, eger iki arka arkaya okunan deger sirasinda dogru kodlar gelmemisse o zaman pulse kacirdiginiz yada programlama ve/veya mekanik ariza oldugunu vb anlarsiniz. Eger sisteminiz basit ise size iki-bit gray code yeterli olur. iki bit sirasi su sekildedir

00 <-> 01 <-> 11 <-> 10 <-> 00 ......


yenieskiyonu
0010saat
0100saat
1101saat
1011saat
0001saat-ters
0111saat-ters
1110saat-ters
1000saat-ters

bunun disindaki kombinasyonlar hata durumunu belirtir.

simdi diyelimki bu iki bit degeri RB7/RB6 reg icinde aldiniz ve RB her degistiginde bir kesme olustu. (16F877A gibi bir PIC kullandiginiz varsayimi ile)

Kesme'ye geldiginizde soyle bir pseudo kod olusturmaniz lazim:

1- yeni_deger = RB .AND. 0xc0   (RB7-RB6 disindaki bitleri sifirla,)
2- case yeni_deger == 0x00   // == 00 
          if eski_deger == 0x80    // == 10
              pulse++
              donus=e_saat_yonunde
          elif eski_deger == 0x40  // == 01
              pulse--
              donus= e_saatin_aksi_yonde
          else
              /* hata pulse kacirildi, hatayi nasil halledecekseniz program icinde onu yapacaksiniz */
          endif
      case yeni_deger == 0x40          // == 01 ;
          if eski_deger == 0x00    // == 00
              pulse++
              donus=e_saat_yonunde
          elif eski_deger == 0xc0  // == 11
              pulse--
              donus= e_saatin_aksi_yonde
          else
              /* hata pulse kacirildi, hatayi nasil halledecekseniz program icinde onu yapacaksiniz */
          endif
          ........ vs

eger kesme icinde butun bu islemleri yapmak iki kesme arasindaki sureyi asiyorsa, temel olarak yapabileceginiz bir kac programlama yontemi var, bunlarida eger oyle bir durum oldugunu dusunuyorsaniz konusabiliriz. Eger bir logic analyzer yada digital osiloskopunuz var ise basit bir sekilde kesme icinde harcadiginiz zamani gorecek basit bir duzenek yapabilirsiniz. Bunun icin kullanilmayan bir I/O pin bulup kesmeye girer girmez 1 yapin vede kesmeden cikar cikmaz 0 yapin. tercihan dijital bir osiloskop ile motor donerken bu i/o pine bakip iki pulse arasindaki 1 olan sureler  sizin kesmede harcadiginiz sure olacaktir (kaba olarak) bu sekilde donus yonu, pulse artti azaldi degerlerinide kullanilmaya i/o pinlere koyup kesme devresinin neler yaptigini osiloskop ile kontrol edebilirsiniz. (tabii logic analyzer olsa daha kolay/sik olurdu)


tabii bu kodu daha basit ve hizli bir halede getirebilirsiniz (look-up table ile vs)

eger isterseniz hafta sonunda CCS_C ile size bir ornek kod yazmaya calisirim.

kolay gelsin

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

zamzam23

teşekkür ederim zahmet edip örnek kod yazmanıza gerek yok ama PID kontrolünü de timer kesmesi içinde yaptıgım için kesmeler birbirine giriyor dolayısıyla sıkıntı oluyor galiba. süre bazında sıkıntım var dolayısıyla program sacmalıyor. onun dısında rb0 kesmesıyle pasl kacırabılırım evet ama bu benım programımı etkılememesı lazım cok hassas calısmıyorum sonucta. ama rb0 ı bırakıp RB kesmesıne gecebılırım yalnız yıne süre sıkıntım olacak 2 kesme var biri palsleri sayıyor diğeri PID yapıyor.

Burak B

"... a healthy dose of paranoia leads to better systems." Jack Ganssle

camby

Alıntı yapılan: mufitsozen - 02 Temmuz 2011, 13:22:07
Alıntı yapılan: zamzam23 - 02 Temmuz 2011, 08:59:32
hiçbirşey değişmedi sonuc aynı.

Sayin zamzam23,

rotary bir encoder ile yon ve hiz tesbiti yaparken ortaya cikan problemleri bulmaya calisiyorsunuz anladigim kadari ile. Rotary encoder devrelerinde n-bit gray code kullanilir, bunun nedeni eger iki pulse arasinda bir problem olur ise bunu anlamaktir. Cunki grey-code icinde arka arkaya gelen iki deger sadece bir bit degisiklik gosterir, dolayisi ile bir onceki degeri biliyorsaniz bir sonraki degerden saat yonunde yada saat yonunun aksi yonde donus oldugunu anlarsiniz, eger iki arka arkaya okunan deger sirasinda dogru kodlar gelmemisse o zaman pulse kacirdiginiz yada programlama ve/veya mekanik ariza oldugunu vb anlarsiniz. Eger sisteminiz basit ise size iki-bit gray code yeterli olur. iki bit sirasi su sekildedir

00 <-> 01 <-> 11 <-> 10 <-> 00 ......


yenieskiyonu
0010saat
0100saat
1101saat
1011saat
0001saat-ters
0111saat-ters
1110saat-ters
1000saat-ters

bunun disindaki kombinasyonlar hata durumunu belirtir.

simdi diyelimki bu iki bit degeri RB7/RB6 reg icinde aldiniz ve RB her degistiginde bir kesme olustu. (16F877A gibi bir PIC kullandiginiz varsayimi ile)

Kesme'ye geldiginizde soyle bir pseudo kod olusturmaniz lazim:

1- yeni_deger = RB .AND. 0xc0   (RB7-RB6 disindaki bitleri sifirla,)
2- case yeni_deger == 0x00   // == 00 
          if eski_deger == 0x80    // == 10
              pulse++
              donus=e_saat_yonunde
          elif eski_deger == 0x40  // == 01
              pulse--
              donus= e_saatin_aksi_yonde
          else
              /* hata pulse kacirildi, hatayi nasil halledecekseniz program icinde onu yapacaksiniz */
          endif
      case yeni_deger == 0x40          // == 01 ;
          if eski_deger == 0x00    // == 00
              pulse++
              donus=e_saat_yonunde
          elif eski_deger == 0xc0  // == 11
              pulse--
              donus= e_saatin_aksi_yonde
          else
              /* hata pulse kacirildi, hatayi nasil halledecekseniz program icinde onu yapacaksiniz */
          endif
          ........ vs

eger kesme icinde butun bu islemleri yapmak iki kesme arasindaki sureyi asiyorsa, temel olarak yapabileceginiz bir kac programlama yontemi var, bunlarida eger oyle bir durum oldugunu dusunuyorsaniz konusabiliriz. Eger bir logic analyzer yada digital osiloskopunuz var ise basit bir sekilde kesme icinde harcadiginiz zamani gorecek basit bir duzenek yapabilirsiniz. Bunun icin kullanilmayan bir I/O pin bulup kesmeye girer girmez 1 yapin vede kesmeden cikar cikmaz 0 yapin. tercihan dijital bir osiloskop ile motor donerken bu i/o pine bakip iki pulse arasindaki 1 olan sureler  sizin kesmede harcadiginiz sure olacaktir (kaba olarak) bu sekilde donus yonu, pulse artti azaldi degerlerinide kullanilmaya i/o pinlere koyup kesme devresinin neler yaptigini osiloskop ile kontrol edebilirsiniz. (tabii logic analyzer olsa daha kolay/sik olurdu)


tabii bu kodu daha basit ve hizli bir halede getirebilirsiniz (look-up table ile vs)

eger isterseniz hafta sonunda CCS_C ile size bir ornek kod yazmaya calisirim.

kolay gelsin

Hata olduğunu tespit etmekten ziyade olası hatanın min. seviyede tutulabilmesi için bunun yapıldığı biliyorum.

Bahsettiğin devrede Pic girişine gelen sinyaller grey formda mı ? Eğer öle ise grey kod veren encoder'lar var mı yoksa dışarda çevirici mi var ?

Ayrıca kesme kodları çok uzun , 2 bitlik durumda bile 12 if sorgusu oldu , bu şekille kullanılmayabilir . Gray kod konusunu biraz daha açabilir misin ?

ilhan_mkp

camby hocam bildiğim kadariyla artımlı enkoderlrin hepsi gray code birdek mutlak enkoderler var genelde pozisyon ilgisi amacıyl kullanılan

camby



Şu bildiğimiz arttırımlı encoder sinyallerine gray kod deniyormuş , tamam ben yanlış düşünmüşüm. Teşekkürler İlhan uyandırdığın için  ;)

A fazı ve B fazı ozmn 2 bit gray kod oluyor , 3 bitlik yada daha fazla bitlik gray kod kullanılıyor mu arttırımlı encoder' larda ?

@mufitsozen , yukarda sana sorduklarımı hiç yazılmamış kabul edebilirsin :)


ilhan_mkp

ben hiç 3bit 4bit olanını görmedim duymadim şöyle bir mantık yürütebilim plc lerin hızlı sayıcı wizardlarında artımlı encoder için a ve b fazı için giriş vardir yani 2 bit birde z ucu var kaç pls olursa olsun tur başina 1 pals verir ama nun kullanım alanının knuyla pek bir alakası yok sanırım