Anahtarı ile LED'i açma ve kapatma


10

Kapalı olduğunda açmak ve dokunsal bir basma düğmesi anahtarı kullanarak kapatmak için bir LED almak için kod yazmaya çalışıyorum. WiringPi kütüphanesi ile doğru kod olduğuna inandığım şeyi yazdım, ama sadece kapalı olduğunda açmak için alabilirim ve bundan sonra kapatmak için alamıyorum. Çok nadir durumlarda ve birçok defa basıldıktan sonra LED açıkken kapanacak ve düğmeye basacağım, ancak eminim çalışması gerektiği gibi değil.

#include <wiringPi.h>
int main (void)
{
    wiringPiSetup ();
    pinMode (0, OUTPUT);
    pinMode (1, INPUT);
    digitalWrite (0, LOW);
    for(;;)
    {
        if(digitalRead (1) == LOW)
        {
            if(digitalRead (0) == HIGH)
                digitalWrite (0, LOW);
            else if(digitalRead (0) == LOW)
                digitalWrite (0, HIGH);
         }
     }
     return 0;
}

Devrenin nasıl bağlandığına dair bir resim ekledim.LEDciruit

c 

2
Kitaplığınızda anahtar için herhangi bir geri dönüş var mı? Değilse muhtemelen LED'i başarılı bir şekilde kapatırsınız ve hemen tekrar açarsınız. Bir durum değişikliği tespit ettikten sonra, kısa bir süre için başka tespitleri yok sayın.

1
@MikeW Ben buna inanmıyorum. Bir if ifadesi işlendikten sonra bir gecikme eklemeyi deneyeceğim.

6
@duskwuff Bu soru kesinlikle programlama ile ilgilidir.

1
led'in geçerli durumunu içeren bir yerel değişkeni (ON / OFF) (muhtemelen bir numaralandırma yoluyla) bir çıkış piminin durumunu okumaya çalışmayın. Bunun yerine, giriş durumu değişikliğinin kenarını giriş piminin yüksekten alçak seviyesine tespit edin. sonra yerel değişken akım durumunu güncelleyin: outputimagevar = (outputimagevar == HIGH)? DÜŞÜK: YÜKSEK; daha sonra digitalWrite (0, outputimagevar); ardından, giriş DÜŞÜK'ten YÜKSEK'e değiştiğinde, YÜKSEK'ten DÜŞÜK algılama mantığını sıfırlayın. Ayrıca, belki de 3 ardışık okumanın hepsinin aynı durumu gösterdiğinden emin olarak, giriş durumunu 'geri' başlattığınızdan emin olun.

Ne yaptım her if deyimi yuva içine yarım saniye gecikme eklemek ve bu sefer doğru çalışıyor gibi görünüyor. Bir şey bana bunun, düğmeye yarım saniyeden daha hızlı basıldığını tahmin edebileceğim için her zaman işe yaramayacak bir tür bruteforce yöntemi olduğunu söylüyor ve muhtemelen ana projemde böyle çalışmaz, bu yüzden cevapların geri kalanı. Herkesin girdisini takdir ediyorum.

Yanıtlar:


4

Kablo bağlantısı kod için doğru görünüyor.

Sorun kod çok sıkı bir döngü içinde olmasıdır. Teoride, düğmeye basıldığında, döngü gövdesi LED'i tekrar tekrar açar ve kapatır. Teorik olarak, düğme bırakıldığında LED'in açık bırakılması (veya sönmesi) 50/50 şanslı olacaktır. Düğmeye basıldığında parlaklıkta bir değişiklik fark ediyor musunuz? Farkedilmek için yeterli olmayabilir.

Pratikte, LED'i açık bırakma eğiliminin nedeni, zaten açık olup olmadığını görmek için test ettiğiniz yöntemdir. Yazma pimi 0 HIGH, çıkışa 3,3 V uygular. Ancak bu tel LED'e bağlanır ve pim bir çıkış olacak şekilde yapılandırılır. LED, okunduğunda YÜKSEK olarak kaydedilmeyecek kadar voltajı düşürüyor olabilir, ancak bazen kesime yakın olduğu için yanar.

Pratikte, LED'i her düğmeye basıldığında kapatmak ve açmak için kod, düşme kenarı tarafından tetiklenen bir kesme kullanacaktır. Yorumlarda belirtildiği gibi, bu durumda kesintiyi geri almak istersiniz. Aynı şeyi, düğmenin önceki durumunu kaydederek ve yalnızca düğme durumu değiştiğinde LED'i değiştirerek de kesintisiz yapabilirsiniz. Kod yazılırken iptal etmek artık bir anlam ifade etmiyor.

#include <wiringPi.h>
int main (void)
{
    wiringPiSetup ();
    pinMode (0, OUTPUT);
    pinMode (1, INPUT);
    digitalWrite (0, LOW);

    int prevButton = HIGH, LED = 0;

    for(;;)
    {
        if(prevButton == HIGH && digitalRead(1) == LOW)  // a falling edge
        {
            prevButton = LOW;

            if(LED)
            {
                LED = 0;
                digitalWrite(0, LOW);
            }
            else
            {
                LED = 1;
                digitalWrite(0, HIGH);
            }
        }
        else if(prevButton == LOW && digitalRead(1) == HIGH)  // a rising edge, do nothing
        {
            prevButton = HIGH;
        )

        // Add a delay here to debounce the button 

    }
    return 0;
}

0

Mevcut durumdaki GPIO durumundan çıkarım yapmak yerine "durumu" normal değişkenlerde tutmak daha kolaydır.

Ayrıca "meşgul döngü", işletim sisteminin işleme izin vereceği her CPU döngüsünü tüketir; böyle basit bir işlem için CPU yükünüzün% 100'e çıkacağını göreceksiniz! İşlemin, usleep()örneğin bir çağrı ile CPU'yu diğer görevlere bırakmasına izin vermelisiniz . Gecikme ayrıca anahtarın sektirilmesini de sağlar.

#include <wiringPi.h>
#include <unistd.h>

int main (void)
{
  wiringPiSetup ();
  pinMode (0, OUTPUT);
  pinMode (1, INPUT);
  digitalWrite (0, LOW);

  // Initial state
  int led = LOW ;
  bool button_down = (digitalRead(1) == LOW) ;

  for(;;)
  {
    // If button-down event (Hi-lo transition)...
    if( !button_down && digitalRead(1) == LOW )
    { 
      // Keep button state
      button_down = true ;

      // Toggle LED state
      led = (led == LOW) ? HIGH : LOW ;
      digitalWrite( 0, led ) ;
    }
    // Button up event...
    else if( button_down && digitalRead(1) == HIGH ) 
    {
      // Keep button state
      button_down = false ;
    }

    usleep( 10000 ) ;
  }

  return 0;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.