지난 글에서 이어집니다
디스플레이 개발은 어느 정도 완성되었으니, 이제 회로를 꾸미는 일을 하고 있다. 그런데 비상정지버튼을 설치하고서 아두이노 Interrupt 기능을 사용하려고 하는데, 도대체가 이렇게 헷갈리는 기능은 처음 보았다.
Interrupt가 필요했던 배경은, 아두이노로 모터를 제어할 때 이상 행동이 잦기 때문이다. 일반적인 데스크탑이나 노트북에서 윈도우 오류가 가끔씩 뜨는 것처럼, 아두이노도 오류가 발생하는데 빈도가 훨씬 높다. 어깨 재활 기구(이전 글 참고)랍시고 기구를 만들었는데 어깨가 뽑힐 정도로 모터가 빠르게 움직여 버린다면, 여기저기서 고소당할지도 모르는 일이다.
그래서 어린 시절 재난영화에서 익히 보았던 비상정지버튼을 사다가, 디자인하는 제품에 장착했더랬다. 버튼을 누르면, 아두이노에서 반복되는 Loop 기능을 깨부수고 Interrupt 기능이 아두이노를 장악해버리길 기대하면서. 그렇다면 아두이노가 이상 행동을 하더라도, 빠르게 버튼을 누른다는 가정하에 작동을 중단시킬 수 있는 것이다.
말하자면, 위와 같은 구조를 상상했던 것이다. 노트북에 블루스크린이 뜨면 전원버튼으로 컴퓨터를 꺼버린 뒤에 재시작하는 것이 국룰인만큼, Interrupt 함수가 발생하고 나면 아두이노를 재시작해버리면 되겠거니- 싶었다.
Interrupt 함수 자체는 구현하기 참 간단하다. 코드는 대략 아래처럼 짰더랬다.
#define interruptPin 18
volatile boolean emergency = 0;
void setup()
{
attachInterrupt(digitalPinToInterrupt(interruptPin),emergency_break, FALLING);
Serial.begin(9600)
}
void loop()
{
//모터 제어
Serial.print("내용")
}
void emergency_break(){
//Interrupt 함수
Serial.print("Emergency")
}
그런데 웬걸, 결과는 심각하게 달랐다. 시리얼 모니터 결과는 아래와 같다.
내 예상에 따르면, "EMERGENCY"가 출력됨가 동시에, 아두이노의 void loop가 붕괴되면서 작동이 멈춰야했다. 컴퓨터로 롤을 하다가 블루스크린이 떴을 때, 창을 내리고 계속 게임을 할 수는 없지 않은가? 그런데 void loop는 멀쩡하게 살아있었다. Interrupt로 emergency_break 함수를 시행한 뒤에도 계속해서 Serial 출력을 뱉어내는 질긴 생명력에 감탄할 수밖에 없었다.
아두이노 포럼같은 곳에서도 해당 방법을 문의하는 글들이 상당히 많았는데, 해결책이 조금 요상하다. 말로 풀어보자면, 인터럽트 함수를 통해 어떤 변수의 상태를 바꾸고(예를 들면, emergency_state = True) void loop() 안에는 while 구문을 삽입함으로써 (같은 예로서, while(emergency_state = False){//모터제어} break;) 정상작동과 비상사태를 구분하라는 것이다.
그런데, 아무리 생각해봐도 loop 안에서 문제가 발생했기에 emergency를 사용하는 상황에서, loop 안에 정상상태와 비상사태를 구분하는 조건문이 잘 작동할 수 있을까 의문이다. 환자들로부터 뺨이라도 맞지 않기 위해서는 보다 안전한 장치가 필요한데 아직 답이 나오지 않는다.
그래서 Interrupt를 대체 어떻게 해야 할까나.
그냥 뺨 맞을 때 반대쪽 뺨이라도 내줘야 하나?
'트렌드 한눈에 보기 > 학계 트렌드' 카테고리의 다른 글
아두이노 통신 고군분투의 기록 - UART vs I2C (0) | 2021.04.01 |
---|---|
책상 위에 서서 생각할 수 있는 방법 - Molex Climping (0) | 2021.03.24 |
한국 정부에서 1600억을 들여 개발 중인 아이언맨 슈트 - 엔젤로보틱스 (3) | 2021.03.05 |
아두이노 2.42 inch OLED 테스트 (0) | 2021.03.03 |
기계공학의 최전선 (1) - 종이접기를 활용한 충격파 흡수 (0) | 2021.03.01 |