6-1장. 아두이노의 기본 명령어
※아두이노 프로그래밍 기초 - 기본 구문
본격적인 아두이노 프로그래밍에 들어가기 전에, 기본 구문 몇 가지부터 알아보도록 합시다.
대부분의 유용한 내용은 아두이노 참조(https://www.arduino.cc/reference/ko/) 에서 볼 수 있으니 참고하시길!
목차
- 기본 구조
- 변수
- 주석
- 연산자
- 조건문
- 반복문
- 함수
- 배열
- 아두이노 핀 설정
◎ 기본 구조
아두이노 프로그램의 구조는 간단합니다.
프로그램 실행 >> setup 실행 >> loop 실행 (반복)
이 끝입니다.
당연하게도 저 setup, loop의 중괄호 { } 안에 코드를 넣어야 작동하겠죠.
다만, 아두이노에서는 필수적으로 setup(), loop() 함수를 필요로 합니다.
⊙setup()
setup 함수는 아두이노에 전원을 입력하고 단 한 번만 실행되는 함수로, 한번 실행 이후 더 이상 setup 함수는 실행되지 않습니다.
따라서 아두이노 프로그램을 제작할 시 핀 입력, 출력 설정과 기본 사전 설정을 진행할 때 사용됩니다.
⊙loop()
loop 함수는 문장을 반복하며, 아두이노 내에서 setup 함수 실행 후 loop 함수 내에 있는 코드가 실행됩니다.
따라서 아두이노 프로그램을 제작할 시 센서의 입, 출력값을 받고 통제하거나 연결된 엑추에이터를 제어하는 역할을 합니다.
◎ 변수
변수를 선언한다 : 프로그래밍에서 사용할 수 있는 원하는 변수를 저장할 곳을 만드는 것입니다.
int : 대표적인 숫자형 변수로, 정수형(integer)의 약자입니다. 소수점을 저장할 수 없으며, -2,147,483,648 ~ 2,147,483,647까지의 숫자를 저장할 수 있습니다. 이 범위를 벗어나는 값을 가지면 오버플로 오류가 일어납니다.
float : 실수형 변수로, 부동소수점 저장 변수입니다. 소수점을 저장하며, double와 동일한 크기입니다.
String : 문자, 단어를 저장할 때 사용하는 변수입니다.
char : 반각 문자(1byte로 표현할 수 있는 문자) 하나를 저장할 때 사용하는 변수입니다.
boolean / bool : 참, 거짓을 저장하는 변수입니다.
⊙예시
다음 사진은 각각 해당하는 변수를 만든 사진입니다.
int 자료형의 a변수, char 자료형의 b 변수, boolean 자료형의 c 변수가 있습니다.
특이하게도 문자열 끝에 세미콜론(;) 이 붙어 있는데, 이는 문장의 끝을 의미하는 것으로 컴퓨터는 문장의 시작과 끝을 모르기 때문에 마지막 부분에 세미콜론이 필요합니다.
그리고, 변수 이름 앞에 숫자가 오거나 변수 이름 중 대부분의 특수문자, 명령문이 와서는 안됩니다.
⊙변수 대입
수학에서는 등호가 서로 같다를 의미하지만, 프로그래밍에서의 등호는 대입을 의미하는 연산자입니다.
등호 오른쪽에 있는 것을 등호 왼쪽에 대입하는 것이며,
다음 코드는 a에 100을 대입하겠다는 것입니다.
a는 1줄에서 int 자료형으로 만들어진 변수이므로, 100이 들어갈 수 있습니다.
각 자료형마다 값을 저장하는 방법은 같지만(= 연산자 사용), 중간 처리의 과정은 조금 다릅니다.
char 자료형으로 만들어진 변수인 b는 작은따옴표(')를 통해 문자를 감싸 줘야 하고.
bool 자료형으로 만들어진 변수인 c는 참일 경우 true, 거짓일 경우 false를 입력해야 합니다.
string 자료형의 경우는 큰따옴표(")를 사용해서 감싸야합니다.
그리고 변수를 선언하자마자 값을 넣을 수도 있습니다.
⊙변수 대입 실습
좋아요, 한번 실습을 해 봅시다.
void setup()의 중괄호 안에 다음과 같은 명령어를 입력해 주세요.
Serial.begin(9600);
int a1 = 1;
double a2 = 3.14159;
char a3 = 'A';
String a4 = "Hello World!";
bool a5 = true;
Serial.println(a1);
Serial.println(a2);
Serial.println(a3);
Serial.println(a4);
Serial.println(a5);
자, 어떻게 나올까요?
혹시 모르는 명령어 몇 가지를 설명한다면, Serial.begin()은 () 안의 숫자만큼의 속도로 아두이노 보드와 시리얼 통신을 합니다. (아두이노 보드와 보드레이트(데이터 전송 속도)가 같아야 합니다)
그리고 Serial.println()는 () 안의 변수를 출력합니다.( 여기서 print뒤에 붙은 ln은 출력 후 한 줄 띄웁니다. (\n과 같음))
자, 그러면 이제 진짜로 어떻게 나올까요?
짜잔!
몇 가지는 맞추셨겠지만, 몇 가지는 틀리셨을 겁니다.
당연하죠, 아두이노에서는 기본적으로 실수형 변수의 소수점을 2자리까지만 출력합니다.
혹시나 소수점 출력을 조정하고 싶으시다면 Serial.println(a1, 3);처럼 입력하시면 소수점을 3자리까지 출력해 줍니다.
다만, float 변수 자체의 고질적인 문제 때문에 6자리 이후에는 정확도가 떨어질 겁니다.
이 문제는 부동소수점 방식의 자체적인 문제인데, 여긴 아두이노 강좌이지 자료구조 강좌가 아니기 때문에 여기까지만 배우도록 하겠습니다.
bool명령어는 딱히 틀린 게 아니에요. true는 0을 제외한 수(대표적으로 1), flase를 0으로 출력합니다.
◎ 주석
주석은 프로그래밍을 할 때 적는 메모와도 같은 것으로서, 실제 프로그램에서는 동작하지 않지만 사람의 편의성을 위해 사용되는 것입니다.
// 을 통해 1줄을 주석 처리할 수 있고, /* */ 을 통해 * 사이의 모든 내용을 주석 처리할 수 있습니다.
주석의 예시입니다.
◎ 연산자
연산자는 말 그대로 변수, 혹은 상수들의 연산을 할 때 사용합니다.
⊙산술 연산자
+ | 덧셈 연산자 | 덧셈 연산을 수행합니다 |
- | 뺄셈 연산자 | 뺄셈 연산을 수행합니다 |
* | 곱셈 연산자 | 곱셈 연산을 수행합니다 |
/ | 몫 연산자 | 연산식의 몫을 추출합니다 |
% | 나머지 연산자 | 연산식의 나머지를 추출합니다 |
⊙비교 연산자
a < b | a보다 b가 클 때 true를 출력하고, a보다 b가 작거나 같을 때 flase를 출력합니다. |
a <= b | a보다 b가 크거나 같을 때 true를 출력하고, a보다 b가 작을 때 flase를 출력합니다. |
a > b | a보다 b가 작을 때 true를 출력하고, a보다 b가 크거나 같을 때 flase를 출력합니다. |
a >= b | a보다 b가 작거나 같을 때 true를 출력하고, a보다 b가 클 때 flase를 출력합니다. |
a == b | a와 b가 같을 때 true를 출력하고, a와 b가 다를 때 flase를 출력합니다. |
a != b | a와 b가 다를 때 true를 출력하고, a와 b가 같을 때 flase를 출력합니다. |
⊙비교 연산자 실습
void setup()
{
Serial.begin(9600);
int a = 0;
String text;
if (a>0)
{
text = "plus";
}
else if (a<0)
{
text = "minus";
}
else
{
text = "0";
}
Serial.println(text);
}
void loop()
{
}
다음과 같이 아두이노 보드에 입력하고, int a = 에 -3, 8, 0을 각각 넣어보고 출력이 어떻게 나오는지 확인하세요.
시리얼 모니터에는 다음과 같이 출력됩니다.
⊙논리 연산자
f(a) | | f(b) | or | f(a), f(b) 중 하나가 참(true)이라면 참(true)를 출력합니다. | f(a), f(b) 중 모두가 거짓(flase)이라면 거짓(false)을 출력합니다. |
f(a) && f(b) | and | f(a), f(b) 중 모두가 참(true)이라면 참(true)를 출력합니다. | f(a), f(b) 중 하나가 거짓(flase)이라면 거짓(false)을 출력합니다. |
◎ 조건문
if (조건식)
{
시행 1
}
시행 2
조건 식 안의 식이 참이면 시행 1을, 아닐 경우 시행 2를 시행하는 조건문입니다.
다음과 같은 구조를 가지고 있습니다.
if(필수)
else if (elif와 동의).... ( 조건을 추가적으로 분류하기 위해 추가합니다.
else(else if에서 처리되지 않으면 여기서 처리됩니다)
◎ 반복문
⊙while
while(조건식)
{시행}
조건식이 참일 동안 시행됩니다.
예시)
a = 10
while(a<10)
{
a+1
}
⊙for
while(변수; 조건식; 변화량)
{시행}
변수 설정 후 조건식 비교, 시행 후 변화량만큼 변수를 변화시키고 다시 조건식을 비교 후 시행을 반복합니다.
⊙for 구문 실습
void setup()
{
Serial.begin(9600);
for (int x = 1; x < 10; x = x+1)
{
Serial.print(x);
}
}
void loop()
{
}
다음과 같이 아두이노 보드에 입력하고, 시리얼 모니터에서 어떻게 출력되는지 확인하세요.
출력 : 123456789
◎ 함수
함수란 프로그래밍에서 사용하는 일종의 도구입니다.
내가 만들어 놓는 도구죠.
예를 들어 1부터 100까지 저장하고 싶다고 생각합시다, 이때 1부터 100까지 일일이 적는 것은 너무 불편하니 변수 x에 1을 저장하고, 변수 x에 계속 1씩 더해서 출력하면 어떨까요?
이럴 때 사용되는 것이 함수입니다. 일일이 필요한 코드를 작성할 필요 없이 함수를 사용하는 것입니다.
그리고 이런 함수는 한번 만들어두면 계속 사용할 수 있으니 편리합니다.
- 함수의 구조
함수는 입력, 처리, 출력의 세 부분으로 나누어집니다.
일단 예시 함수를 하나 만들어 봅시다.
사실 만들 필요도 없습니다. 아두이노 IDE를 켜자마자 나오는 저것들이 함수입니다.
하늘색으로 표시된 void라는 부분은 리턴 타입인데, 이는 함수의 출력값을 어떤 데이터 타입으로 보낼 것인지 선언하는 부분입니다.
붉은색으로 칠해진 부분이 함수의 이름을 의미합니다.
소괄호() 쳐진 부분 안은 매개변수를 의미하는데, 함수에 들어갈 입력을 명시하는 부분입니다.
그리고 중괄호로 처리된 부분에 동작과 관련된 코드가 삽입되며, return 명령어를 통해서 출력값을 내보낼 수 있습니다.
return 명령어는 함수를 종료하는 명령어로 사용되며, return 명령어를 사용하면 함수가 호출된 곳으로 결괏값을 보내지 않습니다.
필요 없을 경우는 사용하지 않아도 됩니다.
그럼 진짜로 함수를 하나 만들어 봅시다.
void test(){digitalWrite(LED_BUILTIN, HIGH);delay(1000);digitalWrite(LED_BUILTIN, LOW);delay(1000);}
간단한 함수를 하나 만들어 왔습니다.
무슨 뜻인지 모르겠는 당신! 가서 실습편 1장을 읽고 오세요!
아무튼, 이 함수를 loop 윗부분에 대신 넣어 봅시다.
그러면, 잘 작동하는 것을 확인할 수 있습니다.
잠깐, 함수 안에 반복문들을 넣으면 어떻게 되죠?
좋은 질문이에요, 한번 만들어보도록 합시다.
void setup()
{
Serial.begin(9600);
hello(); //hello 함수를 실행합니다.
}
void loop()
{
}
void hello()
{
for(int i = 0; i <5; i++)
{
Serial.println("start");
}
}
좋아요. 이제 실행해 볼까요?
그러면 이제 시리얼 모니터에
start
start
start
start
start
가 나와 있을 것입니다.
⊙매개변수를 포함한 함수
이렇게 실행되는 함수도 있는 반면에, 값을 받아서 작동되는 함수도 존재합니다.
이때 받는 값을 매개변수, 출력하는 값을 반환값(return값)이라고 합니다.
한번 만들어봅시다!
void setup()
{
Serial.begin(9600);
int a;
a = add(1,2); // 여기서 add 함수가 실행됩니다.
Serial.println(a); //a값 ( add 함수에서 받은 return값 )을 출력합니다.
}
void loop()
{
}
int add(int x, int y)
{
int z;
return z = x + y; // add 함수에서 받은 매개변수 ( 여기서는 1=x , 2=y )를 받아 z값을 출력합니다.
}
다음과 같이 입력해 주세요.
그리고 이제 a = add(1,2) 안에 들어가 있는 순서쌍을 각각
1,2
4,9
14,125로 입력하고 , 시리얼 모니터의 출력값을 확인해 봅시다.
그렇다면 출력값으로 각각
3
13
139가 나올 것입니다.
이렇게 함수는 여러 가지에 활용할 수 있는 중요한 부분이므로, 만약 사용이 어렵다고 느끼신다면 여러 방법을 검색해 보는 것을 추천합니다.
처음 함수를 배우면 이해하기 어려울 수 있지만, 간단한 부분부터 차례로 익혀나간다면 어렵지 않게 학습할 수 있을 것입니다.
◎ 배열
프로그래밍을 하다 보면, 변수로는 뭔가 데이터 저장량이 모자라는 것을 알 수 있을 것입니다.
물론 변수를 늘리는 것도 방법이지만, 변수가 너무 많아지면 저장공간에도, 내 계획표에도, 아무튼 여러모로 문제가 생기죠.
그럴 때는 배열을 만들어서 여러 개의 데이터를 저장하고 사용하면 편리합니다.
한번 배열을 만들어봅시다.
다음과 같이 코드를 입력해 주세요.
void setup()
{
Serial.begin(9600);
int a[3] = {1,2,3};
Serial.print(a[0]);
Serial.print(a[1]);
Serial.print(a[2]);
}
void loop()
{
}
배열은 데이터 유형 + 배열 이름[배열 개수] 형태로 만들어집니다.
이 코드에서는 배열 a에서 3개의 값에 각각 1, 2, 3을 저장했으며, 이 값은 a[0], a[1], a[2]로 접근할 수 있습니다.
이때 대괄호[ ] 안의 숫자를 인덱스(index)라고 부르며, 인덱스는 0부터 시작합니다.
a[0] | a[1] | a[2] |
1 | 2 | 3 |
저렇게 값이 저장되어 있다고 생각하세요.
◎ 아두이노 기본 핀 설정
아두이노 보드에는 여러 개의 핀이 있고, 이 핀들에게는 각각 설정이 있습니다.
아두이노 보드에 입력하는 명령어로 이 핀들의 성질을 바꾸고, 여러 역할을 할 수 있습니다.
⊙pinMode(pin, mode);
특정 핀을 출력 또는 입력 모드로 설정하는 명령어입니다.
pin - 설정하고자 하는 핀 번호 (혹은 변숫값)
mode - INPUT, OUTPUT
⊙digitalwrite(pin);
디지털 핀의 상태값을 읽는 명령어입니다.
LOW, HIGH 중 하나의 값을 받습니다.
⊙digitalwrite(pin, value);
디지털 핀의 전압을 0V 또는 5V로 설정하는 명령어입니다.
pin - 설정하고자 하는 핀 번호(혹은 변숫값)
value - LOW, HIGH
⊙analogRead(pin);
아날로그 핀의 상탯값을 읽는 명령어입니다.
0~1023 사이의 값을 읽습니다.
⊙analogWrite(pin, value);
아날로그 핀의 값을 수정하는 명령어입니다.
0~1023 사이의 값을 출력합니다.
⊙delay(time);
프로그램을 time만큼 정지시킨 후 실행합니다.
time - 설정하고자 하는 시간(밀리초 단위)
※밀리초 : 1/1000초, 즉 1000밀리초 = 1초이다. (1000ms = 1s)
⊙millis();
프로그램 실행 이후 경과된 시간을 반환합니다.
※ms단위로 반환하며, print(millis()); 로 반환받습니다.
다음에는 더 어려운 프로그래밍에 대해서 배우도록 합시다!