Arduino ile akıllı kill switch yapalım...

Sumer Yamaner

Moderator
Katılım
17 Eyl 2013
Mesajlar
8,769
Tepkime puanı
23,156
Yaş
61
Konum
İstanbul
Web sitesi
www.sumeryamaner.com
İlgi Alanı
Uçak
Aklıma gelen yeni bir proje...
Benzinli motorlarda motoru durdurmak için kill switch kullanıyoruz. Daha doğrusu kullanmalıyız da bazılarımız nedense inatla kullanmıyor o ayrı konu.
Bazı kill switchler klasik. Yani komut verdiğiniz anda motorun ateşlemesi kapatılıyor. Bazılarında ise değiştirilemeyen bir gecikme var. Bu da bazen sorun olabiliyor.
Pahalı sistemlerde ise farklı özellikler oluyor. Örneğin ilgili switchi bir kere tıklatıyorsunuz sistem arm ediliyor sonra tekrar tıklatınca motor kapanıyor. Böylece uçuş sırasında yanlışlıkla butona parmağın çarpıp motoru durdurması riski ortadan kaldırılıyor.
Yapacağımız şey şu:
Alıcıdan gelen sinyali işleyeceğiz.
Önce ateşleme gelen sinyal ne olursa olsun OFF konumunda ve bir de gösterge LED'i var, o da kapalı.
Başlangıçta sinyal ON ise OFF olmasını bekleyeceğiz.
Sonra tekrar ON olduğunda ateşlemeyi aktive edeceğiz. LED de yanacak.
Sonra sinyali izlemeye başlayacağız. Eğer OFF sinyali gelirse ve bir saniye içinde tekrar ON ve OFF olursa ateşlemeyi kapatıp LED'i söndüreceğiz. Eğer bir saniye içinde bu değişiklik gerçekleşmezse hiçbir şey yapmadan ateşleme aktif halde bekleyeceğiz.
Ayrıca, bir timeout süresinde alıcıdan hiç sinyal gelmezse ateşlemeyi kapatacağız.

Haydi klavye başına! :)

NOT: Arduino çıkışını bir optokuplör ile ateşleme besleme hattına bağlayacağız.
 
Arduino ile akıllı kill switch yapalım...

Başka bir güzel proje daha :halay: Akşama inşallah vakit ayırıp, ben de bununla ilgili kendi kodumu yazmak isterim :thumbup:
 
Arduino ile akıllı kill switch yapalım...

İkinci Arduino kodum geliyor... :)

Çalışma algoritması şöyle. Sisteme enerji geldiğinde önce alıcıdan sinyal gelip gelmediğini geliyorsa da ateşlemenin ON olup olmadığını kontrol ediyoruz. Çünkü ateşlemesi açık bir konumda başlamak istemiyoruz güvenlik nedeniyle. Bu esnada ateşleme LED'i yanıp sönüyor. Tahminimce ateşleme açıksa hızlı hızlı, alıcıdan sinyal gelmiyorsa yani verici kapalıysa (ki alıcıda failsafe varsa bunun bir anlamı olmaz) daha yavaş olarak yanıp sönüyor. Daha yavaş olma sebebi şu: pulseIn işlevinin default timeout süresi 1 saniye. Yani alıcıdan sinyal gelmiyorsa LED yanıp sönmeleri arasında bir saniye bekleme süresi olacak. Halbuki alıcıdan sinyal geliyor ve sinyal ON konumundaysa LED saniyede bir kez yanıp sönecek.
Alıcıdan ON sinyali geldiğinde bu sefer OFF gelmesini bekleyeceğiz. Bu sırada LED sönük kalıyor. Sonra ON sinyali bekliyoruz ve geldiğinde hem ateşleme LED'ini yakıyor hem de ateşlemeyi ON yapıyoruz.
Artık loop kısmına girebiliriz. Buraya girdiğimizde alıcıdan kesin olarak ON sinyali geldiğini ve ateşlemenin aktif olduğunu biliyoruz artık.
Yine alıcı girişini okumaya devam ediyoruz.
Loop içinde eğer alıcıdan gelen sinyal kesilirse yarım saniye daha bekliyoruz ve tekrar kontrol ediyoruz. Aslında pulseIn komutu timeout değeri nedeniyle yaklaşık 2.5 saniye beklemiş oluyoruz. Alıcı sinyali hala yoksa motoru kapatıyoruz (failsafe olarak).
Alıcıdan gelen OFF sinyali durumunda yarım saniye içinde tekrar ON sinyali gelip gelmediğine bakıyoruz. Çünkü motoru kapatmak için hızlı bir şekilde OFF / ON / OFF yapmamız gerekiyor. Eğer yarım saniye sonra ON sinyali gelmediyse ateşlemeye bir şey yapmıyoruz, sadece loop bölümünün sonundaki kodla tekrar ON komutu gelmesini bekliyoruz.
Eğer OFF komutunu yarım saniye sonra ON komutu izlerse sonraki on saniye içinde tekrar OFF komutu gelmesi halinde ateşlemeyi kapatıyoruz.
Loop bölümü içinde ateşlemeyi açan herhangi bir kod olmadığı için ateşlemenin bir daha açılabilmesi için sistemin resetlenmesi yani enerjinin kesilip tekrar uygulanması gerekiyor. Bu da bir güvenlik faktörü olabilir (başka türlüsünü beceremedim diyemedim!). :)


Kod:
// Benzinli motor ateşlemesini kontrol etmek için akıllı kill switch uygulaması
// Alıcı PWM <= 1500 ise ateşleme kapalı, > 1500 ise ateşleme açık
int rxPin = 12; //Alıcı sinyali 12 nolu uçta
int ignition = 0; //Ateşleme kontrolü 0 nolu uçta
int ignLED = 1; //Ateşleme göstergesi LED 1 nolu uçta
int ign_status = 0; //Başlangıçta ateşleme kapalı. Bu değişken şimdilik bir işe yaramıyor.
int rxPWM = 0; //Alıcı sinyali değişkeni
int i = 0; //Genel FOR döngü değişkeni



void setup()
{
  pinMode(ignition, OUTPUT);
  pinMode(ignLED, OUTPUT);

  while(rxPWM > 1500 || rxPWM == 0) //Eğer alıcı sinyali yoksa ya da ateşleme açıksa bekliyoruz
  {
    rxPWM = pulseIn(rxPin, HIGH);
    digitalWrite(ignLED, HIGH);
    delay(250);
    digitalWrite(ignLED, LOW);
    delay(250);    
  }
  while(rxPWM <= 1500) //Burada ateşlemenin açık komutunu bekliyoruz
  {
    rxPWM = pulseIn(rxPin, HIGH);
  }
  ign_status = 1;
  digitalWrite(ignLED, HIGH);
  digitalWrite(ignition, HIGH); //Ateşlemeyi açtık
}

//Setup çıkışında alıcı sinyali var ve PWM değeri > 1500 yani ateşleme açık durumda


void loop()
{
  rxPWM = pulseIn(rxPin, HIGH);
  if(rxPWM == 0)			//Eğer alıcıdan sinyal gelmiyorsa 500 ms sonra tekrar kontrol ediyoruz. Yine yoksa ateşleme OFF
  {
    delay(500);
    rxPWM = pulseIn(rxPin, HIGH);
    if(rxPWM == 0)
    {
      digitalWrite(ignition, LOW);
      digitalWrite(ignLED, LOW);
      ign_status = 0;
    }
  }
  else if(rxPWM <= 1500)	//Alıcıdan ateşleme OFF komutu geldiyse yarım saniye bekleyip tekrar kontrol ediyoruz
				//Eğer yarım saniye içinde komut ON olmadıysa hiç birşey yapmıyoruz
				//Eğer yarım saniye içinde tekrar ON yapıldıysa bu sistemi arm ediyor
  {
    delay(500);
    rxPWM = pulseIn(rxPin, HIGH);
    if(rxPWM > 1500)
    {
      for(i = 0; i < 100; i ++)	//Sistem arm edilmiş durumda. On saniye boyunca alıcıyı okuyoruz.
				//On saniye içinde OFF komutu gelirse ateşlemeyi kapatıyoruz.
      {
        delay(100);
        rxPWM = pulseIn(rxPin, HIGH);
        if(rxPWM <= 1500)
        {
          digitalWrite(ignition, LOW);
          digitalWrite(ignLED, LOW);
          ign_status = 0;
        }
      }
    }
    while(rxPWM <= 1500)	//Tek bir OFF komutu geldi ama sonrasında tekrar ON/OFF yapılmadı
				//Bu durumda ON komutu gelene kadar burada bekliyoruz
                                //Arada alıcı sinyali giderse yine failsafe için ateşlemeyi kapatıyoruz
    {
      rxPWM = pulseIn(rxPin, HIGH);
      if(rxPWM == 0)
      {
        rxPWM = pulseIn(rxPin, HIGH);
        digitalWrite(ignLED, HIGH);
        delay(250);
        digitalWrite(ignLED, LOW);
        delay(250);    
      }      
    } 
  }

}
 
Arduino ile akıllı kill switch yapalım...

Sen bu isi çözdün abi :) Bakalım Zafer bey 10 üzerinden kaç verecek bu kodlamaya :)


Sent from my iPhone using Tapatalk
 
Arduino ile akıllı kill switch yapalım...

Kapatıldıktan sonra tekrar açılabilir hali. Aklıma geldi de, benzinli motoru çalıştırırken özellikle ilk çalıştırmada jikle aç kapa yaparken ateşlemeyi hep kapatırım. Burada sıkıntı olacaktı. O nedenle yeni versiyon geldi... :)

Kod:
// Benzinli motor ateşlemesini kontrol etmek için akıllı kill switch uygulaması
// Alıcı PWM <= 1500 ise ateşleme kapalı, > 1500 ise ateşleme açık
int rxPin = 12; //Alıcı sinyali 12 nolu uçta
int ignition = 0; //Ateşleme kontrolü 0 nolu uçta
int ignLED = 1; //Ateşleme göstergesi LED 1 nolu uçta
int ign_status = 0; //Başlangıçta ateşleme kapalı. Bu değişken şimdilik bir işe yaramıyor.
int rxPWM = 0; //Alıcı sinyali değişkeni
int i = 0; //Genel FOR döngü değişkeni



void setup()
{
  pinMode(ignition, OUTPUT);
  pinMode(ignLED, OUTPUT);

  while(rxPWM > 1500 || rxPWM == 0) //Eğer alıcı sinyali yoksa ya da ateşleme açıksa bekliyoruz
  {
    rxPWM = pulseIn(rxPin, HIGH);
    digitalWrite(ignLED, HIGH);
    delay(250);
    digitalWrite(ignLED, LOW);
    delay(250);    
  }
  while(rxPWM <= 1500) //Burada ateşlemenin açık komutunu bekliyoruz
  {
    rxPWM = pulseIn(rxPin, HIGH);
  }
  ign_status = 1;
  digitalWrite(ignLED, HIGH);
  digitalWrite(ignition, HIGH); //Ateşlemeyi açtık
}

//Setup çıkışında alıcı sinyali var ve PWM değeri > 1500 yani ateşleme açık durumda


void loop()
{
  rxPWM = pulseIn(rxPin, HIGH);
  if(rxPWM > 1500)
  {
    digitalWrite(ignLED, HIGH);
    digitalWrite(ignition, HIGH);
  }
  if(rxPWM == 0)			//Eğer alıcıdan sinyal gelmiyorsa 500 ms sonra tekrar kontrol ediyoruz. Yine yoksa ateşleme OFF
  {
    delay(500);
    rxPWM = pulseIn(rxPin, HIGH);
    if(rxPWM == 0)
    {
      digitalWrite(ignition, LOW);
      digitalWrite(ignLED, LOW);
      ign_status = 0;
    }
  }
  else if(rxPWM <= 1500)	//Alıcıdan ateşleme OFF komutu geldiyse yarım saniye bekleyip tekrar kontrol ediyoruz
				//Eğer yarım saniye içinde komut ON olmadıysa hiç birşey yapmıyoruz
				//Eğer yarım saniye içinde tekrar ON yapıldıysa bu sistemi arm ediyor
  {
    delay(500);
    rxPWM = pulseIn(rxPin, HIGH);
    if(rxPWM > 1500)
    {
      for(i = 0; i < 100; i ++)	//Sistem arm edilmiş durumda. On saniye boyunca alıcıyı okuyoruz.
				//On saniye içinde OFF komutu gelirse ateşlemeyi kapatıyoruz.
      {
        delay(100);
        rxPWM = pulseIn(rxPin, HIGH);
        if(rxPWM <= 1500)
        {
          digitalWrite(ignition, LOW);
          digitalWrite(ignLED, LOW);
          ign_status = 0;
        }
      }
    }
    while(rxPWM <= 1500)	//Tek bir OFF komutu geldi ama sonrasında tekrar ON/OFF yapılmadı
				//Bu durumda ON komutu gelene kadar burada bekliyoruz
                                //Arada alıcı sinyali giderse yine failsafe için ateşlemeyi kapatıyoruz
    {
      rxPWM = pulseIn(rxPin, HIGH);
      if(rxPWM == 0)
      {
        rxPWM = pulseIn(rxPin, HIGH);
        digitalWrite(ignLED, HIGH);
        delay(250);
        digitalWrite(ignLED, LOW);
        delay(250);    
      }      
    } 
  }

}
 
Arduino ile akıllı kill switch yapalım...

Abi sana zahmet, bununla ilgili devre cizimi de alalim rica etsek :RCKolik:
 
Arduino ile akıllı kill switch yapalım...

Kill switch'in ne olduğu konusunda çok bilgim olmadığı için koda çok bir şey diyemiyorum ama bence Sümer'bey'in "delay" fonksiyonunu bırakıp "Timer" kullanma vakti gelmiş.
 
Arduino ile akıllı kill switch yapalım...

Oleeyyy yeni bi ders konusu çıktı! :)

Zafer Bey, kill switch uzaktan kumanda ile açılıp kapatılan bir switch. Benzinli motorlarda ateşleme beslemesini kesip motoru durdurmaya yarıyor. Genel uygulamada galvanik izolasyon için optokuplör kullanılıyor. Ben de sisteme bir optukuplör bağlamayı planlıyorum. Mehmet'ciğim devresi anormal basit ve kısa süre içinde geliyor.
 
Arduino ile akıllı kill switch yapalım...

Bu uygulamada yok ama hizli verigirisi olan bir uygulamada yada hafiza kullanimi kritik cok sayida timer tanimlamak zorunda kalacagimiz durumlarda interrupt'lari kullanabiliriz.

Soz verdigim tachometre projesinde bir ornegini paylasmaya calisacagim. ( Siparis ettigim bir iki parca gelince hazirlamaya basliyacagim )
 
Arduino ile akıllı kill switch yapalım...

Tamamen katılıyorum ancak interrupt kullanımı bu işte bir tür "koşmak" anlamında. Halbuki ben şu an "emekliyorum". :D Göre göre, okuya okuya, deneye deneye, sizlerin de katkılarıyla öğreneceğiz diye umuyorum. :)
 
Arduino ile akıllı kill switch yapalım...

Sumer hocam bende bir yastan sonra ogrenmeye basladim bu nedenle pek bir iddiam yok , ama okumayi ogrenmeyi cok seviyorum.

Siparis ettigim hall effect sensorleri gelince projeye baslayacagim. Orada interrupt ile yapmayi dusunuyorum. O donemde detayli anlatmaya calisacagim.
 
Arduino ile akıllı kill switch yapalım...

Çok sevinirim. Görebildiğim kadarıyla Arduino çok güçlü bir interrupt sistemine sahip. Onların kullanılması ile birçok işlevi gerçekleştirmek mümkün olacaktır.
 
Arduino ile akıllı kill switch yapalım...

hgumus' Alıntı:
Siparis ettigim hall effect sensorleri gelince projeye baslayacagim. Orada interrupt ile yapmayi dusunuyorum. O donemde detayli anlatmaya calisacagim.
Projenizi merakla bekliyoruz.Yalniz dikkat ettim eski bir uyemiz olmaniza ragmen henuz sizinle tanismamisiz. Sadece Sumer abi gibi doktor oldugunuz biliyoruz ama mesela isminizi ben sahsen bilmiyorum.

Acaba rica etsek kisaca kendinizi ve ilgi alanlarini bizlerle paylasabilir misiniz. Simdiden Tesekkur ederiz :)

 
Arduino ile akıllı kill switch yapalım...

Test edilmiş kill switch kodu ve videosu...

Bu VIDEOYU görmek için izniniz yok. Giriş yap veya üye ol

Kod:
// Benzinli motor ateşlemesini kontrol etmek için akıllı kill switch uygulaması
// Alıcı PWM <= 1500 ise ateşleme kapalı, > 1500 ise ateşleme açık
int rxPin = 12; //Alıcı sinyali 12 nolu uçta
int ignition = 3; //Ateşleme kontrolü 3 nolu uçta
int ignLED = 2; //Ateşleme göstergesi LED 2 nolu uçta
int ign_status = 0; //Başlangıçta ateşleme kapalı. Bu değişken şimdilik bir işe yaramıyor.
int rxPWM = 0; //Alıcı sinyali değişkeni

void setup()
{
  pinMode(ignition, OUTPUT);
  pinMode(ignLED, OUTPUT);

  while(rxPWM <= 1500) //Burada ateşlemenin açık komutunu bekliyoruz
  {
    rxPWM = pulseIn(rxPin, HIGH, 25000);
  }
  ign_status = 1;
  digitalWrite(ignLED, HIGH);
  digitalWrite(ignition, HIGH); //Ateşlemeyi açtık
}


void loop()
{
  rxPWM = pulseIn(rxPin, HIGH, 25000);
  if(rxPWM == 0)
  {
    delay(500);
    rxPWM = pulseIn(rxPin, HIGH, 25000);
    if(rxPWM == 0)
    {
        digitalWrite(ignition, LOW);
        digitalWrite(ignLED, LOW);
        ign_status = 0;
    }
  }
  rxPWM = pulseIn(rxPin, HIGH, 25000);
  if(rxPWM > 1500)
  {
  ign_status = 1;
  digitalWrite(ignLED, HIGH);
  digitalWrite(ignition, HIGH); //Ateşlemeyi açtık
  }
  while(rxPWM > 1500)
  {
    rxPWM = pulseIn(rxPin, HIGH, 25000);
  }
//Alıcıdan ateşleme OFF komutu geldiyse bir saniye bekleyip tekrar kontrol ediyoruz
//Eğer bir saniye içinde komut ON olmadıysa hiç birşey yapmıyoruz
//Eğer bir saniye içinde tekrar ON yapıldıysa bu sistemi arm ediyor
  delay(1000);
  rxPWM = pulseIn(rxPin, HIGH, 25000);
  if(rxPWM > 1500)
  {
    for(int i = 0; i < 50; i ++)	//Sistem arm edilmiş durumda. Beş saniye boyunca alıcıyı okuyoruz.
		//Beş saniye içinde OFF komutu gelirse ateşlemeyi kapatıyoruz.
    {
      rxPWM = pulseIn(rxPin, HIGH, 25000);
      delay(100);
      if(rxPWM <= 1500)
      {
        digitalWrite(ignition, LOW);
        digitalWrite(ignLED, LOW);
        ign_status = 0;
        i = 50;
      }
    }
  }
  while(rxPWM <= 1500)	//Tek bir OFF komutu geldi ama sonrasında tekrar ON/OFF yapılmadı
			//Bu durumda ON komutu gelene kadar burada bekliyoruz
    {
      rxPWM = pulseIn(rxPin, HIGH, 25000);      
    } 
}
 
Arduino ile akıllı kill switch yapalım...

Sümer Yamaner' Alıntı:
Test edilmiş kill switch kodu ve videosu...
Özellikle yanlışla switch dokununca motor stop önlemi çok akıllıca ve tecrübe kokuyor :D
Kendi adıma söyleyeyim video anladım ile kodun sonucunu görmek çok keyifli :halay: Ellerine sağlık abi. :thumbup: