İnternette çeşitli forumlarda zaman zaman karşılaştığım bir soru...
Konveyor üzerinde sensörle aktuator arasında birden fazla urun girecek kadar mesafe varsa, urunlerin takibini nasıl yapabilirim.
Bu sorunun çözümünü arayanlara destek olması amacıyla kısa bir derleme yapmak istiyorum. Mühendis arkadaşlar için basit olabilecek bu uygulama, işi sahada öğrenmek zorunda kalan elektrikçi arkadaşlar ve teknisyenler için bazen baş ağrıtıcı olabiliyor.
Öncelikle internette konuyla ilgili arama yapmak için ihtiyacınız olan anahtar kelimeler: Data buffering, buffering, queue implementation, FIFO buffer, ...
Biraz işin içine girelim...
Gelen datayı saklayıp, ihtiyaç olduğunda çıkartmak için öncelikle hangi yöneme ihtiyacınız olduğuna karar vermeniz gerekiyor.
Konveyör örneği üzerinden gidersek, konveyör üzerindeki ürün sensörünün önünden geçen ilk ürün aynı zamanda konveyörü ilk terk edecek üründür. Dolayısıyla, "ilk giren ilk çıkar" prensibine sahip bir buffer uygulamalıyız. (FIFO - First In First Out).
Hadi sizi google'da FIFO Buffering yazıp aramaktan kurtarmış olayım, bu cümleye tıklayın yeter.
Bunun için FIFO tabir edilen bir arşivleme sistemi kullanmak gerekiyor.
Bunun için dairesel olarak düşünebileceğimiz bir kayıt alanı (Ön koşul 'array'ler konusu) tasarlayalım.
Özetle işlem bu şekilde devam edebilir. Eğer useCell = StoreCell ise, kayıtlı parça olmadığı bilgisinin kullanıcıya verilmesi gerekir. Eğer storeCell bufferSize'a ulaşırsa, yeniden sıfırlanmalı ve çemberin ilk elemanına gitmelidir.
Fikir vermesi açısından kodunu da yazayım. Fakat yazdığım kodu direkt olarak kullanmayın. Zira arıza kontrollerini tamamen çıkarttım ve FIFO'dan pozisyon okuma işlemini nasıl yaptımı görmeniz açısından aynı koda dahil ettim. Konuya yabancı olanların okuması kolay olsun diye değişken tiplerini belirttiğim notasyonu da kullanmadım.
Konveyor üzerinde sensörle aktuator arasında birden fazla urun girecek kadar mesafe varsa, urunlerin takibini nasıl yapabilirim.
Bu sorunun çözümünü arayanlara destek olması amacıyla kısa bir derleme yapmak istiyorum. Mühendis arkadaşlar için basit olabilecek bu uygulama, işi sahada öğrenmek zorunda kalan elektrikçi arkadaşlar ve teknisyenler için bazen baş ağrıtıcı olabiliyor.
Öncelikle internette konuyla ilgili arama yapmak için ihtiyacınız olan anahtar kelimeler: Data buffering, buffering, queue implementation, FIFO buffer, ...
Biraz işin içine girelim...
Gelen datayı saklayıp, ihtiyaç olduğunda çıkartmak için öncelikle hangi yöneme ihtiyacınız olduğuna karar vermeniz gerekiyor.
Konveyör örneği üzerinden gidersek, konveyör üzerindeki ürün sensörünün önünden geçen ilk ürün aynı zamanda konveyörü ilk terk edecek üründür. Dolayısıyla, "ilk giren ilk çıkar" prensibine sahip bir buffer uygulamalıyız. (FIFO - First In First Out).
Hadi sizi google'da FIFO Buffering yazıp aramaktan kurtarmış olayım, bu cümleye tıklayın yeter.
Bunun için FIFO tabir edilen bir arşivleme sistemi kullanmak gerekiyor.
Bunun için dairesel olarak düşünebileceğimiz bir kayıt alanı (Ön koşul 'array'ler konusu) tasarlayalım.
Kullanılacak kayıt alanı tasarımı |
Kayıt alanına parça kayderken neler oluyor? |
Kayıt alanından kayıt okurken neler oluyor? |
Özetle işlem bu şekilde devam edebilir. Eğer useCell = StoreCell ise, kayıtlı parça olmadığı bilgisinin kullanıcıya verilmesi gerekir. Eğer storeCell bufferSize'a ulaşırsa, yeniden sıfırlanmalı ve çemberin ilk elemanına gitmelidir.
Fikir vermesi açısından kodunu da yazayım. Fakat yazdığım kodu direkt olarak kullanmayın. Zira arıza kontrollerini tamamen çıkarttım ve FIFO'dan pozisyon okuma işlemini nasıl yaptımı görmeniz açısından aynı koda dahil ettim. Konuya yabancı olanların okuması kolay olsun diye değişken tiplerini belirttiğim notasyonu da kullanmadım.
(* If not enabled, return for efficiency! *)IF NOT(Enable) THEN RETURN; END_IF;(* Event Handling *)R_TRIG_Enable(CLK:=Enable);(* Initialization *)IF R_TRIG_Enable.Q THENEncoderPositionParameter := UINT#1006; (* Yaskawa Related: For position, select external encoder *)UseCell := INT#0;StoreCell := INT#0;END_IF;(* always read actual position of encoder *)MC_ReadParameter_1(Axis := Encoder21, Enable := TRUE, ParameterNumber:=EncoderPositionParameter);EncoderPosition := MC_ReadParameter_1.Value;(* Operation *)R_TRIG_PartSensor(CLK := diPartComing);PartDetected := R_TRIG_PartSensor.Q;(*part recording to buffer*)if PartDetected then(*record position to buffer store cell*)Buffer[StoreCell] := EncoderPosition;(*increase store cell, if buffer size reached then store to the first buffer cell (circular buffer)*)if (StoreCell < (Buffersize - INT#1)) thenStoreCell := StoreCell + INT#1;elseStoreCell := INT#0;end_if;end_if;(*part reading - to give an idea how to do it, several needs can cause a part read. For instance; if the part passes over the minimum working area...*)R_TRIG_ReadPart(CLK := ReadPart);ReadPartPulse := R_TRIG_ReadPart.Q;if ReadPartPulse thenif NOT (StoreCell = UseCell) then(*Get part position *)PartPosition := Buffer[UseCell];(*increase UseCell, if buffer size reached then store to the first buffer cell (circular buffer)*)if (UseCell < (Buffersize - INT#1)) thenUseCell := UseCell + INT#1;elseUseCell := INT#0;end_if;else(*warn user*)NoPartInBuffer := TRUE;end_if;end_if;
NOT: Buraya kod eklendiğinde güzel gözükmüyormuş. Siz okuyacaksanız kopyalayıp notepad++'a falan atın.(*delete user warning*)if not ReadPart thenNoPartInBuffer := FALSE;end_if;
Hiç yorum yok:
Yorum Gönder