전자, 전기, 소프트웨어, 기계, 3D 프린터, 아두이노, 라즈베리파이, 쇼핑몰 창업

전체 페이지뷰

이 블로그 검색

최신글

[Blender] 3D viewport 사용법

[강좌] 11. 스위치 디바운싱 코드 작성하기


무작정 보고 따라하며 배우는 아두이노 강좌입니다.
아두이노 공식 사이트에서 제공하는 강좌를 바탕으로 작성되었습니다.
해당 게시글은 Arduino UNO 보드를 기준으로 작성되었습니다.

11. 스위치 바운싱 현상 해결하기


  지난 강좌에서 버튼을 사용하여 아두이노를 제어하는 방법을 알려드렸습니다. 그 과정에서 풀업/풀다운 저항에 대해 약간 언급하였으나, 풀업 풀다운 저항은 스위치 작동 후 잔전류에 의한 플로팅 현상이고, 이 잔전류를 흘려보내 깔끔한 스위치 제어를 하게 해 줍니다.

  이번 강좌에서 말씀드릴 바운싱 현상은 플로팅 현상과 다르게 스위치를 누르는 순간의 불규칙한 전압 상태를 뜻합니다. 플로팅은 스위치를 작동 후 남은 잔전류에 의한 것이라면 바운싱은 스위치를 누르는 과정에서 두 접점이 가까워지는 과정에 전기적 인력 등 여러 요인에 의해 요동치는 상태를 뜻합니다.

  바운싱 현상을 해결하기 위한 디바운싱 현상은 간단한 원리로 작동됩니다. 풀업/풀다운 저항처럼 하드웨어적으로 해결하는 것이 아닌, 소프트웨어상으로 스위치를 누른 후 일정 시간 후 다시 스위치의 상태를 점검하여 실제로 스위치를 작동한 것인지, 바운싱에 의해 잘못 처리된 입력인지 확인하게 됩니다.

  따라서, 본 강좌의 경우 새로운 코드를 알려드리기보다는 기존에 알려드린 코드를 응용하여 제작된 디바운싱 코드를 알려드립니다. 필자는 본 강좌의 경우 코드를 일일이 해석하여 분석하는 능력을 키우는 기회가 되었으면 합니다. 

준비물 ( 아두이노와 PC는 기본입니다 )

10k 저항, 브레드보드, 점퍼케이블, 푸시버튼

회로도

이전 강좌와 같은 회로입니다.
참고 : http://gucciheon.blogspot.kr/2018/03/10.html

코드설명 

  이번 소스 설명은 이전 강좌들에서 알려드린 소스들로 응용된 강좌입니다.

  일반적으로 디바운싱을 위한 코드로 delay()를 사용하여 지연을 주고 스위치의 상태를 확인하는 경우도 있지만, delay()를 사용하게 되면 전체 코드의 작동이 일시적으로 중단됩니다. 그래서 지난 강좌에서 알려드린 millis()를 사용하여 일정 시간간격으로 스위치를 제어합니다.
millis() 참고 : http://gucciheon.blogspot.kr/2018/03/9-delay-led.html

  디바운싱 코드는 이전 강좌를 읽어보신 분이라면 충분히 직접 작성해보실 수 있습니다.

  아래 아두이노 공식 홈페이지에서 제공하는 예제 소스는 ledState , buttonState(=reading) , lastButtonState , lastDebounceTime , debounceDelay 라는 변수들을 생성하여 millis()와 함께 스위치를 제어합니다. ledState로 현재 LED의 출력을 제어합니다. buttonState로는 버튼이 장착된 핀의 입력 값을 저장합니다. lastButtonState는 현재의 버튼 입력값과 기존 버튼 입력값을 비교해서 바운싱 현상을 체크하는 기준으로 사용됩니다. 이렇게 버튼 입력값을을 비교하는 시간간격을 설정하기 위해 debounceDelay 변수를 사용하고 마지막으로 버튼의 입력값이 바뀐 시점을 lastDebounceTime으로 지정하여 millis()에서 lastDebounceTime의 값을 뺸 것이 debounceDelay보다 크면 버튼의 상태를 재확인하게 됩니다.

말로 설명하니 어렵지요?..ㅎㅎ
코드를 보며 한줄한줄 해석을 시작해 보세요!

/*
 Debounce

 Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
 a minimum delay between toggles to debounce the circuit (i.e. to ignore
 noise).

 The circuit:

 * Note: On most Arduino boards, there is already an LED on the board
 connected to pin 13, so you don't need any extra components for this example.

 * LED attached from pin 13 to ground
 * pushbutton attached from pin 2 to +5V
 * 10K resistor attached from pin 2 to ground

 created 21 November 2006
 by David A. Mellis
 modified 30 Aug 2011
 by Limor Fried
 modified 28 Dec 2012
 by Mike Walters
 modified 30 Aug 2016
 by Arturo Guadalupi


 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/Debounce
 */

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
}

0 개의 댓글:

댓글 쓰기