드디어 여러분의 손으로 첫 이동 로봇을 성공적으로 조립하셨습니다! 이제 이 로봇을 단순히 움직이게 하는 것을 넘어, 여러분이 원하는 대로 '생각하고 행동'하게 만드는 방법을 배울 시간입니다. 이 모든 것은 프로그래밍을 통해 이루어집니다. 이 글에서는 로봇 제어에 필수적인 아두이노 프로그래밍의 기본 개념들을 쉽고 명확하게 설명합니다. 변수, 조건문, 반복문, 함수 등 기본적인 문법 요소들이 로봇의 움직임과 센서 데이터 처리에 어떻게 활용되는지 구체적인 예시와 함께 알아보고, 여러분의 로봇을 더욱 똑똑하게 만드는 데 필요한 첫 걸음을 내딛게 될 것입니다.
프로그래밍이란 무엇인가? 로봇과의 대화
프로그래밍은 컴퓨터나 마이크로컨트롤러에게 특정 작업을 수행하도록 명령을 내리는 과정입니다. 이 명령들은 프로그래밍 언어라는 약속된 규칙에 따라 작성되며, 로봇은 이 명령을 순서대로 실행하여 원하는 작업을 수행합니다. 아두이노는 C/C++ 기반의 간소화된 언어를 사용하며, 직관적인 구조 덕분에 로봇 프로그래밍 입문자에게 매우 적합합니다.
아두이노 스케치(Sketch)의 기본 구조 다시 보기
지난 글에서 잠시 보았던 아두이노 스케치(아두이노 프로그램 파일을 스케치라고 부릅니다)의 기본 구조를 다시 살펴보겠습니다.
void setup() {
// 1. 초기 설정 코드: 로봇이 시작될 때 단 한 번만 실행됩니다.
// 핀 모드 설정 (입력/출력), 시리얼 통신 시작, 변수 초기화 등
}
void loop() {
// 2. 반복 실행 코드: setup() 함수 실행 후 무한히 반복 실행됩니다.
// 센서 값 읽기, 모터 제어, 조건에 따른 동작 변경 등 로봇의 주된 동작
}
setup()
: 로봇이 깨어나서 주변을 둘러보고 준비하는 과정과 같습니다. 어떤 핀을 출력으로 쓸지, 어떤 통신을 시작할지 등 초기 설정을 여기서 합니다.loop()
: 로봇이 눈을 뜨고 나서 해야 할 일을 계속해서 반복하는 것입니다. 센서를 보고, 판단하고, 움직이고, 다시 센서를 보는 과정이 끊임없이 반복됩니다.
로봇 프로그래밍의 핵심 개념들
이제 로봇을 제어하는 데 필수적인 프로그래밍 개념들을 하나씩 알아보겠습니다.
1. 변수 (Variables): 정보 저장 공간
변수는 데이터를 저장하는 이름이 붙은 저장 공간입니다. 센서 값, 모터 속도, 카운터 등 로봇이 작동하면서 얻거나 사용하는 다양한 정보들을 변수에 저장하여 활용합니다.
- 선언: 변수를 사용하기 전에 어떤 종류의 데이터를 저장할지(자료형)와 변수 이름을 지정해야 합니다.
int
: 정수 (예: 10, -5, 0)float
: 소수 (예: 3.14, 0.5)char
: 문자 (예: 'A', 'b')boolean
: 참(true) 또는 거짓(false) (예:true
,false
)
- 초기화: 변수를 선언함과 동시에 초기 값을 지정할 수 있습니다.
- 예시:
C++
int motorSpeed = 150; // 정수형 변수 motorSpeed를 선언하고 150으로 초기화 float distance = 0.0; // 소수형 변수 distance를 선언하고 0.0으로 초기화 boolean obstacleDetected = false; // 참/거짓 변수 obstacleDetected 선언 const int LED_PIN = 13; // 변경되지 않는 값은 'const'로 상수 선언 (대문자 관례)
- 로봇 활용: 센서에서 읽은 거리 값을
distance
변수에 저장하고,motorSpeed
변수 값을 조절하여 로봇의 속도를 변경할 수 있습니다.
2. 연산자 (Operators): 값 계산 및 비교
연산자는 변수나 상수에 대해 수학적 계산(+
, -
, *
, /
), 비교(==
, !=
, <
, >
), 논리(&&
, ||
, !
) 등의 작업을 수행합니다.
- 산술 연산자:
+
(더하기),-
(빼기),*
(곱하기),/
(나누기),%
(나머지) - 비교 연산자:
==
(같다),!=
(다르다),>
(크다),<
(작다),>=
(크거나 같다),<=
(작거나 같다) - 논리 연산자:
&&
(AND, 그리고),||
(OR, 또는),!
(NOT, ~이 아니다) - 예시:
C++
int a = 10; int b = 3; int sum = a + b; // sum은 13 boolean isGreater = (a > b); // isGreater는 true boolean complexCondition = (sum > 10 && isGreater); // complexCondition은 true
- 로봇 활용: 센서로 측정한 거리가 특정 값보다 작은지 비교하여 장애물을 감지하거나, 두 조건이 모두 만족할 때만 로봇이 움직이도록 할 수 있습니다.
3. 조건문 (Conditional Statements): 판단과 분기
조건문은 특정 조건이 참(true)일 때만 특정 코드 블록을 실행하도록 합니다. 로봇이 주변 환경에 따라 다른 행동을 취하도록 할 때 사용됩니다.
if
문: 가장 기본적인 조건문.C++if (조건) { // 조건이 참일 때 실행되는 코드 }
if-else
문: 조건이 참일 때와 거짓일 때 각각 다른 코드를 실행합니다.C++if (조건) { // 조건이 참일 때 실행 } else { // 조건이 거짓일 때 실행 }
if-else if-else
문: 여러 조건을 순차적으로 검사할 때 사용합니다.C++if (조건1) { // 조건1이 참일 때 } else if (조건2) { // 조건1이 거짓이고 조건2가 참일 때 } else { // 모든 조건이 거짓일 때 }
- 로봇 활용:
C++
// 초음파 센서로 거리를 측정하는 가상의 코드 (실제는 센서 라이브러리 사용) float currentDistance = readUltrasonicSensor(); if (currentDistance < 20) { // 거리가 20cm 미만이면 // 로봇 정지 또는 후진 stopMotors(); Serial.println("Obstacle detected! Stopping."); } else if (currentDistance >= 20 && currentDistance < 50) { // 20cm 이상 50cm 미만이면 // 로봇 속도 줄이기 setMotorSpeed(100); // 느린 속도 Serial.println("Obstacle nearby, slowing down."); } else { // 로봇 전진 setMotorSpeed(200); // 일반 속도 Serial.println("Clear path, moving forward."); }
4. 반복문 (Loops): 특정 작업 반복 수행
반복문은 특정 코드 블록을 여러 번 반복하여 실행할 때 사용됩니다.
for
문: 정해진 횟수만큼 반복할 때 주로 사용됩니다.C++for (초기화; 조건; 증감) { // 조건이 참인 동안 반복 실행되는 코드 }
while
문: 조건이 참인 동안 반복 실행됩니다. 조건이 거짓이 되면 반복이 종료됩니다.C++while (조건) { // 조건이 참인 동안 반복 실행되는 코드 }
- 로봇 활용:
for
문: 로봇 팔이 10번 움직이도록 하거나, LED를 5번 깜빡이도록 할 때.while
문: 특정 센서 값이 만족될 때까지 로봇이 대기하거나, 장애물을 피할 때까지 후진하는 등의 동작.
C++// LED 3번 깜빡이기 for (int i = 0; i < 3; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); delay(200); }
C++// 장애물이 감지되지 않을 때까지 후진 float distance = readUltrasonicSensor(); while (distance < 10) { // 거리가 10cm 미만이면 계속 후진 moveBackward(); distance = readUltrasonicSensor(); // 다시 거리 측정 delay(50); } stopMotors(); // 장애물이 없어지면 정지
5. 함수 (Functions): 코드 재활용 및 모듈화
함수는 특정 작업을 수행하는 코드 블록에 이름을 붙여 필요할 때마다 호출하여 사용할 수 있도록 만든 것입니다. 코드를 모듈화하고 재활용하여 가독성을 높이고 오류를 줄이는 데 매우 중요합니다.
- 정의:
C++
// 반환값 자료형 함수이름(매개변수1 자료형, 매개변수2 자료형, ...) { // // 함수가 수행할 코드 // return 반환값; // 반환값이 없는 경우 void // }
- 예시:
C++
// 로봇을 전진시키는 함수 void moveForward(int speed) { digitalWrite(motor1_in1, HIGH); digitalWrite(motor1_in2, LOW); analogWrite(motor1_ena, speed); digitalWrite(motor2_in3, HIGH); digitalWrite(motor2_in4, LOW); analogWrite(motor2_enb, speed); } // 로봇을 정지시키는 함수 void stopMotors() { analogWrite(motor1_ena, 0); analogWrite(motor2_enb, 0); } void loop() { moveForward(200); // 로봇을 속도 200으로 전진 delay(3000); stopMotors(); // 로봇 정지 delay(2000); // ... 다른 동작 }
- 로봇 활용:
moveForward()
,turnLeft()
,readDistanceSensor()
등 반복적으로 사용되는 동작들을 함수로 만들어 코드를 간결하게 만듭니다.
디버깅: 로봇의 문제점을 찾아 해결하기
프로그래밍 과정에서 오류는 필연적으로 발생합니다. 이를 찾아 해결하는 과정을 디버깅(Debugging)이라고 합니다.
- 시리얼 모니터 활용:
Serial.begin(9600);
으로 시리얼 통신을 시작하고,Serial.println("메시지");
나Serial.print(변수이름);
을 사용하여 프로그램의 특정 지점에서 변수 값이나 메시지를 출력하여 흐름을 추적합니다. - LED 깜빡임: 특정 코드 블록이 실행될 때 LED를 깜빡이도록 하여 프로그램의 진행 상황을 시각적으로 확인합니다.
- 주석 활용: 코드에 대한 설명을 주석(
//
또는/* */
)으로 달아두면 나중에 코드를 이해하고 수정하는 데 큰 도움이 됩니다. - 단계별 테스트: 전체 코드를 한 번에 작성하기보다, 작은 부분부터 작성하고 테스트하면서 점진적으로 완성해 나갑니다.
마무리하며...
이번 글에서는 아두이노를 이용한 로봇 프로그래밍의 핵심 개념들을 알아보았습니다. 변수, 연산자, 조건문, 반복문, 그리고 함수는 여러분의 로봇에 '지시를 내리고', '판단하게 하며', '반복적인 작업을 수행'하도록 만드는 기본적인 도구들입니다. 이 개념들을 익히고 실제 코드로 적용하는 연습을 반복하면, 여러분의 로봇은 단순한 장난감을 넘어 여러분의 명령에 따라 움직이는 똑똑한 파트너가 될 것입니다.
다음 편에서는 더 강력한 성능으로 복잡한 지능을 부여할 수 있는 라즈베리 파이를 이용한 로봇 프로그래밍, 특히 파이썬 기초에 대해 알아보겠습니다. 로봇 공학의 다음 단계로 나아갈 준비를 해주세요! 이제 여러분이 조립한 로봇에 이 프로그래밍 개념들을 적용하여 간단한 동작(예: 일정 시간 전진 후 정지)을 코드로 구현해 보고 시리얼 모니터로 결과를 확인해 보세요!
0 댓글