Saat Kontrolünde Algoritma Desteği

Başlatan Mucit23, 20 Şubat 2025, 23:11:46

Mucit23

Umarım doğru bir başlık atabilmişimdir. Ufak bir algoritma desteğine ihtiyacım var.

Zamana bağlı olarak 4 farklı program içeren bir sistem yapıyorum. Sistemin çalışması kısaca şöyle olacak

1. Program Aktif olma saati 06:00 
2. Program Aktif olma saati 12:00
3. Program Aktif olma saati 15:00
4. Program Aktif olma saati 21:00

Sistem ilk açıldığında sistem saati hangi programın içeriğindeyse o programı aktif etmem lazım. Saat 06:00 ile 12:00 arasında 1. Program, 12:00 ile 15:00 arasında 2. Program, 15:00 ile 21:00 arasında 3. Program ve 21:00 ile 06:00 arasında 4. program çalışacak.

Sistem ilk çalıştığında diyelim ki saat 15:27

Bu durumda saat değeri 1. 2. 3. ve 4. program saat değerleriyle büyük eşit sorgulaması yapıyorum.  Güncel saat 1. 2 ve 3 program saat değerinden büyük yada ileride ama 4. saat değerinden küçük olduğu için 3. program dilimi diyorum sonuçta.

Kısmen çalışıyor Fakat şöyle bir Bug var çözemedim.

Yukarıdaki senaryoda saat 21:00 ile 06:00 arasında 4. program çalışması gerekir.

Diyelim ki sistemi enerjilendirdik saat 01:45. Bu durumda benim büyük eşit sorgulaması çalışmıyor. Saat dilim aralığı 21:00 ile 6:00 arasına girse de Saat 23:59 dan sonra 00:00 olacağı için çalışmayacak.

Dolayısıyla Saat 6:00'ı geçene kadar sistem çalışmayacak.

Burada daha düzgün bir alogirtma yürütmem lazım. Bunu PLC ve Ladder ile yapmaya çalışıyorum birde

Fikir verebilecek olan var mı? 

Epsilon

#1
4.programın başlangıcını 20:59:59 bitişinide 23:59:59 arası olarak tanımlayın ,5.programın başlangıcını 00:00:00 bitişinide  05:59:59 a kadar yapın ama 4.programın gittiği aynı yere gönderin (Yada aynı kodları yazın)
* Editörde bu tür uygulamalar için  saat modları da olabilir ,o zaman 5.bölüme gerek olmaz (PLC bilmiyorum)

Mucit23

#2
Olayın biraz karmaşık olduğunu düşünüyorum. Sistem statik olsa belki dediğiniz şekilde olur ama o şekilde de olmuyor gibi. Çünkü dinamik yada parametreler çok değişken. 1. Program saat 9:30 da başlasa nasıl olacak. Tam anlayamadım. Bunu otomatik yaptırmam lazım. 

Belki sadece dakika formatında işlem yapsak sanki daha kolay olacak. Saat dilimini dakikaya çevirip işlem yapmak lazım.

1. Program Aktif olma saati 06:00 Yada 360dk
2. Program Aktif olma saati 12:00 Yada 720dk
3. Program Aktif olma saati 15:00 Yada 900dk
4. Program Aktif olma saati 21:00 Yada 1260dk

Bu denklemde her bir programı aktif edip pasif edebiliyoruz birde. Buda bir parametre.  Bu çok önemli değil sadece dediğim sorunu çözersem problem kalmayacak.

Soruyu tekrarlıyayım. Bir program yazmalıyım Program çalıştığı anda hangi saat dilimi içerisinde olduğumu bulmalıyım. Saat diyelim 02:00 Dolayısıyla 4. program aktif olması lazım. 21:00 ile 06:00 arası 4. program.

Ama benim yapmış olduğum basit büyük eşit sorgu işe yaramıyor. 

Bu arada saat değerleri değişken. Kullanıcı belli bir sırayla saat değerlerini giriyor.

Epsilon

 Başlangıc saatinden büyük VE Bitiş saatinden küçükse diye tek satırda sorgulatmanız lazım

Mucit23

Alıntı yapılan: Epsilon - 21 Şubat 2025, 00:24:57Başlangıc saatinden büyük VE Bitiş saatinden küçükse diye tek satırda sorgulatmanız lazım

Olmuyor ki o şekilde.

4. Senaryo için başlangıç saati 21:00, bitiş saati 06:00

Saat diyelim ki 03:00

Başlangıç saatinden büyük mü ? Hayır
Bitiş saatinden küçük mü ? Evet

Bu ikisini bir if ile tek satırda VE şartıyla sorgulatırsam HAYIR cevabını alırım. İkisini aynı anda sağlamıyor. Sorunum bu zaten  :-\ 

sezgin

00:00 itibariyle 24*60 1440 saydırıp saatin dakikasına göre bir sorgu işletseniz nasıl olur?

1. Program Aktif olma    0 - 359
2. Program Aktif olma 359 - 719
3. Program Aktif olma 720 - 899
4. Program Aktif olma 900 - 1439

Epsilon

#6
Gece 12 den sonrası için daha önce yazdığım gibi
4.senaryonun başlangıcını
20:59:59 bitişini 23:59:59 yapıp
5.senaryo başl.00:00:00
bitişi 05:59:59 yapıp sonraki senaryoyu 2 diye adlandırıp 06:00 dan 11:59:59 a kadar tanımlıyacaksınız(Tabi 5.senaryoda 4.senaryo ile aynı komutlar olacak veya aynı procedure gidecek)
Bu şekilde çalışması gerekir

elektronik kassabı

Onu VEYA ile sorgulamalısınız. Örnek:
1: 6'dan büyük VE 12'den küçük
...
4: 21'den büyük VEYA 6'dan küçük

Epsilon

Bu arada aslında gece 12 den sonraki saat,saat olarak küçüktür ama tarih olarak büyüktür(Gün değeri artıyor)

Epsilon

#9
@Mucit23
Size Excelde saatler olarak değil ama girilen değer aralığında bir hücreye 1,2,3,4 diye yazdıran kısmı hazırladım ve düzgün çalışıyor.
Yeşile girdiğiniz değere göre sarı alanda 1ile 4 arasında değer yazıyor (mavideki aralıklara göre)
D1 hücresinde yazan formül:
=EĞER(VE(C1>=0;C1<=12);"1";EĞER(VE(C1>=13;C1<=22);"2";EĞER(VE(C1>=23;C1<=44);"3";EĞER(VE(C1>=45;C1<=77);"4";"4"))))
 Bu syntax muhtemelen sizin kullanacağınız synaxa çok yakındır.Artık mavi alanları örneğinize göre doldurursunuz
Formülün en sonundaki 4 kapa parantezin hemen solundaki tüm bu 4 değerin dışındaki durumlar içinde 4 yaz demektir
Bu 1...4 arasındaki rakamlar gidilecek alt programlar, doğal olarak (yada label ler )

TABLO" border="0

hasankara

Algoritmanın ismi aslında circular buffer, circular queue, cyclic buffer yada ring buffer başlıklarında geçebiliyor. Yaklaşım doğru sadece offset vermek yeterli olabilir. Dahada iyisi taşma durumlarında da standart kurguyu kullanmak için güncel değeri karşılaştırmadan önce periyota bölüp kalan sayıyı sorgulamak şeklinde. Bu örnek için periyot 24 saat oluyor.

Kabaca böyle birşey;
     if((ActualTime+3)%24) >= (6  + 3)%24){}
else if((ActualTime+3)%24) >= (15 + 3)%24){}
else if((ActualTime+3)%24) >= (12 + 3)%24){}
else if((ActualTime+3)%24) >  (21 + 3)%24){}

Mucit23

Alıntı yapılan: Epsilon - 21 Şubat 2025, 04:48:10@Mucit23
Size Excelde saatler olarak değil ama girilen değer aralığında bir hücreye 1,2,3,4 diye yazdıran kısmı hazırladım ve düzgün çalışıyor.
Yeşile girdiğiniz değere göre sarı alanda 1ile 4 arasında değer yazıyor (mavideki aralıklara göre)
D1 hücresinde yazan formül:
=EĞER(VE(C1>=0;C1<=12);"1";EĞER(VE(C1>=13;C1<=22);"2";EĞER(VE(C1>=23;C1<=44);"3";EĞER(VE(C1>=45;C1<=77);"4";"4"))))
 Bu syntax muhtemelen sizin kullanacağınız synaxa çok yakındır.Artık mavi alanları örneğinize göre doldurursunuz
Formülün en sonundaki 4 kapa parantezin hemen solundaki tüm bu 4 değerin dışındaki durumlar içinde 4 yaz demektir
Bu 1...4 arasındaki rakamlar gidilecek alt programlar, doğal olarak (yada label ler )

TABLO" border="0

Biraz anladım. Deneyeceğim. Aslında ben bitiş için ekstra saat bilgisi almıyorum. Sonraki programın başlangıç saat önceki programın bitiş saati oluyor. Normal zamanda saatin akışına göre kontrol edeceğimden dolayı sorun yok zaten saat dilimlerinde. Benim derdim sadece ilk açılış.

Alıntı yapılan: hasankara - 21 Şubat 2025, 07:35:08Algoritmanın ismi aslında circular buffer, circular queue, cyclic buffer yada ring buffer başlıklarında geçebiliyor. Yaklaşım doğru sadece offset vermek yeterli olabilir. Dahada iyisi taşma durumlarında da standart kurguyu kullanmak için güncel değeri karşılaştırmadan önce periyota bölüp kalan sayıyı sorgulamak şeklinde. Bu örnek için periyot 24 saat oluyor.

Kabaca böyle birşey;
     if((ActualTime+3)%24) >= (6  + 3)%24){}
else if((ActualTime+3)%24) >= (15 + 3)%24){}
else if((ActualTime+3)%24) >= (12 + 3)%24){}
else if((ActualTime+3)%24) >  (21 + 3)%24){}


Hasan hocam biraz daha açıklayabilirmisiniz ofset verme işini.

Benim yaklaşımım şu şekilde

1. Program Aktif olma saati 06:00
2. Program Aktif olma saati 12:00
3. Program Aktif olma saati 15:00
4. Program Aktif olma saati 21:00

Güncel saat de diyelim 18:57 olsun.

Bu değerler değişebilir tabi.

Sırayla 1. Programı kontrol ediyorum.

Saat 1. Program saatinden büyük mü? Evet ise program=1 yapıp sorguya devam ediyorum.
Saat 2. Program saatinden büyük mü? Evet ise program=2 yapıp sorguya devam ediyorum.
Saat 3. Program saatinden büyük mü? Evet ise program=3 yapıp sorguya devam ediyorum.
Saat 4. Program saatinden büyük mü? Hayır. Bu durumda en son program değeri 3 de kalmıştı burdan devam ediyorum sorguyu bitiriyorum.

Çalışıyor ama dediğim bug var.

@hasankara ofset verme mantığını biraz daha açıklayabilirmisin?

Burda şöyle bir sıkıntı daha var. Ben hep saat değerlerini sıralı giriyorum. Fakat aşağıdaki gibi olsa ne olacak

1. Program Aktif olma saati 13:32
2. Program Aktif olma saati 07:55
3. Program Aktif olma saati 03:11
4. Program Aktif olma saati 23:50

Bu durumda birde bunları büyükten küçüğe doğru sıralamak gerekir ki bunu kullanıcıya yaptırtacağım.




tunayk

Aslında önce bir normal >= taramsı yapacaksınız. Hiç bir kontrolde true alamadı iseniz, en büyük saat değerini alabilirsiniz. Çünkü önceki gün en son aktif edilecek program oydu.

hasankara

C dilinden faydalanarak algoritmayı kurgulamaya çalıştım. 3 saatlik offset verme sebebini açıklamamışım. Birde 2. ve 3. eşik sırasını ters yazmışım. Aslında senin uygulamada offset değerinin kod içinde dinamik olarak hesaplanıp kullanılması gerekiyor.

En yüksek eşik değerini periyoda yuvarlayarak 0 lamış oluyoruz. Böylece sayısal olarak bütün değerlerden küçük bir eşik değeri elde ediyoruz.
Özetle; Offset = Periode - Max_threshold, periyot değişkeni 24 saat sabit olarak tanımlanabilir diğer değerler uçucu olabilir.

Kullanıcı eşik değerlerini küçükten büyüğe girmesi zorunlu tutulursa, son eşik Max_threshold olur, zorunlu tutulmazsa kullanıcı hatalarını kısıtlamak için ek senaryolar planlanabilir.

periode = 24;
// All threshold values must be entered lower than the period value.
threshold1 =6; // user must enter the minimum hour value
threshold2 =12; // user must enter 2rd hour value
threshold3 =15; // user must enter 3rd hour value
threshold4 =21; // user must enter the maximum hour value
offset = periode - threshold4;
    if((ActualTime + offset)%periode) >= (threshold1  + offset)%periode){}
else if((ActualTime + offset)%periode) >= (threshold2  + offset)%periode){}
else if((ActualTime + offset)%periode) >= (threshold3  + offset)%periode){}
else if((ActualTime + offset)%periode) >  (threshold4  + offset)%periode){}

arci03

Merhaba zamana kıyaslamada en kolay işlem dakika veya saniye cinsinde dönüşüm yaparak olduğunu düşünüyorum.altta picbasic de yazdığım ornek bir kod var burada her saat den veri alınca dakikaya dönüşün yapıp ardından saatleri sorgulama yapmalıyız Program saatleri değişken tanımlayarak her seferinde kodda değişiklik yapmadan uygun çalışmaya devam edecektir.
programlar arası değişim de saatlerin bir sonraki saate göre 1 eksik olması olası karışıklıkları engelleyecektir.
program 4 de diğerlerinden farklı olarak veya ile sorguluyoruz sonuç olara saat 24:00 dan sonra sistem saati otomatik olarak sıfırlanacak bu sebeple ek kontrol yapmaya gerek olmayacaktır.

Prg1 = 360  '06:00 dakika Cinsinden Saat
Prg2 = 540  '09:00 dakika Cinsinden Saat
Prg3 = 865  '14:25 dakika Cinsinden Saat
Prg4 = 1270 '21:10 dakika Cinsinden Saat
Basla:
RealSaat = 18
RealDak  = 10
TopDak   = (RealSaat * 60 ) + RealDak
if TopDak >= Prg1 and TopDak <= (Prg2-1) then 'Burada artık program1 e ait kodlar olacak
if TopDak >= Prg2 and TopDak <= (Prg3-1) then 'Burada artık program2ye ait kodlar olacak
if TopDak >= Prg3 and TopDak <= (Prg4-1) then 'Burada artık program3 e ait kodlar olacak
if TopDak >= Prg4 or  TopDak <= (Prg1-1) then 'Burada artık program4 e ait kodlar olacak
goto Basla