[Arudino] Interrupt

HEEJOON MOON·2022년 6월 4일
0

Interrupt in Arduino

아두이노는 인터럽트 제어를 위한 함수를 제공

  • attachInterrupt(intNo, ISR, mode): ISR(Interupt Service Routine)를 등록
  • detachInterrupt(intNo): ISR을 해제
  • Interrupts(): 전체 인터럽트 활성화
  • noInterrupts(): 전체 인터럽트 비활성화

attachInterrupt(intNo, ISR, mode)

  • intNo : 인터럽트 번호에 따른 인터럽트 제어
  • ISR : 인터럽트 발생 시 실행될 함수의 이름을 기재.
    이때 delay()는 작동하지 않으며, 매개변수 사용이 불가.
  • mode : 인터럽트 발생 조건.
    1) Falling : 신호가 HIGH->LOW 변경시 인터럽트 발생
    2) RISING : 신호가 LOW->HIGH 변경시 인터럽트 발생
    3) CHAGNE : 신호가 변경시(falling, rising) 인터럽트 발생
    4) LOW : 신호가 LOW인 동안 인터럽트 반복 호출

Keypad 및 Interrput를 활용한 LED 제어

< HW settings >

< SW >

#include <MsTimer2.h>

int Button = 2; // Keypad를 위한 입력 핀 정의. 이때 2번핀을 사용해야 인터럽트 0번을 사용가능
int LED[3] = {5, 6, 7}; // Arduino LED PIN 정의

// Timer function 정의
void LedControl(){
	static int counter = 0;
    static byte output = HIGH;
    
    digitalWrite(Led[counter++], output); // LED ON/OFF
    
    if(counter>1){
    	counter = 0;
        output = !output; // 현재와 반대 상태로 전환
    }
}

// ISR
void ButttonLedControl(){
	static byte output = HIGH; // LED ON/OFF를 결정한 바이트
    
    digitalWrite(LED[2], OUTPUT); // LED[2](16번 LED) ON/OFF 수행
    output = !output; // 현재 상태와 반대로 전환
}

// void setup(){
	int i;
    
    // ButtonPin을 입력으로 설정
	pinMode(BUTTON, INPUT_PULLUP); // 별도의 저항 설치 없이 INPUT가능
	
    // LED PIN을 출력으로 설정
    for(i=0; i<3; i++)
    	pinMode(Led[i], OUTPUT);
        
    // 인터럽트 설정
    attachInterrupt(0, ButtonLedControl, RISING); // 0번 인터럽트가 Rising조건으로 발생시, ButtonLedControl ISR 수행
    
    // Timer 설정
    MsTimer2::set(500, LedControl); // 500ms마다 LedControl함수 수행
    
    // Timer 시작
    MsTimer2::start();
}

void loop(){}

Keyoad버튼 2개를 사용한 인터럽트

< SW >

#include <MsTimer2.h>
int Button1 =2; // 아두이노 버튼 핀1 정의 (인터럽트 0번 사용)
int Button2 =3; // 아두이노 버튼 핀2 정의 (인터럽트 1번 사용)
int Led[3] = {5, 6, 7}; // LED Pin 정의

int debounceDelay = 50; //바운드에 대한 기준 시간값
unsigned long lastDebounceTime = 0; // 현재시간값을 가져올꺼니간 자료형은 같은형으로 맞춘다.
int buttonstate=1; //왜! 1이냐면 내부풀업모드 버턴이 초기값이 1이여서 초기값을 1로 잡음.
int lastButtonState=1; //마지막 버턴상태를 기록한다. 왜냐면 다음 버턴상태와 비교하기 위해서이다.
boolean ledState = false; // LED 반전 상태값을 만들려고 변수를 선언했군요.

// Timer function
void LedControl(){
    static int counter =0; // ISR에서 사용할 배역 인덱스
    static byte output = HIGH; // LED ON/OFF
    // LED 1~9 ON/OFF 수행
    digitalWrite(Led[counter++], output);
    if(counter > 1){
        counter =0; // 배열 인덱스 초기화
        output =!output; // 현재와 반대 상태로 전환
      }
}
// ISR
void ButtonLedControlOn(){
    // Button값을 읽는다
    int reading = digitalRead(Button1); 
    
    // Button의 변화가 읽어났으면 변화 시간을 저장.
    if (reading != lastButtonState){
      lastDebounceTime = millis(); 
    }
    
    // DebounceDelay 이상일 때만 실행
    if ((millis() - lastDebounceTime) > debounceDelay){
       digitalWrite(Led[2], HIGH); // LED[2](16번 LED) ON 수행
    }
    
    // 현재 읽은 버튼의 상태를 다음 버튼의 상태와 비교하기 위해 저장
    lastButtonState = reading;
}

void ButtonLedControlOff(){
    // Button값을 읽는다
    int reading = digitalRead(Button1); 
    
    // Button의 변화가 읽어났으면 변화 시간을 저장.
    if (reading != lastButtonState){
      lastDebounceTime = millis(); 
    }
    
    // DebounceDelay 이상일 때만 실행
    if ((millis() - lastDebounceTime) > debounceDelay){
       digitalWrite(Led[2], LOW); // LED[2](16번 LED) ON 수행
    }
    
    // 현재 읽은 버튼의 상태를 다음 버튼의 상태와 비교하기 위해 저장
    lastButtonState = reading;
}



void setup() 
{
    int i;
    
   // Button 핀을 입력으로 설정
   pinMode(Button1, INPUT_PULLUP);
   pinMode(Button2, INPUT_PULLUP);
   
   // LED PIN을 출력으로 설정
   for(i=0; i<3; i++){
      pinMode(Led[i], OUTPUT);
   }
   
   // 인터럽트 설정
   attachInterrupt(0, ButtonLedControlOn, RISING);
   attachInterrupt(1,ButtonLedControlOff, FALLING);
   
   // Timer 설정
   MsTimer2::set(500, LedControl);
   
   // Timer 시작
   MsTimer2::start();
}
void loop() {
}

Polling

#include <MsTimer2.h>
int Button1 =2; // 아두이노 버튼 핀1 정의 
int Button2 =3; // 아두이노 버튼 핀2 정의 
int Led[3] = {5, 6, 7}; // LED Pin 정의

int debounceDelay = 50; //바운드에 대한 기준 시간값
unsigned long lastDebounceTime1 = 0; 
unsigned long lastDebounceTime2 = 0; 
int buttonstate1=1;
int lastButtonState1=1; 
int buttonstate2=1;
int lastButtonState2=1; 
boolean ledState = false; 

// Timer function
void LedControl(){
    static int counter =0; // ISR에서 사용할 배역 인덱스
    static byte output = HIGH; // LED ON/OFF
    // LED 1~9 ON/OFF 수행
    digitalWrite(Led[counter++], output);
    digitalWrite(Led[2], ledState);
    if(counter >1){
        counter =0; // 배열 인덱스 초기화
        output =!output; // 현재와 반대 상태로 전환
      }
}
void setup() 
{
    int i;
    
    // Button 핀을 입력으로 설정
    pinMode(Button1, INPUT_PULLUP);
    pinMode(Button2, INPUT_PULLUP);

   // LED PIN을 출력으로 설정
   for(i=0; i<3; i++){
      pinMode(Led[i], OUTPUT);
   }
   
   // Timer 설정
   MsTimer2::set(500, LedControl);
   // Timer 시작
   MsTimer2::start();
}
void loop() {
   int reading1 = digitalRead(Button1); //버턴값 읽는다.
   int reading2 = digitalRead(Button2); //버턴값 읽는다.

    if (reading1 != lastButtonState1) { //버턴의 변화가 일어났니!
        lastDebounceTime1 = millis(); // 그러면 현재 시간을 저장한다.
    }

    if (reading2 != lastButtonState2) { //버턴의 변화가 일어났니!
        lastDebounceTime2 = millis(); // 그러면 현재 시간을 저장한다.
    }
    
    if ((millis() - lastDebounceTime1) > debounceDelay | (millis() - lastDebounceTime2) > debounceDelay) {  //버턴변화가 50시간값 안에 발생했으면 바운스(채터링)으로 무시
                                
        if(reading1!=buttonstate1){ // 버턴이 On/Off 됐는지 확인(버턴의 변화가 일어났는가)       
            buttonstate1=reading1; //버턴의 변화가 일어났으면 그 변화를 기록했다가 다음 버턴 변화의 비교대상이 됨
            ledState=HIGH; 
        }

        if(reading2!=buttonstate2){ // 버턴이 On/Off 됐는지 확인(버턴의 변화가 일어났는가)       
                buttonstate2=reading2; //버턴의 변화가 일어났으면 그 변화를 기록했다가 다음 버턴 변화의 비교대상이 됨
                ledState=LOW; 
        }
    }
    
    lastButtonState1 = reading1;
    lastButtonState2 = reading2;
}
profile
Robotics, 3D-Vision, Deep-Learning에 관심이 있습니다

0개의 댓글