5. 아두이노로 LED와 스위치 제어하기 - 스마트 폰으로 제어하는 아두이노 -
강의 개요 아두이노 보드의 디지털입출력을 이용하여 입력을 받아들여 그 입력에 따라 출력을 제어 방법과 명령어 학습 on/off 스위치를 이용하여 출력의 상태를 제어하는 것은 오래되고 가장 손쉬운 제어 방식이지만, 최근 스위치의 입력을 블루투스나 WiFi 등을 활용하여 원격으로 제어 가능
5.1 디지털 입력 제어 : LED와 Switch 제어 디지털입출력 핀으로 디지털 입력을 받아들이는 방법 회로 구성 2개의 디지털입출력 핀 사용 각각 디지털입력을 받아들일 수 있는 on/off 스위치와 디지털출력을 확인하기 위한 LED 연결 스위치 동작 버튼이 눌려지면 +5V의 전압이 접지로 흘러 "0"이 NOT 게이트에 입력되고 10번 핀은 "HIGH" 버튼이 떨어지면 +5V의 전압이 NOT 게이트에 입력되어 10번 핀은 "LOW"
Frizing을 이용한 도면 제작 (Frizing, : www.fritzing.org 브레드 보드에 아두이노 보드와 저항, LED, 스위치 등의 여러 가지 부품을 모의 구성해 볼 수 있도록 하여 주며, 회로도나 PCB 제작을 쉽게 할 수 있도록 도와 주는 프로그램
예제 5.1 디지털입출력 핀 10번의 입력제어 디지털입출력 핀 10번 : 스위치 연결 디지털입출력 핀 8번 : LED를 연결 스위치가 눌려지면 HIGH가 입력되고, 떨어지면 LOW가 입력 디지털입출력 핀 8번 : LED를 연결 스위치가 입력되면 LED가 켜지도록 제어 입출력 설정 setup( )함수 안에서 pinMode( )함수를 이용 디지털입출력 핀 8번은 출력으로 설정 디지털입출력 핀 10번은 입력으로 설정 아두이노 보드의 디지털입출력 핀은 디지털 출력에 사용하였던 핀을 모두 입력으로 사용 가능 void setup() { pinMode(8, OUTPUT); pinMode(10, INPUT); }
입력 판단 if-else문 사용 버튼 스위치가 눌려지면, LED가 연결되어 있는 10번 핀에 "HIGH"를 출력하고, 그렇지 않으면 "LOW"를 출력하여 LED를 OFF
예제 5.1의 스케치 int pin_led=8; int pin_sw=10; 정수형 변수 pin_led와 pin_sw에 각각 디지털입출력 핀 8번과 10번을 지정 void setup() { pinMode(pin_led, OUTPUT); pinMode(pin_sw, INPUT); } 디지털입출력 핀 8번(pin_led)을 출력으로 설정 디지털입출력 핀 10번(pin_sw)을 입력으로 설정 void loop() { i nt sw_in=digitalRead(pin_sw); 핀 10번(pin_sw)으로부터 값을 읽어 sw_in저장 if(sw_in==1) { digitalWrite(pin_led, HIGH); else digitalWrite(pin_led, LOW); digital_in가 “1”이면, LED을 on digital_in가 “1”이 아니면, LED을 off
5.2 다중 if-esle문을 이용한 디지털 제어 여러 개의 상태조건을 판단하여 조건에 따라 제어
예제 5.2 4개의 스위치와 LED를 이용한 입출력 제어 디지털입출력 핀 9~12번 : 스위치 연결 디지털입출력 핀 4~7번 : LED 연결 스위치가 눌려지면 각 스위치에 지정된 LED가 on되도록 제어 if-else문 사용
예제 5.2의 주요 개념 배열 이용 버튼 스위치 연결된 디지털입출력 핀 4개 : 배열 pin_SW[ ] LED 연결된 디지털입출력 핀 4개 : 배열 pin_LED[ ]
예제 5.2의 스케치 int pin_LED[ ]= {4, 5, 6, 7}; int pin_SW[ ]= {9, 10, 11 ,12}; int val; int i ; 배열 pin_LED : 디지털입출력 핀 4, 5, 6, 7번 배열 pin_SW : 디지털입출력 핀 9,10,11,12번 스위치 입력을 받기 위한 변수 for문을 위한 변수 void setup() { for(i=0; i<4; i++) { pinMode(pin_LED[i], OUTPUT); pinMode(pin_SW[i], INPUT); } 핀 4, 5, 6, 7번을 출력모드 지정 핀 9, 10, 11, 12번을 입력모드 지정 void loop() { for(i=0; i<4; i++) { val=digitalRead(pin_SW[i]); if(val==1) { digitalWrite(pin_LED[i], HIGH); else { digitalWrite(pin_LED[i], LOW); ① sw1(D9)가 눌려지면 LED1(D4)에 HIGH출력 나머지 LED2, LED3, LED4는 LOW출력 ② sw2(D10)가 눌려지면 LED2(D5)에 HIGH출력 나머지 LED1, LED3, LED4는 LOW출력 ③ sw3(D11)가 눌려지면 LED3(D6)에 HIGH출력 나머지 LED1, LED2, LED4는 LOW출력 ④ sw4(D12)가 눌려지면 LED4(D7)에 HIGH출력 나머지 LED1, LED2, LED3은 LOW출력
예제 5.3 4개의 기능 스위치에 의한 LED 제어 디지털입출력 핀 8개에 4개씩 스위치와 LED를 연결하고, 스위치가 눌려지면 각 스위치에 다음과 같이 지정된 LED 동작이 되도록 제어 스위치 선택 LED 동작 sw1 4개의 LED가 동시에 on sw2 4개의 LED가 동시에 on/off sw3 4개의 LED가 오른쪽에서 왼쪽으로 순차적으로 on sw4 4개의 LED가 왼쪽에서 오른쪽으로 순차적으로 on 스위치가 눌려지지 않으면 4개의 LED가 동시에 off
예제 5.3의 주요개념 if-else문 사용 버튼 스위치가 연결되어 있는 배열 pin_SW[0]에서부터 순차적으로 스위치가 눌려져 입력이 발생하였는지 검사 눌려졌으면 해당하는 기능 수행
예제 5.3의 스케치 1 int pin_LED[]= {4, 5, 6, 7}; int pin_SW[]= {9, 10, 11 ,12}; int val; int i; 배열 pin_LED : 디지털입출력 핀 4, 5, 6, 7번 배열 pin_SW : 디지털입출력 핀 9,10,11,12번 스위치 입력을 받기 위한 변수 for문을 위한 변수 void setup() { for(i=0; i<4; i++) { pinMode(pin_LED[i], OUTPUT); pinMode(pin_SW[i], INPUT); } 핀 4, 5, 6, 7번을 출력모드 지정 핀 9, 10, 11, 12번을 입력모드 지정
예제 5.3의 스케치 2 void loop() { loop()의 시작 if(digitalRead(pin_SW[0])==1){ for(i=0; i<4; i++) { digitalWrite(pin_LED[i], HIGH); } sw1(D9)가 눌려지면 4개의 LED가 동시에 on else if(digitalRead(pin_SW[1])==1){ delay(1000); sw2(D10)가 눌려지면 4개의 LED가 동시에 on/off
예제 5.3의 스케치 3 else if(digitalRead(pin_SW[2])==1){ for(i=0; i<4; i++) { digitalWrite(pin_LED[i], HIGH); delay(1000); } sw3(D11)가 눌려지면 4개의 LED가 오른쪽에서 왼쪽으로 순차적으로 on else if(digitalRead(pin_SW[3])==1){ digitalWrite(pin_LED[3-i], HIGH); sw4(D12)가 눌려지면 4개의 LED가 왼쪽에서 오른쪽으로 else { digitalWrite(pin_LED[i], LOW); 스위치가 눌려지지 않으면 모든 LED off loop()의 끝
5.3 switch-case문을 이용한 디지털 제어 스위치 등의 조건에 따라 좀 더 편리하게 제어하기 하기 위하여, if-else문 대신 switch-case문 사용하는 방법을 살펴보자.
예제 5.4 case문을 사용한 기능 스위치 제어 if-else문 대신 case문 사용 digitalRead()와 bitWrite()함수를 이용하여, switch( )를 위한 case 번호 생성 bitWrite(select, i, val) 변수 select의 i번째의 비트에 val의 값 "1"을 설정하는 함수 bitWrite(select, 3, "1") 실행 예(변수 select의 초기 값 “0”), for(i=0; i<4; i++) { val=digitalRead(pin_SW[i]); bitWrite(select, i, val); }
스위치 배열 pin_SW[]= {SW0, SW1, SW2, SW3}이면, 선택되는 select값 스위치 선택 SW0 SW1 SW2 SW3 select 2진수 값 00000001 00000010 00000100 00001000 case문 전달 값 1 2 4 8
예제 5.4의 스케치1 int pin_LED[]= {4, 5, 6, 7}; int pin_SW[]= {9, 10, 11 ,12}; int i, j, sw=0; boolean select, val; 배열 pin_LED: 디지털입출력 4, 5, 6, 7번 배열 pin_SW: 디지털입출력 9,10,11,12번 void setup() { for(i=0; i<4; i++) { pinMode(pin_LED[i], OUTPUT); pinMode(pin_SW[i], INPUT); } setup문 핀 4, 5, 6, 7번을 출력모드 지정 핀 9, 10, 11, 12번을 입력모드 지정
예제 5.4의 스케치2 void loop() { loop( ) 시작 for(i=0; i<4; i++) { val=digitalRead(pin_SW[i]); bitWrite(select, i, val); } switch( )를 위한 case 번호 생성 switch(select) { switch(sw) 시작 case 1: digitalWrite(pin_LED[i], HIGH); break; sw1(D9)가 눌려지면 4개의 LED가 동시에 on case 2: for(j=0; j<4; j++) { delay(200); digitalWrite(pin_LED[i], LOW); sw2(D10)가 눌려지면 4개의 LED가 동시에 4번 on/off
예제 5.4의 스케치1 case 4: for(i=0; i<4; i++) { digitalWrite(pin_LED[i], HIGH); delay(500); } break; sw3(D11)가 눌려지면 4개의 LED가 왼쪽에서 오른쪽으로 순차적으로 on case 8: digitalWrite(pin_LED[3-i], HIGH); sw4(D12)가 눌려지면 4개의 LED가 오른쪽에서 왼쪽으로 default: digitalWrite(pin_LED[i], LOW); 스위치가 눌려지지 않으면 모든 LED off switch(select) 끝 loop( ) 끝
5.4 HBE-MCU-Multi의 스위치 모듈 LED MODULE과 SWITCH MODULE
HBE-MCU-Multi의 스위치 모듈 S0~S7의 버튼 스위치 : 74HC14를 거쳐 BT0~BT7에 연결 Hexa Inverting Schmitt Trigger인 74HC14는 사용하여 입력 신호를 반전시켜 체터링 현상을 제거
스위치 모듈의 버튼 스위치부 회로도
Mega 보드와 모듈의 연결 Mega 보드와 LED모듈의 신호선 포트 연결 Mega 보드의 22, 24, 26, 28, 30, 32, 34, 36을 LED 모듈의 LED 0 ~ 7까지 연결 Mega 보드와 스위치 모듈의 버튼 스위치 부분 연결 Mega 보드의 23, 25, 27, 29, 31, 33, 35, 37을 스위치 모듈의 BT0~BT7까지 연결 주의 아두이노 Mega모듈의 DIGITAL 핀 22번과 23번이 첫 번째부터 시작하지 않고, 2번째 핀부터 시작하므로 핀을 연결할 때, 반드시 22번과 23번 핀의 위치를 확인 스위치 모듈의 버튼 스위치 BT0핀도 컨낵터의 첫 번째부터 시작하지 않고, 2번째 핀부터 시작하므로 주의
Mega보드와 LED 모듈, 스위치 모듈의 연결
예제 5.5 LED-스위치 연동 제어 Switch모듈과 LED 모듈을 사용하여 Switch모듈의 눌러진 버튼과 같은 LED의 불이 점등하자. 주요개념 LED 모듈에 연결되는 아두이노 Mega모듈의 디지털입출력 핀 22, 24, 26, 28, 30, 32, 34, 36과 스위치 모듈의 BT0~7에 연결되는 디지털입출력 핀 23, 25, 27, 29, 31, 33, 35, 37을 배열을 사용하여 지정 각 스위치의 입력을 읽고 LED를 켜기 위하여 for문을 사용
예제 5.5의 스케치 byte LED[8] = {22,24,26,28,30,32,34,36}; byte SWITCH[8]= {23,25,27,29,31,33,35,37}; byte val = 0; LED 제어를 위한 핀들의 배열 지정 스위치 입력을 위한 핀들의 배열 지정 void setup() { byte z; for(z=0;z<8;z++) { pinMode(LED[z],OUTPUT); pinMode(SWITCH[z],INPUT); } LED 제어 핀의 출력 모드 설정 스위치 입력 핀의 입력 모드 설정 void loop() { byte i; for(i=0;i<8;i++) { val = digitalRead(SWITCH[i]); digitalWrite(LED[i], val); 스위치의 상태를 읽음 스위치의 상태를 해당 LED로 출력
연습과제 1 LED의 깜박이는 속도가 4개의 스위치를 사용하여 4단계로 조정되는 스케치를 만들어 보자. 4장의 연습과제에서 다룬 과제들을 각 스위치의 기능으로 제어 할 수 있도록 스케치를 구현하여 보자. 8개의 스위치에 값을 부여하고, 덧셈 스위치를 지정하여, 2개의 스위치의 값을 더한 결과를 LED에 나타내 보자.
연습과제 2 예제 5.2나 5.5에서 스위치의 우선순위를 정하여 두 개 이상의 스위치가 동시에 눌려졌을 때 우선순위가 높은 스위치의 제어가 이루어지도록 스케치를 만들어 보자. (예: 우선순위가 SW0>SW1>SW3>SW4일 때, SW1과 SW3이 동시에 눌려지면 SW1에 의하여 지정된 동작을 하도록 한다.) if-else문과 case문을 사용하여 제어 할 때의 장단점을 비교해 보자.
함수정리 digitalRead(pin-munber); 아두이노 보도의 디지털입력으로 선언된 핀을 통하여 HIGH('1')와 LOW('0') 값을 읽는 명령어 -pin-munber : 디지털입력으로 선언된 핀의 번호 (예) val = digitalRead(10); 핀10을 통해 읽은 값을 변수 val에 저장 if-else (예) digitalWrite(10, HIGH); 핀10에 ‘1’ 출력 digitalWrite(10, ‘1’); 핀10에 ‘1’ 출력
함수정리 switch-case 변수 x의 bitPosition번째의 비트에 value의 값(0 또는 1)을 설정 -pin-munber : 디지털출력으로 선언된 핀의 번호 -state : HIGH 또는 '1', LOW 또는 '0' (예) digitalWrite(10, HIGH); 핀10에 ‘1’ 출력 digitalWrite(10, ‘1’); 핀10에 ‘1’ 출력 bitWrite(x, bitPosition, value); 변수 x의 bitPosition번째의 비트에 value의 값(0 또는 1)을 설정 (예) bitWrite(sw, 3, "HIGH"); 핀10에 ‘1’ 출력 digitalWrite(10, ‘1’); 핀10에 ‘1’ 출력