안녕하세요 번개쥐 입니다.
오늘은 잠깐 잡설을 조금 하고, 본격적으로 강의 시작하겠습니다.

잡설이라는게 다른게 아니라, 이제는 슬슬 작품을 하나 따라 만들어 볼때가 된거 같은데요. 물론, 많은분이 제글을 읽으시는 것은 아니겠지만. 그래도 어떤 작품을 선호하는지 궁금해서 말이죠.

크게 두가지가 있습니다. 
첫번째는 우리가 흔히 보는 오락실에 있는 오락기 같이 액추에이터(모터같은거)가 적고, 대신에 버튼이 많이 들어가고 lcd 등을 이용한 여러가지 전자기기

두번째는 rc카나 드론 같이 액추에이터 제어가 주가 되는 흔히 말하는 어른을 위한 장난감(?)

일단 두 작품에서 장단점은 다음과 같습니다.
장점
첫번째 작품은 일단 돈이 적게듭니다. 그리고 이론적으로 필요한건 제가 쓴 글만 읽어 보면 됩니다.

두번째 작품은 아무래도 장난감이 신나죠?(모터 돌아가고 위용위용 거리니깐요 ㅋㅋ)

단점
첫번째 작품은 아무래도 좀 심심합니다. 프로그래밍을 좀 많이 해야 한다는 것도 있고요.

두번째 작품은 돈이 많이듭니다. 돈이...

다들 어떻게 생각하시는지... 아니면 뭔가 이런 거 제가 해보고 싶습니다. 하는 아이디어 있으시면 쪽지 주세요. 반영합니다.

오늘은  스위치를 쓰는 것을 배워보도록 하겠습니다. 
 
오늘 필요한 준비물은 점퍼선과 저항 그리고 브레드보드 입니다.
 

회로도로 표현했습니다. V부분(노랑선)이 아두이노에서 5V핀이 되고 GND부분(파랑선)은 GND핀에 연결해 주시면 됩니다. 그리고 S(스위치) 와 R(저항)사이에 또 점퍼선(사진에서 주황색선)을 연결해 주시면 됩니다. 그리고 그 점퍼선은 원하시는 핀에 꽂아 주세요.(저는 12번 핀에 꽂았습니다.)

 

자, 이번에 필요한 코드는 위와 같습니다. Serial 관련 부분은 이제 충분히 설명 드렸으나, 그래도 한번도 살펴 보지요. 
setup 함수 안의 코드는
Serial.begin(9600)은 Serial 통신의 속도를 정하고 통신의 시작을 알립니다.
pinMode는 12번 핀의 상태를 INPUT 즉, 얘를 입력으로 쓰겠다는 이야기 입니다.

loop 함수 안의 코드를 봅시다.
int i = digitalRead(12); 이부분은 그대로 해석 하시면 됩니다. 디지털로 읽겠다. 즉, on/off 여부만을 읽겠다는 얘기입니다. 그리고 on은 1로 반환되고, off는 0으로 반환 됩니다.
Serial.println(i); i에 스위치에서 읽은값을 저장이 되었죠? 그걸 serial 통신으로 출력하는 겁니다.
delay(10); 10마이크로초 만큼 기다렸다가 루프를 다시 돕니다. 이제 이소스를 컴파일하여 전송하여 봅시다.
전송이 끝났다면 시리얼 모니터를 열어 봅시다.
 
 
버튼을 누르지 않으면 0만 보일겁니다.
 
버튼을 누르면 1로 바뀌겠죠?

그런데 자, 잠시 생각을 해봅시다. c언어는 순차지향적 언어죠? 예를 들어 이런 코드를 짯다고 해봅시다.

 
이런 프로그램을 짠다고 생각해 봅시다. 지금 위에 있는 코드를 응용하여 짠다면 어떤 문제점이 생길까요?
한번 고민해 봅시다.





고민 해 보셨나요? 만약에 입력이 프로그램이 돌아가는 중간에(switch on? 이과정이라던가) 걸려버리면 인식을 못하게 된다는 문제점이 있습니다. 그래서 가끔 전자기기 중에 버튼을 몇번 눌러야 스위치가 온되는 것들이 있는게 저런것 때문이지요.

 
 

자 위의 프로그램을한번 봅시다.(이번에는 입력핀을 2번으로 바꿔 주세요!)
이번에는 스위치가 들어올때 마다 0,1로 바뀌는 프로그램을 짜본겁니다. 어, 이번에는 digitalRead가 안보이네? pinMode 가 없네? 하고 의아하신 분들이 있으실 겁니다.

이번에 배울 개념은 인터럽트(intterupt)입니다. intterupt는 뭐냐하면 arduino에 박혀있는 atmega328칩중에서 자체적으로 이미 만들어져 있는 버튼이라고 보시면 됩니다.

그리고 이것의 유용한 장점이 무엇이냐면 digitalRead에 비해 순차적인 부분에서 영향을 덜받는다는 점입니다. 즉, 아무때나 입력을 해도 다 인식을 할 수있다는 점이지요.

attatchIntterupt라는 함수를 setup 에서 선언해주기만 하면 됩니다.
attatchIntterupt(인터럽트 번호, on이 될시에 행할 코드의 함수, 언제 실행할것인가(FALLING,RISING,CHANGE중에 선택하시면 되는데 FALLING이나 CHANGE중에 아무거나 쓰셔도 보통 별 이상 없습니다.)

인터럽트 번호는 핀번호와는 다릅니다! 인터럽트는 특정 핀에서만 지원을 해주는데요. arduino uno의 경우 2,3번 핀이 인터럽트를 지원 하지요. 그리고 2번핀의 인터럽트 번호는 0번이고 3번핀은 인터럽트 번호 1입니다.

일단 지금까지 본 함수들과는 약간 다를 겁니다. attachInterrupt함수는 함수 인자(argumet)에 함수를 받는 콜백 함수라고 합니다. 그래서 함수를 하나 짜고 그걸 이안에 넣는 방식으로 코딩을 해야 하지요.

위의 코드는 계속 Serial로 보내는게 아니라 바뀔때만, 즉 한번 누를때마다 값을 출력하는 프로그램입니다. 

 
이 코드가 조금 난해 해 보이실수도 있는데 
void test()
{
 if(i==0)
i=1;
else if(i==1)
i=0;
}
이코드와 동일한 의미 입니다. 즉, 0이면 1로 바꾸고 1이면 0으로 바꾸는 겁니다.
그리고, 이건 좀 덜 중요한 부분인데 attachIntterupt의 인자로 쓰이는 함수 안에서 쓰이는 변수는 전부 volatile을 붙여서 선언을 해주어야 합니다. (맨앞의 volatile int i=0; 가보이시죠?)
이건 아직 설명하기에는 조금 시기 상조인거 같아 넘어가도록 하겠습니다.(나중에 이런 저수준 제어에 관해 한번 설명하는 글을 올리도록 하겠습니다!)

코드를 업로딩 해서 시리얼 모니터를 켜고 스위치를 눌러보면
 
요런식으로 한번 한번 출력 될겁니다.

이번에는 조금더 활용하는 숙제를 내보도록 하겠습니다. digitalRead를 쓰던 attachIntterupt를 이용하건 스위치를 이용하여 13번 핀에 on, off신호를 제어 해 보세요!(만약 성송하신다면 스위치를 이용하여 아두이노에 기본 장착된 led를 제어 할수 있을 겁니다.)


오늘 내용은 유익하고 쉬우셨나요? 다음에 더 좋은글로 찾아 뵙도록 하겠습니다.