Arduino pin low süresi okuma ve dallanma?

elek

Profesyonel Üye
Katılım
24 May 2006
Mesajlar
2,911
Puanları
318
Bir pinin low olma süresini milisaniye cinsinden okuyup belirli değerler arasında ise 4 adet ledi değişik şekilde yakacağım.. bunu en basit şekilde nasıl yapabilirim..timer ve if yapısı kullanacağım ama özellikle timer yapısına yabancıyım arduino da..örneğin 1000 ms den küçükse kırmızı yansın,1000-1300 arası ise sarı led yansın gibi..
devre alt yapısı şu şekilde hazır;
ışık sensörü digital girişe bağlı,4 adet led digital çıkışa bağlı..
basit bir program yazdım..
ışığı engel ile kesince bir adet ledi yakıyorum.. engel kalkınca sönüyor..
bu noktadan ilerleyebilirmiyiz..

void setup() {
// put your setup code here, to run once:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(11,INPUT);
unsigned int sayac;
}

void loop() {
// put your main code here, to run repeatedly:
digitalWrite(2,LOW);
int sayac = digitalRead(11); // 11 nolu pini oku ve sayac değişkenine ata
if (sayac==1)
digitalWrite(2,HIGH);
}
 
Son düzenleme:
C:
const byte inputpin= 11;

const byte led1= 12;
const byte led2= 13;

volatile byte verihazir = 0;
volatile long zamanilk = 0;
volatile long aralik = 0;


void setup() {

  pinMode(led1, OUTPUT);

  pinMode(led2, OUTPUT);

  pinMode(inputpin, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(inputpin), baslangic, FALLING);

}



void loop() {



if(verihazir){

if( aralik < 1000) digitalWrite(led1,HIGH);

else if (aralik >1500) digitalWrite(led2,HIGH);

verihazir=0;

attachInterrupt(digitalPinToInterrupt(inputpin), baslangic, FALLING);

           }

}



void baslangic() {

zamanilk=millis();
verihazir=0;

attachInterrupt(digitalPinToInterrupt(inputpin), bitis, RISING);

}



void bitis() {

detachInterrupt(digitalPinToInterrupt(inputpin));

aralik= millis()-zamanilk;
verihazir=1;

}
 
Kod:
//Arduino framework doğrudan timer1 fonksiyou vermez harici kitaplık yüklenecek
//https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/arduino-timerone/TimerOne-r11.zip

#include <TimerOne.h>

void ledYak(uint8_t);
volatile unsigned int sayac = 0;


const uint8_t kirmizi = 2,sari = 3, yesil = 4,mavi = 5,sensor = 7;

const int kirmizi_alt_limit = 1000,kirmizi_ust_limit = 1300;
const int sari_alt_limit = 1300,sari_ust_limit = 1500;
//Alt limit ve üst limitler buraya eklenecek

void setup() {
  pinMode(kirmizi, OUTPUT);
  pinMode(sari, OUTPUT);
  pinMode(yesil, OUTPUT);
  pinMode(mavi, OUTPUT);
  pinMode(sensor,INPUT); //butona basılınca 1 olacağını varsayıyorum
  Timer1.initialize(1000);        
  Timer1.attachInterrupt(ledYak); 
}

void loop() {

}

void ledYak(uint8_t pin){
  //digitalWrite fonksiyonu çok fazla işlemci cycle i tükettiği içi
  // doğrudan portd registerina yazmak gerekli
  //timer kesmeleri mümkün olduğunca kısa olmalıdır
  
  if((PIND & (1 << sensor)) > 0){
    sayac++;
    if(sayac >= kirmizi_alt_limit && sayac <= kirmizi_ust_limit)
      PORTD = kirmizi;
    if(sayac >= sari_alt_limit && sayac <= sari_ust_limit)
      PORTD = sari;
    //Diğer ledler için aynıları eklenecek  
  }
  else{
    PORTD = 0;
    sayac = 0;
  }
}
 
Son düzenleme:
..sağolun arkadaşlar.Yazdıklarınızı inceleyip kendi durumuma uydurmaya çalışacağım..

Arduino da dış kesme ve millis fonksiyonunu inceledim..
Şöyle bir şey sorayım..
sensörün çıkışını bir kare dalga gibi düşünürsek;
yükselen kenarda engel geldi..bir süre kaldı..düştü..ikinci yükselen kenarda tekrar geldi..
iki tane kesme satırı görüyorum loop döngüsünde..
bu durumda her iki kesme komutunda RISING kullanmam gerektiğini düşünüyorum..
doğru mu?
yani periyod süresini bulmuş olacağım..başlık sanırım yanlış oldu..neyse..
bir de "if verihazır" satırını tam çözemedim..
 
O senin sensörünün ürettiği sinyale bağlı
 
Eğer konu pinin low süresini ölçmek ise her iki kesme de RISING kullanmak yanlış olur.
@silvestir 'in kodu low süresini ölçmek için gayet yeterli/doğru.

Ama period yani iki yükselen veya iki düşen arasını ölçmek istiyorsanız, tek kesme olmalı ve kesmede periot başlangının düşen/yükselen olmasına göre ya RISING yada FALLING kullanılmalı.

verihazir değişkeni ise ilk çalıştırmada ölçme işlemi hiç başlamamışken veya ölçme işlemi başlamış ama low sinyal devam ediyor yani ölçme işlemi bitmemişken, hatalı olarak led durumlarının değişmemesini garantiliyor.
 
Klasik yöntem ile yaptım ama if satırı hata veriyor..

Kod:
volatile long zamanBas = 0;
volatile long zamanSon= 0;
volatile long sure = 0;
const byte inputpin= 3;// sensör çıkış,engel yoksa sıfır.
const byte Kirmizi= 4;
const byte Yesil= 5;
const byte Mavi=6;
const byte Sari=7;
void setup() {
pinMode(inputpin,INPUT_PULLUP);
pinMode(Kirmizi,OUTPUT);
pinMode(Yesil,OUTPUT);
zamanBas=0;
zamanSon=0;
sure=0;
}
void loop(){
kontrol:
if (inputpin=1)
{
goto basla;
}
goto kontrol;
basla:
zamanSon=millis();
sure=(zamanSon-zamanBas);
zamanBas=zamanSon;
//***********1. kontrol
if (sure<1000)
{
digitalWrite(4, 1);
goto altprog;
}
else;
{
digitalWrite(4, 0);
}
//**********2. kontrol
if (sure<3000)
{
digitalWrite(5, 1);
goto altprog;
}
else;
{
digitalWrite(5, 0);
}
altprog:
 if (inputpin = 0)
{
goto kontrol;
}
goto altprog;
}
 
Son düzenleme:
Sanırım Basic alışkanlığı var.

Görebildiğim kadarı ile if koşullarındaki = == hatası dışında birde else ifadelerinin sonunda fazlalık ; var. Dolayısı ile else altındaki satırlar daima çalışır ve ledler sönük kalır.
Bunun dışında çok detaylı incelemedim ama kod iki yükselen arasındaki zamanı ölçer görünüyor.

C++:
volatile long zamanBas = 0;
volatile long zamanSon= 0;
volatile long sure = 0;
const byte inputpin= 3;// sensör çıkış,engel yoksa sıfır.
const byte Kirmizi= 4;
const byte Yesil= 5;
const byte Mavi=6;
const byte Sari=7;

void setup() {
    pinMode(inputpin,INPUT_PULLUP);
    pinMode(Kirmizi,OUTPUT);
    pinMode(Yesil,OUTPUT);
    zamanBas=0;
    zamanSon=0;
    sure=0;
}

void loop()
{

kontrol:
    if (inputpin==1){goto basla;}
    goto kontrol;

basla:
    zamanSon = millis();
    sure = (zamanSon-zamanBas);
    zamanBas = zamanSon;

//***********1. kontrol
    if (sure<1000){
        digitalWrite(4, 1);
        goto altprog;
    }
    else //; hata
    {
        digitalWrite(4, 0);
    }
    
//**********2. kontrol
    if (sure<3000){
        digitalWrite(5, 1);
        goto altprog;
    }
        else// ; hata
    {
        digitalWrite(5, 0);
    }
altprog:
    if (inputpin == 0)
    {
        goto kontrol;
    }
        goto altprog;
}
 
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için onları kabul etmelisiniz. Daha fazla bilgi edin…