Tekrarlayan zamanlayıcı hakkında (millis fonksiyonu)

amenofis

Üye
Katılım
18 Tem 2019
Mesajlar
36
Tepkime puanı
7
Puanları
8
Konum
Bursa
Boşta olan timer varsa onu kullanabiliriz.

Board Uno mu?
Timer1 ya da Timer2 kullanan herhangi bir kütüphane kullanıyor musun (pwm vs.)?
Zamanlayıcı milisaniye değil de 1 saniye ya da 1 dakika adımlarla çalışsa olur mu? Mesela "şu kadar dakika sonra..." diyebiliyor muyuz?
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Ardunio Uno klon (ch340 çipli), pin sayısı yeterli olursa bunda devam edeceğim.
Kullandığım kütüphaneler,
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>

Timer1 ve Timer2 i algoritmamda kullanmıyorum. Yani boşta ikiside. Milisaniye olması şart değil. Millis kullanıldığı için dakika ve saat verilerini milisaniyeye dönüştürmek zorunda kaldım.

Teşekkürler,
Ali
 

amenofis

Üye
Katılım
18 Tem 2019
Mesajlar
36
Tepkime puanı
7
Puanları
8
Konum
Bursa
C:
typedef void (*Fonk)();

Fonk timer_gorev;
uint16_t timer_sayac;

ISR(TIMER1_COMPA_vect)
{
    if(--timer_sayac == 0) {
        TCCR1B = 0;
        timer_gorev();
    }
}

static void timer_hazirla()
{
    TCCR1A = TCCR1B = 0;
    TCNT1 = 0;
    OCR1A = 62500;
    TIMSK1 = _BV(OCIE1A);
}

static void gorev_kur(Fonk gorev, uint16_t dakika)
{
    timer_gorev = gorev;
    timer_sayac = dakika * 15;
    TCCR1B = _BV(WGM12) | _BV(CS12) | _BV(CS10);
}
Basitçe bu şekilde bir zamanlayıcı düşündüm. İhtiyaca göre daha detaylı hale getirilebilir. Şu an deneme şansım olmadığı için deneyemedim. 1 dakikaya kurarak led yakabilirsin denemek için. Kullanmak için bu kodu en tepeye yapıştır. setup() içinde timer_hazirla() fonksiyonunu çağır. Sıradaki görevi tetiklemek için işlemi bir fonksiyon içinde yaz ve süreyi başlatmak için gorev_kur() fonksiyonunu kullan. İlk parametresi yazdığın fonksiyonun ismi, ikinci parametre ise kaç dakika sonra çalışacağı. Bu zamanlayıcı tamamen asenkron çalışır. loop() içindeki kodları bloklamaz.

Örnek bir led yakma görevi.

void led()
{
digitalWrite(5, HIGH);
}
...

gorev_kur(led, 1);
 
Son düzenleme:

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Sizin kurduğunuz işleyiş mantığını kavrayamadım. Bende aşağıda ki gibi uyarladım.

void setupTimer1()
{
TCCR1A = 0;

TCCR1B = 0;

TCNT1 = 0;

OCR1A = OCR1A = 62499; //1/4hz (16000000/((62499+1)*256))

TCCR1B |= (1 << WGM12); // CTC (Timer on Compare –Timer karşılaştırma Modu) OCR1A ile karşılaştırılır

TCCR1B |= (1 << CS12) | (1 << CS10); // Prescaler 256

TIMSK1 |= (1 << OCIE1A); // Output Compare Match A Interrupt Enable

interrupts(); // Kesmelere izin veriliyor

}

************************************************
ISR(TIMER1_COMPA_vect) //Karşılaştırma kesmesi (TCNT1==OCR1A)
{
gorev();
}
************************************************
void setup()
{
setupTimer1();
}
**************************************************
void loop ()
{

}
************************************************
void gorev()
{
saybasla++;
saybitir++;

if(.....)

if(.....)
}
**************************************************
saybasla gerçekleştimi Led Aktif ve saymaya devam ediyor.
saybitir gerçekleştimi Led Pasif ve ikisini birden sıfırlıyorum. Gayet güzel çalıştı.

OCR1A = 62499; // 1/4 Hz (16000000/((62499+1)*256)) Her OCR1A değeri için 4 sn olarak hesapladım. Bunuda 15 ile çarparsak dakika değerini buluruz.Bu şekilde çalışır.

Millisin aynısı oldu tek fark Her ne durumda veya şartta olursa olsun, işlem zamanı geldimi yapıp geri dönüyor. Ben bu şekilde güncelliyorum resetleme derdini ortadan kaldırmış olduk.

Kontrol edebilir misiniz, benim gözlemlediğim sorunsuz çalışıyor ama hesaplamalarda veya mantık ta bir eksiklik var mı?

Teşekkürler,
Ali
 

amenofis

Üye
Katılım
18 Tem 2019
Mesajlar
36
Tepkime puanı
7
Puanları
8
Konum
Bursa
Sizinki sabit zaman, sabit görev. Benim ki değişken zaman, değişken görev. Ha görev tek ise o şekilde de olur tabi.

millis() kullanırken cpu %100, timer kulanırken cpu neredeyse %0. Eğer pille çalıştıracaksanız işlemciyi uykuya yatırıp pil süresini yıllara çıkarabilirsiniz. millis te ise uyutmak mümkün olmaz. Yani aslında bu yöntem eeprom sorununu da çözer çünkü ona da gerek kalmaz. Fark bu.
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Tek görev yok timer görev içerisine 6 farklı sayıcı koydum, hangisinin süresi gelirse o çalışıyor. O süreleride LCD menuden değiştirebiliyorum. Çoklu görev bir problem yaratmaz diye düşündüm, doğru mu?

Menu içerisinde gezerkende çalışabiliyor artık :) Epromm kullanacağım mecburen, off/on durumunda son duruma göre zamanlara çıkarma yapıyorum.

Anlatayim belki işinize yarar, Onu şöyle bir mantıksal işlemle ile çözdüm işlem süresini 10'a böldüm ve aynı görev içerisinde farklı bir sayaç ile 10 artırdım. 100 olunca sıfırladım ve tekrarlattım. Değeride kesinti anından önce kaydettim. Sistem tekrar enerjilendiğinde kaydedilen o yüzdelik değeri ana işlem zaman süresinden çıkardım ( başlangıç çalışma koşulu için). %10 onluk bir şaşma ile zamanı yakalayabiliyorum. 100 de böle bilirdim lakin çarpandan tek 0 geliyor ve float değeri kaydetmekle uğraşmak istemedim.

Ardunio nun kedin içirisinden gerilim referansı alabilir miyim? Örneğin 3,5V un altına düştümü farklı bir işlem yaptıracağım. Şuan için Besleme kaynağından yaptım ama dahili olursa daha güzel olur.

Teşekkürler,
Ali
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
RTC kütühaneden kaynaklı sanırım, zamanı doğru çarpamadım. RTC nin sayaç ile ilgili kutüphanesi var mı yada saniye elde edebileceğim doğru formul nedir? Örneğin saat 01:20 ise sonuç (60*60 * saat + 60 *dk ) bu olması gerekli. Doğru hatırlıyorsam eğer, saat ve dk çift hane düştümü sorun çıkıyordu yada tam tersiydi.

Teşekkürler,
Ali
 

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
int dakika;
int saat;
void setup() {
}
void loop() {

if ( dakika > rtc.Minute() ) { dakikakomutu(); } /// minute dakikada bir değişeceği için her değişiklik 1 dakika
if ( saat > rtc.Hour() } { saatkomutu(); } /// hour saatte bir değişeceği için her değişiklik 1 saat

dakika = rtc.Minute();
saat = rtc.Hour();

if ( rtc.Hour() == 12 && rtc.Minute() == 30 ) { ogleyemegikomutu(); }
if ( rtc.day() == wednesday ) { gunkomutun(); }

}

vs vs
 
Son düzenleme:

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Benim ihtiyacım farklı ben 20 adet alarm girsem zaten basit rtc ile bunu hallederiz. İhtiyacım sonsuz tekrarlanan durum oluşturmak. O anki zamanla bir işim yok. Zamandan bağımsız zamanlama. her 5 dakika da bir 3dk alarm nasıl çaldırabiliriz RTC ile? Sadece 2 değer girilecek 5dk ve 3dk.

Teşekkürler,
Ali
 

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
en basitinden mantık

void loop() {
if ( rtc.minute() == 05 ) { zilcal(); }
if (rtc.minute() == 08) { zilsus(); }
}

yada

void loop() {
if ( rtc.minute() == 05 || rtc.minute() == 10 || rtc.minute() == 15 ) { zilcal(); }
if ( rtc.minute() == 08 || rtc.minute() == 13 || rtc.minute() == 18 ) { zilsus(); }
}
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Olmaz hocam bu şekilde sayfalar dolusu döngü kurmak lazım. Şöyle bir matematiksel işleme RTC izin verse olur.
b=5
a=0
c=3
d=0
alarm1=rtc.minute*b+ rtc.hour*a
alarm2=rtc.minute*c+ rtc.hour*d

Değeri matamatiksel işleme uygun değil. En azından ben yapamadım.

Teşekkürler,
Ali
 

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
:))

rtc nin matematik ile bir ilgisi yok bildiğin alarmlı saat

neden sayfalar dolusu döngü gereksin ki ?

Kod:
int besdalarm[] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 00};
int ondalarm[] = {10,20, 30, 40, 50, 00};
int ucluk[] = {0 ,0};
int beslik[]= {0, 0};

void setup() {

Serial.begin(9600);
dakika = rtc.Minute();

}

void loop() {
if ( rtc.Minute() != dakika ) {
  int i = 0;
  while ( i < 12 ) {
    if ( rtc.Minute() == besdalarm[i] ) {  ucluk[0] = rtc.Minute(); ucluk[1]= rtc.Minute() + 3; }
    if ( rtc.Minute() == ondalarm[i] ) {  beslik[0] = rtc.Minute(); beslik[1]= rtc.Minute() + 5; }
    i++;
    }
  }
if ( ucluk[0] <= rtc.Minute() && ucluk[1] >= rtc.Minute() ) { cal3(); }
if ( beslik[0] <= rtc.Minute() && beslik[1] >= rtc.Minute() ) { cal5(); }
dakika = rtc.Minute();
}
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Bunlar sabit değerler için olabilir peki değişken değerler için;

Benim algoritma işleyişim;
alarm1basla a:b (saat:dk)
girilen dakika=a // 0-59 arasında değişebilir
girilen saat= b // 0-12 arasında değişebilir

alarm1bitir = (a+c) : (b+d) // (saat:dk)) // 0-59 arasında değişebilir
girilen dakika=c // 0-59 arasında değişebilir
girilen saat= d // 0-6 arasında değişebilir

Çalışması (alrm1basla , alarm1bitir) 2. tekrar ( alarm1bitir+alarm1basla ve alarm1bitir+alarm1bitir ) 3..4..5.........sonsuz

Bu işleyiş RTC ile yapılabilir mi? Şahsen ben yapamadım. Kafamda oluşturamadım.

Teşekkürler,
Ali
 

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
iyide aynı şeyi konuşuyoruz zaten

mesela 20 alarm istiosun

int alarm1[] = { 12, 20, 3 }; // saat ,dakika, ne kadar alarm çalsın
int alarm2[] = { 10, 30, 5}; // saat ,dakika, ne kadar alarm çalsın
int alarm3[] = { 09, 45, 10}; // saat ,dakika, ne kadar alarm çalsın

//vsvs alarmları çoğalt


void loop() {
if ( rtc.hours() == alarm1[0] && rtc.minutes() == alarm1[1] ) { zil(alarm1[2]); }
if ( rtc.hours() == alarm2[0] && rtc.minutes() == alarm2[1] ) { zil(alarm2[2]); }
if ( rtc.hours() == alarm3[0] && rtc.minutes() == alarm3[1] ) { zil(alarm3[2]); }
}

bunlari bir dakikalık komut içine alıp while ile tek seferde hepsini kontrol edebilirsn

daha sonra lcd ekranından veya harici nasıl değiştirmek istiosan alarm ekle

alarm1[0] = lcdden gelen saat komutu veya button ile artı eksi komutu //alarmn başlaycağı saat
alarm1[1] = lcdden gelen dakika komutu veya button ile artı eksi komutu //alarmn başlayacğı dakika
alarm1[2] = lcdden gelen kaç dakika alarm çalacağı komutu veya button ile artı eksi komutu // kaç dakika işlem yapmak istediğin
 
Son düzenleme:

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
veya

int alarm[] = { 10, 30, 3, 12 ,45 ,5 , 9, 25 , 7 } // üç alarm değişkeni girip 20 li set yaparsın

while ile
3 lü set ler halinde tek seferde kontrol edersin
bunlar tamamen yazılımına nasıl başladığına bağlı
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
Sınırı olan bir alarm istemiyorum, aynı frekansı yakalayamadık. Biz tanımlamaları değiştirelim. Alarm yok. Bekleme süresi, Çalışma süresi.
Telefonlardaki saat alarm mantığı gibi düşünüyorsun, ben farklı bir durumdan bahsediyorum.

string gorev [] {"Bekleme suresi", "Calisma suresi"}; // Başka görev yok, tek bir görev ile tekrarı sağlatmak amacımız. Girilen değer normal saat değil, aktif olma aralığı.

Şimdi işleyişe gelelim,

1.Koşul
Hiç bir koşul yok, Set edildiği anda hangi saat veya dakika diliminde olursa olsun o anki değeri baz alır ve beklemeye oradan başlar. 2.koşula geç

2. Koşul
Bekleme süresi doldumu çalışır. 3. koşula geç

3.Koşul
Çalışma süresi dolana kadar çalışır.
Çalışma süresi doldumu 4. koşula geç

4.Koşul
1.koşula git ve tekrar bekleme süresinin dolmasını bekle.

Bu durum günde veya haftada 1 kez değil. Her çalışma süresi dolumundan sonra aynı dongüyü tekrarlar. bekle/çalış/bekle/çalış........ 1.Koşul saati = 4.Koşul saatine eşitlenir. ( Set edilme saatine eşitlenir )

Teşekkürler,
Ali
 

xbrknx

Üye
Katılım
16 Tem 2019
Mesajlar
98
Tepkime puanı
18
Puanları
8
Konum
istanbul
anlamadığın bir olay var

millis timer bilmem ne kullanmak yerine

rtc nin 1 dakikalık süresini kullan diyorum ????
 

alio1984

Üye
Katılım
9 Ağu 2019
Mesajlar
43
Tepkime puanı
1
Puanları
8
Konum
istanbul
int say=0;

if (rtc.minutes > 59)
say ++

if (say== beklenen saat && rtc.minutes == beklenen dakika )
çalış
if (say== çalışma saati && rtc.minutes == çalışma dakikasi )
dur
say=0;

olur, gayette güzel olur. Peki böyle bir işleyişte RTC kullanmanın bir mantığı var mı? RTC demek ekstra 3 pin ve maliyet. Timer bedava. Kod azaltsa işlem yükümü hafifletse yine eyvallah ama yok. timer ile sn tutuyorum, RTC ile dakika tutacağım veya sn olarak tutacağım.

Sonuç olarak RTC ile de yapılabileceğini kanıtlamış olduk :)

Teşekkürler
Ali,
 
Üst