PLC’de Encoder Pals – mm (Mesafe) Dönüşümü: 3 Farklı Hesaplama Yöntemi

  • Konbuyu başlatan Konbuyu başlatan Mesut
  • Başlangıç tarihi Başlangıç tarihi

Mesut

Onursal Üye
Onursal Üye
Katılım
9 Şub 2007
Mesajlar
799
Puanları
206
PLC’de Encoder Pals – mm (Mesafe) Dönüşümü: 3 Farklı Hesaplama Yöntemi

PLC uygulamalarında sıklıkla ihtiyaç duyulan Encoder Pals - mm (Mesafe) dönüşüm hesaplamaları için pratik ve kullanışlı 3 farklı yöntemi aşağıda derledim.

İhtiyacınıza ve mekanik yapınıza en uygun olan yöntemi seçip projelerinizde uygulayabilirsiniz.

Yöntem 1:

Mekanik ve Pals Oranı ile Temel Hesaplama

Bu yöntem, mekanik turun getirdiği hat ve motor/encoder oranları üzerinden doğrudan dönüşüm sağlar.

Mekanik Hat Tespiti: Encoder’ın 1 tam tur dönmesi sonucunda sistemin aldığı yol (mm cinsinden) belirlenir.

Pals Değeri Tespiti: Motorun 1 tam tur dönmesi karşılığında encoder’ın ürettiği pals miktarı belirlenir.

Formül Uygulaması:

Aktüel Ölçü (mm) = ( Sayıcıdan Okunan Pals Değeri x Encoder 1 Tur MM Değeri ) / Motor 1 Tur Pals Değeri





Yöntem 2:

1 mm’ye Düşen Pals Katsayısı İle Hesaplama

Bu yöntem, doğrudan 1 mm mesafe için üretilen pals miktarını bularak hesaplamayı sadeleştirir.

Örnek Senaryo:

Encoder Çözünürlüğü: 1024 Pals

Encoder 1 tam turunda alınan yol: 10 mm

1 mm İçin Üretilen Pals Hesabı:

1 mm Pals Değeri = 1024 Pals / 10 mm = 102,4 Pals/mm

Aktüel Mesafe Hesabı:

Aktüel Ölçü (mm) = Encoder Pals Değeri (Örn: C247) / 102,4


Yöntem 3:

Saha Ölçümü, HMI Set Değeri ve Noktalı Sayı (Float) İşlemleri

Mekanik hesabı zor olan veya kalibrasyon gereken sistemlerde iki nokta arasındaki reel mesafe ve pals ölçümü ile yapılan yöntemdir.

1. Çarpan (Katsayı) Hesabı:

Sistem başlangıç noktasından bilinen en uzak noktaya ilerletilir ve fiziksel mesafe ölçülür (Örn: 1000 mm).

Bu mesafe katedildiğinde encoder’ın okuduğu toplam pals değeri kaydedilir (Örn: 3250 pals).

Pals / mm Katsayısı (Çarpan):

Çarpan Değeri = 3250 Pals / 1000 mm = 3,25 (1 mm'ye denk gelen pals)

2. HMI Panelden Hedef Mesafeye Gitme:

HMI ekranından girilen hedef mm değerini pals bilgisine dönüştürmek için:

Hedef Pals Değeri = İstenen Mesafe (mm) x 3,25
(Bulunan pals değeri PLC karşılaştırma komutları ile işlenir.)

3. HMI Ekranında Aktüel Mesafeyi Gösterme

Hassas ve küsuratlı hesaplama için tam sayı olan pals verisi kayan noktalı sayıya (float) dönüştürülür:

Encoder sayıcı değeri (örn. C247), DFLT komutu ile float veriye çevrilir:

Komut: DFLT C247 D540 (D540 = Float Pals)

Dönüştürülen pals verisi (D540), önceden bulunan çarpan değerine (D504) bölünür:

İşlem: D540 / D504 = D560 (D560 = Float mm)

Ekran gösterimi veya PLC içi kullanım durumuna göre D560 datası tekrar tamsayıya çevrilebilir:

Komut: DINT D560 D570 (D570 = Aktüel mm)


Sorusu olan veya farklı alternatif fikirleri, çözümleri olan arkadaşların görüşlerini beklerim.
 
Kod:
(* Enkoder motor miline veya redüktör çıkışına bağlıysa hesaplama*)
// Değişkenler
// XAxisFrwPosPerRev  = Redüktör çıkışının 1 turdaki mm ilerlemesi [mm/Tur]
// XEncoderPulseInstalled =  (Motor mili veya redüktör çıkışına)Takılı enkoder pulse sayısı [Pulse / Tur]
// XAxisEncRaw = Enkoderden okunan aktuel ham deger [Pulse]
// XGearRatio = Motor miline bağlı redüktör oranı( i= 10 gibi) [Birimi yok]
// "AxisData".XActualPosition = Eksenin o anki hesaplanan aktuel degeri [mm]

IF "AxisData".XEncoderIsOnMotor THEN // İlk kurulum Makina parametresinden gelir
    // 1. Durum: Enkoder Motor Milinde ise
    "AxisData".XActualPosition := ( "AxisData".XAxisFrwPosPerRev / ("AxisData".XGearRatio * "AxisData".XEncoderPulseInstalled) ) * DINT_TO_REAL("XAxisEncRaw");
 
ELSE
    // 2. Durum: Enkoder Redüktör Çıkışında (Yük Milinde) ise
    "AxisData".XActualPosition := ( "AxisData".XAxisFrwPosPerRev / "AxisData".XEncoderPulseInstalled ) * DINT_TO_REAL("XAxisEncRaw");
 
END_IF;
 
Son düzenleme:
Genelde "AxisData".XActualPosition ile olması gereken pozisyon arasında bir kaçıklık(Offset) vardır, bu değer ekrandan operatöre ayarlattırılabilir. Örneğin "AxisData".XActualPosition = 5mm buranın 0mm olması gerekiyor dendiğinde aşağıdaki işlem yapılır.

Kod:
IF HMI.PozisyonDuzelt THEN // HMI dan pozisyonun X mm degerine ayarlanması (Basıldığında setlenen bit)
   Offset_mm         := HMI.SetİstenenPos - "AxisData".XActualPosition
   PozisyonDuzelt    := FALSE;
END_IF
(* Olması gereken aktuel pozisyon*)
"AxisData".XActualOffsetliPosition := "AxisData".XActualPosition + Offset_mm;
 
Son düzenleme:
Tüm yazdıklarımızı fonksiyon bloğuna çevirirsek.

Kod:
FUNCTION_BLOCK "FB_AxisPositionCalculator"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1

VAR_INPUT
    XAxisFrwPosPerRev       : REAL   := 1.0;  // Redüktör çıkışının 1 turdaki mm ilerlemesi [mm/Tur]
    XEncoderPulseInstalled  : UDINT  := 1024; // Takılı enkoder pulse sayısı [Pulse / Tur]
    XAxisEncRaw             : DINT;           // Enkoderden okunan aktüel ham değer [Pulse]
    XGearRatio              : REAL   := 1.0;  // Motor miline bağlı redüktör oranı (i=10 gibi)
    XEncoderIsOnMotor       : BOOL   := TRUE; // TRUE: Motor milinde, FALSE: Redüktör çıkışında
    HMI_PozisyonDuzelt      : BOOL;           // HMI pozisyon kalibrasyon tetikleyicisi
    HMI_SetEdilenPos        : REAL;           // HMI üzerinden istenen pozisyon [mm]
END_VAR

VAR_OUTPUT
    XActualPosition         : REAL;           // Eksenin o anki hesaplanan ham aktüel değeri [mm]
    XActualOffsetliPosition : REAL;           // Offset eklenmiş son pozisyon [mm]
END_VAR

VAR
    Offset_mm               : REAL := 0.0;    // Kalibrasyon offset değeri (Kalıcı olmalıdır)
    R_Trig_Duzelt           : R_TRIG;         // HMI butonunun kenar tetikleyicisi
END_VAR

BEGIN
   
    // --- 1. Aktüel Pozisyon Hesaplama ---
    IF XEncoderIsOnMotor THEN
        // 1. Durum: Enkoder Motor Milinde ise
        // Bölme hatası (division by zero) olasılığına karşı güvenlik kontrolü eklenebilir
        IF (XGearRatio * UDINT_TO_REAL(XEncoderPulseInstalled)) > 0.0 THEN
            XActualPosition := (XAxisFrwPosPerRev / (XGearRatio * UDINT_TO_REAL(XEncoderPulseInstalled))) * DINT_TO_REAL(XAxisEncRaw);
        END_IF;
    ELSE
        // 2. Durum: Enkoder Redüktör Çıkışında (Yük Milinde) ise
        IF UDINT_TO_REAL(XEncoderPulseInstalled) > 0.0 THEN
            XActualPosition := (XAxisFrwPosPerRev / UDINT_TO_REAL(XEncoderPulseInstalled)) * DINT_TO_REAL(XAxisEncRaw);
        END_IF;
    END_IF;

   
    // --- 2. HMI Pozisyon Düzeltme (Kenar Tetikleme ile Güvenli Hale Getirildi) ---
    // HMI butonlarına basılı kalındığında sürekli offset hesaplamasını önlemek için R_TRIG kullanılmıştır.
    R_Trig_Duzelt(CLK := HMI_PozisyonDuzelt);
   
    IF R_Trig_Duzelt.Q THEN
        Offset_mm := HMI_SetEdilenPos - XActualPosition;
    END_IF;


    // --- 3. Offsetli Final Pozisyon ---
    XActualOffsetliPosition := XActualPosition + Offset_mm;

END_FUNCTION_BLOCK
 
Tüm yazdıklarımızı fonksiyon bloğuna çevirirsek.

Kod:
FUNCTION_BLOCK "FB_AxisPositionCalculator"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1

VAR_INPUT
    XAxisFrwPosPerRev       : REAL   := 1.0;  // Redüktör çıkışının 1 turdaki mm ilerlemesi [mm/Tur]
    XEncoderPulseInstalled  : UDINT  := 1024; // Takılı enkoder pulse sayısı [Pulse / Tur]
    XAxisEncRaw             : DINT;           // Enkoderden okunan aktüel ham değer [Pulse]
    XGearRatio              : REAL   := 1.0;  // Motor miline bağlı redüktör oranı (i=10 gibi)
    XEncoderIsOnMotor       : BOOL   := TRUE; // TRUE: Motor milinde, FALSE: Redüktör çıkışında
    HMI_PozisyonDuzelt      : BOOL;           // HMI pozisyon kalibrasyon tetikleyicisi
    HMI_SetEdilenPos        : REAL;           // HMI üzerinden istenen pozisyon [mm]
END_VAR

VAR_OUTPUT
    XActualPosition         : REAL;           // Eksenin o anki hesaplanan ham aktüel değeri [mm]
    XActualOffsetliPosition : REAL;           // Offset eklenmiş son pozisyon [mm]
END_VAR

VAR
    Offset_mm               : REAL := 0.0;    // Kalibrasyon offset değeri (Kalıcı olmalıdır)
    R_Trig_Duzelt           : R_TRIG;         // HMI butonunun kenar tetikleyicisi
END_VAR

BEGIN
 
    // --- 1. Aktüel Pozisyon Hesaplama ---
    IF XEncoderIsOnMotor THEN
        // 1. Durum: Enkoder Motor Milinde ise
        // Bölme hatası (division by zero) olasılığına karşı güvenlik kontrolü eklenebilir
        IF (XGearRatio * UDINT_TO_REAL(XEncoderPulseInstalled)) > 0.0 THEN
            XActualPosition := (XAxisFrwPosPerRev / (XGearRatio * UDINT_TO_REAL(XEncoderPulseInstalled))) * DINT_TO_REAL(XAxisEncRaw);
        END_IF;
    ELSE
        // 2. Durum: Enkoder Redüktör Çıkışında (Yük Milinde) ise
        IF UDINT_TO_REAL(XEncoderPulseInstalled) > 0.0 THEN
            XActualPosition := (XAxisFrwPosPerRev / UDINT_TO_REAL(XEncoderPulseInstalled)) * DINT_TO_REAL(XAxisEncRaw);
        END_IF;
    END_IF;

 
    // --- 2. HMI Pozisyon Düzeltme (Kenar Tetikleme ile Güvenli Hale Getirildi) ---
    // HMI butonlarına basılı kalındığında sürekli offset hesaplamasını önlemek için R_TRIG kullanılmıştır.
    R_Trig_Duzelt(CLK := HMI_PozisyonDuzelt);
 
    IF R_Trig_Duzelt.Q THEN
        Offset_mm := HMI_SetEdilenPos - XActualPosition;
    END_IF;


    // --- 3. Offsetli Final Pozisyon ---
    XActualOffsetliPosition := XActualPosition + Offset_mm;

END_FUNCTION_BLOCK



Merhaba, paylaşımınız için teşekkürler.

Enkoderin motor milinde mi yoksa redüktör çıkışında mı olduğuna göre hesap yapılması ve HMI üzerinden konum düzeltmesi yapılması faydalı bir yaklaşım.

Burada önemli bir ayrım var, konum düzeltmesi ile mesafe ölçüm hatasının düzeltilmesi aynı şey değil. HMI’dan yapılan offset, hesaplanan konuma sabit bir değer ekler.

Örneğin sıfır noktası 2 mm hatalıysa bu düzeltilebilir. Ancak makine her 1000 mm harekette 5 mm eksik ya da fazla ölçüyorsa, yalnızca offset vermek bu hatayı gidermez.

Çünkü sorun sıfır noktasında değil, mesafenin hesaplanmasındadır.

Burada, redüktör oranı, dişli, kayış ve kasnak çapı ile encoder çözünürlüğü gibi etiket verilerine dayanan teorik değerler değil, başlangıç ve bitiş noktaları arasındaki gerçek mekanik mesafe ölçülmeli, hareket boyunca plc'nin enkoderden okuyup saydığı gerçek pulse sayısı esas alınmalıdır.

Elde edilen değerle gerçek “mm başına sayım” oranı bulunup hesap buna göre ayarlanmalıdır.

Bu kalibrasyon, teorik hesaptan kaynaklanan mesafe hatasını azaltır.

Özetle, paylaştığınız FB konum hesabı ve sıfır noktası düzeltmesi için kullanışlı bir yapı.

Ancak mesafenin doğru hesaplanması için ise, gerçek hareket üzerinden bu oranın doğrulanması gerekir.
 
Son düzenleme:
Eksen ilerlemesinde teorik ile pratikte arasında oransal hata varsa tabikide söylediğiniz gibi XAxisFrwPosPerRev [mm] değerinin düzeltilmesi gerekir. Örneğin eksenin teorik ilerleme değeri XAxisFrwPosPerRev = 10mm olsun, pratikte Offset_mm =0 iken,
100mm git dediniz 110mm gittiyse;
XAxisFrwPosPerRev x (110 / 100) değeriyle düzeltmek gerek yani XAxisFrwPosPerRev =11mm şeklinde(artırmak)) düzeltmeniz gerekli.
Eksen eksik gittiyse; 100mm git dediniz 80mm gitti gerçekte o zaman
XAxisFrwPosPerRev x (80 / 100) = 8mm şeklinde düzeltmek(azaltmak) gerek, bu hesaptan sonra gerçek Offset değeri hesaplanmalıdır. Yoksa bu oransal hata offset ile düzeltilemez! Enkoder pulse sayısının ve redüktör oranlarının hatasız olduğunu kabul ediyoruz.
Yukarıdaki fonksiyon bloktaki hesaplamanın avantajı; oransal hata ve offset değerleri düzeltildikten sonra redüktör, enkoder, mekanik offset veya ilerleme oranı değiştiğinde hesapların tekrar yapılmasına gerek duyulmadan ekrandan değiştirilebilmesidir.
 
Son düzenleme:
Motion kontrol uygulamalarında da ilerleme oranı düzeltilmeden eksen hatasını düzeltemessiniz, aşağıda daha önce üzerinde durduğum bir konuyu örnek olarak ekliyorum. Örnekteki 166.67mm değeri mutlaka yukarıda bahsettiğim ölçme yöntemiyle doğrulanmalıdır Ayrıca sistem sizden redüktör oranını ve motorun increment sayılarını doğru girmenizi ister. Sağ taraf pay, sol taraf payda ve bu değerler birbiriyle çarpılıyor şeklinde veriler giriliyor.

Başka bir örnek:
 
Son düzenleme:
Merhaba, paylaşımınız ve örnekleriniz için teşekkürler.

Oransal hatayı önce mm/tur değerini düzelterek gidermek, offset’i de ondan sonra hesaplamak bence doğru sıra. Verdiğiniz örnek bunu açıkça gösteriyor.

Paylaştığınız 166,67 değerinin de yukarıda anlatılan ölçümle doğrulanması gerekir.

Ekrandaki ölçek ayarında redüktör oranı ve motorun increment sayısı doğru girilmelidir. Sağ taraf pay, sol taraf payda olarak çarpıldığı için oran ters girilirse ölçek oranın karesi kadar yanlış çıkar. i=3 için bu 9 kat demek.

Bir de metinde “motorun 100 turunda” yazarken ekranda girişin “redüktör çıkışının 100 turu” olarak yazıldığı görülüyor. Hangisinin doğru olduğu netleşirse girişler de doğru yapılmış olur.

Birkaç pratik nokta da ekleyeyim. 100 mm gibi kısa bir mesafede 1 mm’lik hata yüzde 1 demek, o yüzden ölçümü mümkün olduğunca uzun strokta yapmak iyi olur. Referans noktası tekrarlanabilir olmalı, sensör ya da mekanik durdurucu kullanılabilir. Hedefe her zaman aynı yönden yaklaşılmalı ve ölçüm yük altında yapılmalı. Oran strokun yüzde 25'inde, yüzde 50'sinde ve sonunda kontrol edilmeli. Sapma noktalara göre değişiyorsa tek bir katsayı yetmeyebilir.

İkinci örnekteki “leadscrew pitch” 534,07 mm/rot, 170 mm çaplı bir makaranın çevresiyle (170 x 3,1416 = 534,07) aynı çıkıyor. Bu değer vida adımı değil de makara çevresi olabilir. Hangisi olduğu netleşirse teorik hesap da daha sağlam olur.

Düzeltilmiş mm/tur değeri, kullanılan pals sayısı ve redüktör oranıyla birlikte geçerlidir. Bunlardan biri sonradan değişirse, örneğin enkoderin x4 modunda sayıldığı sonradan fark edilirse, mm/tur değerinin de yeniden ölçülmesi gerekir. Değerin ekrandan değiştirilebilmesi kodu yeniden yazma ihtiyacını ortadan kaldırıyor, ancak her mekanik değişiklikten sonra ölçümü tekrarlamak gerekir.

Son olarak, mm/tur değeri hem geri beslemede (sayımdan mm’ye) hem de hedef dönüşümünde (mm’den sayıma) aynı kullanılmalı. Yoksa gösterge doğru olsa bile eksen girilen değerde durmaz.

Katkınız için teşekkürler, kolay gelsin.
 
Son düzenleme:

Forum istatistikleri

Konular
133,547
Mesajlar
972,192
Kullanıcılar
459,663
Son üye
Erenku22
Geri
Üst