IF ile çalışan döngü, dış kesme ile sağlıklı çalışmıyor?

elek

Profesyonel Üye
Katılım
24 May 2006
Mesajlar
2,911
Puanları
318
Arkadaşlar aşağıda iki kod(Arduino UNO) ekledim..iki kodda da ışığı kaç kere kestiğimi sayıyorum..
birinci kodda her değişiklikte displayde 2 şer atlama oluyor ve sağlıklı çalışmıyordu..delay gecikmesi ekleyerek çözdüm..sensörün ışığını her kestiğimde sayı bir artıyor ve istediğim oluyor.
ama dış kesme ile yaptığım ikinci kodda sensörün ışığını kestiğimde ve açtığımda 2 şer sefer artma oluyor..
bunu bir türlü çözemedim..delay gecikmeside işe yaramadı..bunu halledebilirsem dış kesme ile yaptığıma millis fonksiyonu ekleyerek iki kesme süresini ekrana yazdıracağım..


Kod:
#include <TM1637.h>

#define clk 6
#define dio 7
int  inputpin= 2;

TM1637 tm(clk,dio);
int x=0;
int a;
int b;
int c;
int d;
void setup(){
pinMode(2,INPUT);
  tm.init();
  tm.set();
  }

void loop(){

basla:
delay(50);
if (digitalRead(inputpin)==0)
   goto basla;
   x++;
  a=x/1000;
  b=(x/100)%10;
  c=(x/10)%10;
  d=x%10;
  tm.display(0,a);
  tm.display(1,b);
  tm.display(2,c);
  tm.display(3,d);
  delay(50);
//...........
  kontrol:
  if (digitalRead(inputpin)==0)
  goto basla;
  goto kontrol;
    }
Kod:
// dış kesme ile yapılmış
#include <TM1637.h>

#define clk 6
#define dio 7
int  inputpin= 2;



TM1637 tm(clk,dio);
int x=0;
int a;
int b;
int c;
int d;
void setup(){
pinMode(2,INPUT);
  tm.init();
  tm.set();
   attachInterrupt(0, sayma, RISING);
  }

void loop(){


    }
// kesme gelince sayma döngüsü
  void sayma(){
  delay(1000);
   x++;
  a=x/1000;
  b=(x/100)%10;
  c=(x/10)%10;
  d=x%10;
  tm.display(0,a);
  tm.display(1,b);
  tm.display(2,c);
  tm.display(3,d);

  }
 
Son düzenleme:
Kod:
int  inputpin= 2;

pinMode(7,INPUT);

attachInterrupt(0, sayma, RISING);

Bunların üçü farklı pinlerden bahsediyor. Kesme hangisinde.

Ayrıca kesme içinde işlem yapmak sakıncalıdır yarım kalabilir. Sadece artırmak istediğin sayıyı artırıp loop içinde işlem yaparak ekrana yazdırman gerek.

Ayrıca kullandığın ekranın kitaplığında showNumberDec("sayı", false); gibi bir fonksiyon var onu kullanarak x değişkenini şöyle tm.showNumberDec(x, false); yazdırabilrsin parçalamana gerek yok.
 
Son düzenleme:
..kod la uğraşırken sanırım yanlış kopyalama yapmışım.
pinMode(2,INPUT); olacak..
kesme arduino nun 2. pininde..düzelttim ama değişen birşey yok..
uno nun 2 ve 3. pinleri kesme için..2 için 0, 3 için 1 yazılması gerekiyormuş..
 
En doğru olanı budur kafa karıştırmaz pin numarasını girmen yeterli:
C++:
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
Kesmeyi ışık bitene kadar bekletebilirsin:
C++:
void sayma(){
 x++;
  while(digitalRead(2))
     delay(1);
}

Lakin bu kötü bir uygulamadır aynı senin delay fonksiyonu gibi kesme bitene kadar işlemciyi meşgul eder başka iş yaptırmaz. Ben senin diğer postuna yazmıştım onu kullanabilirsin. Olcuyor değişkeninin altına sayac değişkenini artırabilirsin.
 
Kodun gerektiği gibi çalışması için delay() a gerek yok. Onun yerine aşağıdaki gibi yapabilirsin.
Kod:
//...
int oncekiTus=0;
...
void loop {
  if (oncekiTus==HIGH) && (digitalRead(inputpin)==LOW)) // tus basılıp bırakıldığında
  {
     x++;
  }

  oncekiTus=digitalRead(inputpin);
}

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce
..verdiğin sitede çift kontroldan bahsediyor..bir zamanlar picbasic de parazit önlemek için çift kontrolu kullanmıştım. işe yarıyordu..burada verdiğin kodu kullandım ama sayıcı devamlı sayıyor
sensörden bilgi gelmesede..sanırım yanlış yerlere koydum satırları..

tm.showNumberDec(x, false);
..bu satırı ekledim ama hata verdi..kütüphane ile ilgili sanırım...
 
Birinci kod çalışması;
girişte bir kare dalga olduğunu düşünürsek..
bu kare dalga nın peryodu 1 saniye ile 2 saniye arasında değişiyor..
pozitip kısım ortalama 0.1 saniye ise peryod ortalama 1,5 saniye..
böyle bir dalga..
ilk if ile yükselen kenarı yakalıyorum..ikinci if ile sıfıra düştüğü durumu yakalayıp
tekrar ilk kontrole gidiyorum..
şimdi sorunum bu kod a millis fonksiyonunu yerleştirip peryodu bulmak..yani iki yükselen kenar arasını..kesme ile nasıl yapılacağını önceki açtığım konuda vermiştiniz arkadaşlar..
ama ben öncelikle klasik yöntemle halletmeye çalışıyorum..
burada peryod çok kısa değil.. saniyeler mertebesinde..
 
..aşağıdaki kodda millis foksiyonuda var..program çalışıyor..ışığı elimle kesme hızını arttırıp yavaşlatıyorum rakam uyumlu bir şekilde değişiyor..620, 1210, vs...
aynı hızda kesmeye çalışıyorum.. 100 ler veya 1000 ler hanesi hanesi sabit kalmak koşulu ile diğer rakamlar değişiyor..bu da normal..display e yazma yerini değiştirdim..belki gerekliydi veya değildi ..bilmiyorum..
ama başlangıçta yani ara verilip tekrar ışığı kesmeye başladığımda bir istikrarsızlık var.. neyse biraz ilerleme katettim..ikinci kontrolde sensör çıkışının 1 e çekildiğini tekrar kontrol etmek zorunda kaldım..
kesme ile daha kolay yapılacakmış gibime geliyor ama kesme ile bir türlü anlaşamadım.. :)

Kod:
#include <TM1637.h>

#define clk 6
#define dio 7
int  inputpin= 2;

TM1637 tm(clk,dio);
int t1=0;
int t2=0;
int x=0;
int a;
int b;
int c;
int d;
void setup(){
pinMode(2,INPUT);
  tm.init();
  tm.set();
  }

void loop(){

kontrol1:
delay(10);
if (digitalRead(inputpin)==0)
   goto kontrol1;
   t2=millis();

//...........
  kontrol2:
  if (digitalRead(inputpin)==0){
  kont:
  if(digitalRead(inputpin)==0)
    goto kont;
    x=t2-t1;
    t1=t2;
    //yazma
    a=x/1000;
  b=(x/100)%10;
  c=(x/10)%10;
  d=x%10;
  tm.display(0,a);
  tm.display(1,b);
  tm.display(2,c);
  tm.display(3,d);
  delay(10);
    goto kontrol1;
    }
      goto kontrol2;
    }
 

Forum istatistikleri

Konular
128,158
Mesajlar
915,528
Kullanıcılar
449,904
Son üye
teknikbilimlers31

Yeni konular

Geri
Üst