스위치로 LED 켜고 끄기 작성하려고합니다. 내가 생각하는

촉각 푸시 버튼 스위치를 사용하여 LED가 꺼져있을 때 켜고 끄는 코드를 작성하려고합니다. 내가 생각하는 것은 wirePi 라이브러리를 사용하여 올바른 코드라고 썼지 만 꺼져있을 때만 켜고 그 후에 끌 수는 없습니다. 매우 드문 경우에 여러 번 반복해서 누르면 LED가 켜지고 버튼을 누를 때 LED가 꺼지지 만 그것이 제대로 작동하지 않는다고 확신합니다.

#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;
}

회로가 어떻게 배선되어 있는지에 대한 이미지를 첨부했습니다.LEDciruit



답변

배선이 코드에 맞게 보입니다.

문제는 코드가 매우 타이트한 루프에 있다는 것입니다. 이론적으로 버튼을 누르면 루프 본체가 반복적으로 LED를 켜고 끕니다. 이론적으로, 버튼에서 손을 떼면 LED가 켜져 있거나 꺼져있을 가능성이 50/50입니다. 버튼을 누를 때 밝기가 변하는 것을 알 수 있습니다. 눈에 띄지 않을 수 있습니다.

실제로, LED를 켜두는 경향이있는 이유는 이미 켜져 있는지 테스트하는 방법입니다. 쓰기 핀 0 HIGH는 출력에 3.3V를 적용합니다. 그러나 해당 와이어는 LED에 연결되고 핀은 출력으로 구성됩니다. LED는 읽었을 때 HIGH로 등록되지 않을 정도로 낮은 전압을 떨어 뜨릴 수 있지만 때로는 컷오프 근처에 있기 때문에 전압이 떨어집니다.

실제로, 각 버튼을 누를 때마다 LED를 끄고 켜는 코드는 하강 트리거 인터럽트를 사용합니다. 의견에서 지적했듯이 그 경우 인터럽트를 디 바운스하고 싶습니다. 버튼의 이전 상태를 기록하고 버튼 상태가 변경되었을 때만 LED를 변경하여 중단없이 동일한 작업을 수행 할 수도 있습니다. 코드가 작성 될 때 제거하는 것은 이제 의미가 없습니다.

#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;
}


답변

현재 GPIO 상태에서 추론하지 않고 일반 변수에서 “상태”를 유지하는 것이 더 간단합니다.

또한 “busy-loop”는 OS가 프로세스를 허용하는 모든 CPU주기를 소비합니다. 이러한 간단한 프로세스를 위해 CPU로드가 100 %로 증가 함을 알 수 있습니다! usleep()예를 들어 프로세스가 CPU를 다른 작업에 양도하도록 허용해야합니다 . 지연은 또한 스위치를 바운스 해제하는 역할을합니다.

#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;
}


답변