3.2. 블럭 소개
블록 소개에 들어가기 전에 꼭 읽어주세요!
블록을 제대로 사용하기 위해 꼭 알아야 할 정보들이 중간중간 포함되어 있어요.
예를 들어, 함수 사용법이나 반복적으로 사용되는 중요한 내용들이 앞부분부터 순서대로 설명됩니다.
처음부터 끝까지 차근차근 읽어보시면 이해하는 데 큰 도움이 될 거예요.
1. 기본 블럭
프로보 GULC에서 새 프로젝트를 만들면 자동으로 들어가 있는 블럭들이 있어요.
이 블럭들을 “기본 블럭”이라고 해요.
이 기본 블럭은 삭제하거나 수정할 수 없어요.
왜냐하면, 프로그램이 제대로 작동하려면 꼭 필요한 블럭이기 때문이에요.
블럭에서는 안 보이지만, 실제 프로그램에서는 아래 코드들도 자동으로 들어가 있어요.
#include "api.h"
→ 블럭들이 작동할 수 있게 기능을 가져오는 코드예요.

int main(void)
→ 프로그램이 어디서부터 시작해야 하는지 알려주는 코드예요.

start();
→ 우리가 블럭에서 보는 첫 줄이에요.

end();
→ 프로그램을 안전하게 종료하는 코드예요.

return 0;
→ 컴퓨터에게 “문제 없이 잘 끝났어요!” 라고 알려주는 코드예요.
start 블록만 보이니까, “다른 기본 블록은 어디에 있지?” 하고 궁금할 수 있어요.
이럴 땐 아래쪽에 있는 버튼을 눌러보세요!
그러면 C언어 화면이 열리고, 나머지 기본 블록들이 글자로 된 코드로 들어 있는 걸 볼 수 있어요.
이 블록들은 눈에는 안 보이지만, 프로그램이 제대로 작동하려면 꼭 필요한 블록들이에요.
코드를 들어가기 전에!
주석에 대해서 먼저 알아봐요!
코드를 작성하다 보면, "이 코드가 무슨 뜻이지?" "나중에 보면 내가 쓴 건데도 헷갈릴 것 같아..."
이런 생각이 들 수 있어요.
그럴 때 사용하는 게 바로 “주석(comment)”이에요!
주석이란?
- 주석은 컴퓨터가 읽지 않는 설명 전용 글이에요.
- 주석 안에 적힌 내용은 코드 실행에는 영향을 주지 않아요.
주석은 언제 쓰나요?
- 이 코드가 무엇을 하는지 설명할 때
- 나중에 다시 봐도 이해하기 쉽게 메모를 남길 때
- 친구나 선생님이 코드를 쉽게 이해할 수 있도록 도와줄 때
GULC에서 주석 쓰는 방법
GULC에서는 주석 블록을 원하는 줄 위나 옆에 끌어다 놓고, 그 안에 내용을 작성하면 돼요!
2. 전역 블럭
전역 블럭이 뭐예요?
전역 블럭은 여기저기서 자주 써야 할 코드를 미리 간단하게 정리해 두는 블럭이에요.
왜 쓰나요?
같은 내용을 여러 번 쓰면 귀찮고 헷갈리니까,
→ 이름을 한 번만 정해서 간단하게 쓰려고 해요!
예를 들어,
긴 코드가 반복될 때 별명처럼 짧게 부르면 훨씬 편하죠.
#define은
프로그램 시작 전에 미리 값을 정해두는 거예요.
한 번 정해지면, 실행 중에는 절대 값이 바뀌지 않아요!
variable(변수)은
프로그램이 실행되는 동안 우리가 짠 코드에 따라 값이 바뀔 수 있어요.
상황에 따라 계속 달라진다고 생각하면 돼요!
참고로!
프로그램 시작 전에는
#define이든 variable(변수)든 값을 바꾸는 설정은 가능해요.
하지만 실행이 시작되면,
#define은 고정, variable(변수)은 변경 가능이에요!
- #define
상수(항상 값은 값)를 정하기 위해서 사용합니다.
인자값 ① : 상수를 부를 이름(명칭)
인자값 ② : 이름을 부르면 나올 값

예를 들면
#define 학교이름 "창의와교육초등학교"
→ 학교이름이라고 쓰면 "창의와교육초등학교"로 바뀝니다.
- Variable
변수를 정하기 위해서 사용합니다.
인자값 ① : 사용할 변수의 타입(자료형)
인자값 ② : 사용할
변수의 이름
인자값 ③ : 처음에 넣을 값(초기값)
1) char(숫자 1 또는 0 저장)
GULC에서는 char에 값을 'A', 'B' 같은 문자 자체는 사용할 수 없고 대신 1(참), 0(거짓) 처럼 숫자만 저장해요.
변수 이름은 반드시 영문자, 숫자, 밑줄(_)만 사용할 수 있어요.
한글이나 특수기호, 띄어쓰기는 사용할 수 없습니다.

또한, motor, motor2 같은 단어는 GULC 내부에서 이미 정해져 있는 이름이에요.
이런 이름을 변수로 사용하면 밑줄이 생기거나 에러가 발생할 수 있어요.

→ 그래서 변수 이름은 다른 이름으로 새롭게 만들어야 해요.

2) int(정수 저장)
→‘studentCount라는 변수에 5라는 숫자를 저장해요.
3) unsigned char(0~255까지 숫자 저장)

→‘밝기’라는 변수에 200이라는 숫자를 저장해요. (음수(-) X)
4) unsigned int (양의 정수 저장)

→‘점수’에 950을 저장해요. (음수(-) X)
5) signed char (-128~127 숫자 저장)

‘온도’에 -20을 저장해요. 추울 때도 쓸 수 있어요!
6) signed int (-32,768 ~ 32,767)

‘통장잔액’에 -5000을 저장해요. 돈이 마이너스일 수도 있죠!
3. 지역 블럭
지역 블럭은 main 블럭안에서만 사용되는 블럭입니다.
- while
여기서 1은 참(True)을 뜻해요.
그래서 조건이 항상 맞기 때문에, 무한 반복이 되는 거죠.
왜 이렇게 쓸까요?
GULC에서는 대부분 센서 입력을 계속 읽고, 상태를 판단하면서 동작을 유지하는 구조라서 무조건 반복되는 메인 루프가 필요합니다.
GULC의 while 블록은 보통 while (1) 처럼 무한 루프 형태로 사용돼요.
→ 프로그램이 계속 실행되도록 만들기 위해서예요.
- if / else if / else
우리가 만든 프로그램이 “상황에 따라 다르게 행동하게” 하려면 조건을 검사하고, 그에 맞는 행동을 시키는 구조가 필요해요.
그럴 때 사용하는 게 바로 조건문이에요.
if는 가장 먼저 조건을 확인해서, 그게 맞으면 그 안의 명령을 실행해요.
프로그램이 "지금 버튼값이 1인가요?" 하고 물어보고, 맞으면 그 안에 있는 명령을 실행해요.
else if 는 if의 조건이 맞지 않았을 때, 다른 조건을 확인해볼 수 있게 해주는 구조예요.
프로그램이 "그럼 2는 어때?" 하고 물어보는 거예요.
else는 위의 조건들이 모두 아니었을 때, 마지막으로 실행할 내용을 적는 부분이에요.
"그럼 남은 건 이거밖에 없네~!" 하고 실행되는 구조예요.

간단하게 말하자면!
· if → "맞으면 이거 해!"
· else if → "그게 아니면 이거는 어때?"
· else → "둘 다 아니면 이거 해!"
그리고 꼭 기억하세요!
· if는 맨 처음에 딱 한 번만 사용돼요.
· else도 마지막에 딱 한 번만 쓸 수 있어요.
· 그 사이에 들어가는 else if는 원하는 만큼 여러 번 사용할 수 있습니다!
- 리모컨 입력 포트, 어떻게 작동할까요?
먼저 리모컨 버튼을 누르면, 그 버튼에 해당하는 값이 들어옵니다.
* R_L1 = 리모컨(Remote)의 L1 버튼 입력
그래서 GULC에서 버튼을 누르면 R_L1 같은 이름으로 신호가 들어와요.
아래와 같이
R_L1 버튼이 눌렸을 때만 안에 있는 블록이 실행되게 만들어볼까요?
그런데! 두 개를 동시에 누르거나 따로 눌려야할때가 있을떄는 어떻게할까요?
예를 들어, 리모컨의 R_L1 버튼과 R_R1 버튼을 동시에 눌러야 로봇이 전진하게 만들고 싶다고 해볼게요.
대부분 처음에는 이렇게 해보셨을 거예요.
R_L1R_R1처럼 버튼 이름을 붙여서 쓰거나,
R_L1 R_R1처럼 띄어쓰기를 넣어서 쓰는 경우가 많아요.
하지만 이렇게 하면 바로 에러가 발생하죠.
그럴 땐 어떻게 해야 할까요?
바로 "그리고"라는 뜻의 && 연산자를 사용하면 됩니다!
&&를 사용하면 에러가 없어지고, 우리가 원하는 조건도 정확하게 만들 수 있어요.
이 조건은 두 버튼을 동시에 눌렀을 때만 안에 있는 명령이 실행돼요.
하나만 누르면 실행되지 않아요!
그렇다면 이번엔 반대 상황도 필요하겠죠?
두 버튼 중 하나만 눌려도 작동해야 하는 경우 말이에요.
R_1번 또는 R_2번 버튼 둘 중 하나만 눌러도 동작하도록 하고 싶다면, 이번에는 || 연산자를 사용하면 됩니다.
||는 "또는" 이라는 뜻이에요.
이 조건은 두 버튼 중 하나만 눌러도 안에 있는 명령이 실행돼요.
*참고로 " | "기호는 키보드에서 플러스(+)와 뒤로가기 화살표(백스페이스) 사이에 있는 키를 Shift를 누른 상태에서 입력하면 나옵니다!
여기까지 내용이 어렵지 않았다면, 이제 조금 더 응용해서 쓸 수 있는 심화 과정으로 넘어가볼까요?
예를 들어, 전진 버튼에 대해 생각해보세요.
상황에 따라 이렇게 다르게 만들고 싶을 수 있어요.
· 평소에는 R_L1과 R_R1 버튼을 같이 눌러야 전진하도록 만들고,
· 그런데 급할 땐 R_1 버튼 하나만 눌러도 전진할 수 있게 하고 싶다?
그럴 땐 바로 이런 식으로 조건을 활용할 수 있어요.
(R_L1 && R_R1) || R_1
이 조건의 뜻은 다음과 같아요.
"R_L1과 R_R1을 동시에 누르거나, 또는 R_1번 버튼을 누르면 전진하겠다."
이처럼 조건을 잘 활용하면, 로봇의 동작을 더 편리하고 똑똑하게 제어할 수 있어요.!
이제 입력포트로 넘어가볼게요.
*입력포트 설명을 시작하기 전에!*
처음에는 "어디에 꽂아야 하지?", "이건 무슨 뜻이지?" 하고 저도 조금 당황했지만, 여러분은 걱정 마세요!
아래 설명만 차근차근 읽으면 누구나 쉽게 이해할 수 있어요.
상황에 따라 알맞게 프로그래밍해서 재미있는 아이디어를 꼭! 만들어보세요.
1. Digital (디지털 입력)
포트: A1, A2, A3, A4
꽂는 위치 : CPU 블럭의 A1~A4
설명: 버튼이나 스위치처럼, 눌렸는지(1) 안 눌렸는지(0)만 판단할 수 있어요.
예시:
버튼을 누르면 LED가 켜지고, 떼면 꺼져요.
2. Analog (아날로그 입력)
포트: AA1, AA2, AA3, AA4
꽂는 위치 : CPU 블럭의 A1~A4
설명: 0~1023 사이의 값처럼 점점 변하는 센서 입력을 받을 수 있습니다.
예시:
① 조도 센서 → 주변 밝기에 따라 값 변화
② 거리 센서 → 물체와의 거리 따라 값 변화
3. Falling Edge Input (떨어질 때 감지)
쉽게 말해 버튼을 눌렀다가 손을 뗄 때 한 번만 반응해요.
포트: FEA1 ~ FEA4
꽂는 위치 : CPU 블럭의 A1~A4
설명: 버튼을 누르고 있다가 떼는 순간 1→0 신호가 발생하며 감지됩니다.
예시:
스위치를 눌렀다가 손을 뗄 때 불이 꺼져요.
누르고 있을 땐 아무 일도 없고, 뗄 때 한 번만 반응해요.
4. Rising Edge Input (올라갈 때 감지)
쉽게 말해 버튼을 누르는 순간 한 번만 반응해요.
포트: REA1 ~ REA4
꽂는 위치 : CPU 블럭의 A1~A4
설명: 버튼을 딱 누르는 순간(0→1)만 감지합니다.
예시:
① TV 전원 켜기
- 리모컨 전원 버튼을 딱 한 번 누르면 TV가 켜져요.
- 계속 누르고 있어도 전원은 한 번만 켜져요.
5. Both Edge Input (양쪽 모두 감지)
포트: BEA1 ~ BEA4
꽂는 위치 : CPU 블럭의 A1~A4
설명: 버튼을 누를 때도, 뗄 때도 감지됩니다.
예시:
버튼을 누르면 LED가 파랑,
뗄 때는 LED가 빨강으로 바뀌는 기능 구성 가능
6. Extension Digital (확장 디지털 입력)
EA1 ~ EA4, EA5 ~ EA8
CPU에 연결된 게 아니라, 확장 포트에서 들어오는 디지털 신호를 받을 때 사용해요.
7. Extension Analog (확장 아날로그 입력)
EAA1, EAA2
외부 센서에서 들어오는 아날로그 신호를 받을 때 사용
8. Extension Touch (확장 터치 입력)
ET1 ~ ET8
터치센서를 사용할 때, 이 포트를 통해 입력을 받습니다.
- for
for 블럭이란?
원하는 횟수만큼 어떤 동작을 반복하고 싶을 때 사용하는 블럭이에요.
예를 들어,
· “LED를 5번 깜빡이게 해줘!”
· “소리를 3번 울려줘!”
이렇게 딱 정해진 횟수만큼 반복하고 싶을 때 사용하는 거예요.
for문의 기본 구조는?
보통 이렇게 많이 써요.
for (int i = 0; i < 5; i++)
처음에 0부터 시작해서 i < 5 조건을 만족할 동안 반복하고,
반복할 때마다 i = i + 1로 하나씩 증가하는 방식은 대부분의 C언어에서 사용하는 기본 구조예요.
그럼 몇 번 반복될까요?
바로 5번 반복됩니다!
i 값은
0 → 1 → 2 → 3 → 4
총 5번이죠!
→ 그래서 몇 번 반복할지 정확하게 지정할 수 있어요.
→ 버튼을 누르지 않아도, 정해진 횟수만큼 스스로 반복해요.
하지만 GULC에서는 이 방식 그대로 사용하면 에러가 발생합니다.

왜 에러가 날까요??
GULC에서는 for문 안에서 새로운 변수를 선언하거나 초기화(int i = 0 등)할 수 없습니다.
이는 내부적으로 상수를 블럭 안에서 정할 수 없도록 제한되어 있기 때문이에요.
그럼 어떻게 해야 할까요??
위에서 배운 Variable(변수)을 사용해야 합니다.
먼저 위쪽에서 i라는 변수를 만들고, 초기값을 0으로 설정한 뒤, 그 변수를 for문 안에서 사용하면 됩니다.

char vs int?
대부분 char로 충분합니다.
하지만 초기값이 1보다 크거나, 반복 횟수가 127을 넘는다면 int를 사용하세요.
- switch / case / default / break
1. switch 블럭이란?
상황에 따라 다른 행동을 하게 만들고 싶을 때 사용하는 블럭이에요.
예를 들어,
“버튼 1을 누르면 앞으로, 버튼 2를 누르면 뒤로, 버튼 3을 누르면 멈춰!”
이런 식으로 버튼 값(숫자)에 따라 다른 동작을 하게 하고 싶을 때 사용하는 게 바로 switch예요.
쉽게 말하면 여러 선택지 중에서 정해진 행동을 고르게 해주는 블럭이에요.
switch : "어떤 값인지 보고 정해진 행동을 골라줘!"
case : "이 값일 땐 이렇게 해!"
break : "이제 그만, 더는 안 봐도 돼!"
default : "위에 아무 것도 아니면 이걸 해!"
2. 예시
1) mode 값으로 자동 상태 전환
버튼 없이도 모드를 자동으로 바꾸는 예시예요.
우리가 정한 조건에 따라 mode 값이 자동으로 바뀌면서 로봇이 스스로 움직이는 구조입니다.
예를 들어 아래와 같은 흐름으로 동작할 수 있습니다.
· mode 1 : 준비 단계
→ 준비가 되면 자동으로 mode 2로 전환!
· mode 2 : 동작(진행) 단계
→ 목표에 도달하면 자동으로 mode 3으로 전환!
· mode 3 : 종료 및 대기 단계
→ 효과 출력이 끝나면 다시 mode 1로 돌아갑니다.
이렇게 mode를 조건에 따라 자동으로 바꿔주면, 시작 → 실행 → 종료 → 재시작까지 모두 자동으로 돌아가게 만들 수 있어요!
*황토색 블록( 'mode = 2;' , 'mode = 3;' )은 직접 값을 입력해서 만든 사용자 정의 블록입니다.
*즉, 기본 블록이 아니라 내가 원하는 값을 입력해서 사용하는 블록이에요.
2) if문하고 같이 쓰는 예시도 있어요.
조도 센서(AA1)를 이용해서 주변 밝기에 따라 자동으로 모터를 다르게 작동시키는 프로그램입니다.
① while(1) 로 무한 반복을 시킵니다.
② if문으로 밝기를 판단하고 mode를 설정합니다.
③ mode 값에 따라 실행되는 코드를 다르게 설정합니다.
④ case 1, 2는 각각 밝기 조건에 따른 동작이고, 그 외의 상황(mode가 3)일 때는 default에서 처리합니다.
*황토색 블록( 'mode = 1;' , 'mode = 2;' , 'mode = 3;' )은 직접 값을 입력해서 만든 사용자 정의 블록입니다.
*즉, 기본 블록이 아니라 내가 원하는 값을 입력해서 사용하는 블록이에요.
- DC motor
1. motor1~4
motor1, motor2, motor3, motor4 함수는 모터를 제어하기 위한 기본 함수입니다.
· motor1() → CPU 블럭에서 1번, 2번 모터 제어
· motor2() → CPU 블럭에서 3번, 4번 모터 제어
· motor3(), motor4() → 일반 CPU에서는 동작하지 않고, Power CPU 전용 함수입니다.
주로 4륜 구동 같은 고급 모터 제어에서 사용됩니다.
인자값 ① : -20 ~ 20
→ 숫자가 클수록 속도가 빨라지고,
→ + 값이면 정방향, - 값이면 역방향 회전입니다.

2. motor
① 왼쪽 모터 속도
→ CPU 블럭의 motor1, motor2를 의미합니다.
→ 속도는 -20 ~ 20 범위로 지정할 수 있어요.
→ +는 정방향, -는 역방향입니다.
② 오른쪽 모터 속도
→ CPU 블럭의 motor3, motor4를 의미합니다.
→ 이 속도도 -20 ~ 20으로 설정 가능해요.
③ 동작 시간
→ 단위는 **1/1000초(=밀리초)**입니다.
→ 예: 1000이면 1초 동안 동작
→ 기본적으로 60초까지라고 표시되지만, 그 이상도 가능합니다.
3. allmotor
allmotor() 함수는 4개의 모터를 한 번에 제어할 수 있는 함수예요.
파워 CPU에서만 사용할 수 있는 기능입니다.
조합함수로 motor1, motor2, motor3, motor4 함수가 조합된 함수입니다.
인자값 ① : -20 ~ 20 이며 속도를 의미합니다.
인자값 ② : -20 ~ 20 이며 속도를 의미합니다.
인자값 ③ : -20 ~ 20 이며 속도를 의미합니다.
인자값 ④ : -20 ~ 20 이며 속도를 의미합니다.
모든 속도는 -20 ~ 20 사이로 지정할 수 있어요.
+ 값이면 앞으로, - 값이면 뒤로 움직입니다.

- wheel1 / wheel2
wheel()과 wheel2() 함수는 시간 없이 실시간으로 동작하는 모터 제어 함수입니다.
버튼이나 센서 등의 입력에 따라 즉각 반응해야 하는 상황에 적합해요.
1. wheel함수는 motor1, motor2함수가 조합된 함수입니다.
인자값 ① : -20 ~ 20 이며 속도를 의미합니다.
인자값 ② : -20 ~ 20 이며 속도를 의미합니다.
2. wheel함수는 motor3, motor4함수가 조합된 함수입니다.
인자값 ① : -20 ~ 20 이며 속도를 의미합니다.
인자값 ② : -20 ~ 20 이며 속도를 의미합니다.
- Servo Motor(servo1~4)
servo1, 2, 3, 4함수는 서보모터를 구동하기 위한 함수입니다. B1, B2, B3, B4에 꽂아 사용합니다.
인자값 ① : 0 또는 1 ~ 100
(0=서보토크 풀림, 1=0도, 100=180도)
- Port On() / Off()
이 함수는 LED 보드, 보이스 보드, 릴레이 보드 등 전원을 켜고 끄는 장치들을 간단하게 켜고 끄기 위한 함수입니다.
CPU 블록의 B1, B2, B3, B4 포트 중 하나에 장치를 연결하고, 코드에서 on(B1);을 사용하면 전원이 켜지고, off(B1);을 사용하면 전원이 꺼집니다.
- Sound
1. play
play함수는 멜로디를 출력하는 함수 입니다.
melody, delay함수가 조합된 함수입니다.
인자값 ① : 음의 높이
숫자나 음 이름을 사용해서 소리를 정해요.
예: do4, re5, sol6처럼 do, re, mi는 음이름 뒤 숫자 4, 5, 6은 옥타브 (높낮이)를 뜻해요.
0을 넣으면 쉼표(소리 없음)가 돼요.
인자값 ② : 음의 길이
n1부터 n32까지 있어요.
숫자가 클수록 소리 길이는 짧아지고, 숫자가 작을수록 소리 길이는 길어져요.
예: n1은 가장 길고, n32는 아주 짧아요.
2. buzzer
이 함수는 부저(삐 소리를 내는 장치)에서 소리를 반복해서 내는 함수입니다.
멜로디처럼 음의 높이와 반복 횟수, 울리는 시간 등을 정해서 사용할 수 있어요.
① 음의 높이 (예: do4, mi5 등)
소리의 높낮이를 정해요.
do4는 4옥타브의 ‘도’, sol5는 5옥타브의 ‘솔’
do4 ~ si7 사이 음만 가능해요.
② 반복 횟수 (0 ~ 255)
이 소리를 몇 번 울릴지 정해요.
예: 3으로 넣으면 같은 음이 3번 반복돼요.
③ on 시간 (0 ~ 65535)
소리가 얼마 동안 울릴지 정하는 시간이에요.
숫자가 클수록 길게 울려요. (단위: 1/1000초)
④ off 시간 (0 ~ 65535)
소리가 울린 후 얼마 동안 쉴지 정하는 시간이에요.
이건 부저가 ‘삐’ 하고 난 뒤 얼마나 멈췄다 다시 울릴지에 해당돼요.
3. tempo
tempo함수는 play, melody함수를 사용할 때 음의 속도에 영향을 줍니다.
인자값 ① : 0~255 (값이 작을수록 빠릅니다.)

4. melody
melody함수는 멜로디를 출력하는 함수입니다.
인자값 ① : 0, do4~si7까지 4옥타브로 음의 높이를 의미합니다. (숫자 0 = 쉼표)

5. start_melody / end_melody
이 함수들은 시작과 끝을 알려주는 멜로디를 간단하게 재생할 수 있는 함수입니다.
start_melody 함수는 도 → 레 → 미 → 파 → 솔 → 라 → 시 → 도
순서대로 음이 올라가는 멜로디를 재생합니다.
→ 무언가 시작될 때 사용하기 좋아요!
end_melody 함수는 도 → 시 → 라 → 솔 → 파 → 미 → 레 → 도
순서대로 음이 내려가는 멜로디를 재생합니다.
→ 무언가 끝날 때 사용하면 딱 좋아요!
이 함수들도 melody와 delay 함수를 합쳐서 만든 블록입니다.
인자값 ① : 0 ~ 255
→ 멜로디의 속도를 정해요.
숫자가 작을수록 빠르게, 클수록 느리게 재생돼요.
7. level_up_melody / level_down_melody
이 함수들은 특정한 멜로디를 간단하게 재생할 수 있게 해주는 함수입니다.
level_up_melody 함수는 도 → 미 → 솔 → 도 순서로 음이 올라가는 멜로디를 재생합니다.
level_down_melody 함수는 도 → 솔 → 미 → 도 순서로 음이 내려가는 멜로디를 재생합니다.
이 함수들은 melody와 delay 함수가 조합된 형태로, 직접 음과 길이를 지정하지 않아도 정해진 멜로디가 출력됩니다.
인자값 ① : 0 ~ 255
→ 멜로디의 재생 속도를 의미합니다. 숫자가 작을수록 빠르게 울리고, 클수록 느리게 울립니다.

- delay

delay함수는 시간지연
함수입니다.
인자값 ① : 0~65535 (100=0.1초)
- timer
timer함수는 주로 timer_read()함수와 함께 사용되는 함수로 타이머를 셋팅 할 수 있습니다.
주로 0부터 시작하게 됩니다.
인자값 ① : 0~65535
- rgbled1
rgbled1함수는 RGB LED보드를 동작시키는 함수 입니다. B1, B2, B3, B4에 꽂아 사용합니다.
인자값 ① : RGBOFF, 1~100
(api.h 파일 테이블 참조)

- FND
fnd() 함수는 FND블럭에 숫자(0~99) 를 출력할 수 있게 해주는 함수입니다.
인자값 ① : 0 ~ 99 또는 100
0 ~ 99 : FND에 해당 숫자를 표시합니다.
예: fnd(25); → 숫자 25가 화면에 표시돼요.
100 : FND 화면을 끄는 명령입니다.
예: fnd(100); → 화면이 꺼집니다.
- EEPROM
전원이 꺼져도 값이 사라지지 않는 저장 공간이에요.
중요한 값을 저장해두고, 다시 켰을 때 불러올 수 있어요!
EEPROM_write(주소, 데이터);
주소 : 0 ~ 255 (저장할 위치)
데이터 : 0 ~ 255 (저장할 값)
➡아래 사진은 주소 1번에 ‘50’이라는 값을 저장하는 거예요.
그런데, 값을 불러오는 read 블록은 어디에 있을까요?
EEPROM 블록에는 없어요!
‘직접입력’ 블록을 사용하면 돼요! (블록리스트 밑에서 두번째에 있습니다.)

① 직접입력하면 됩니다.
② 함수 탭으로 들어가세요! 아래처럼 더블클릭하면 불러오기가 됩니다.

예시를 들어보겠습니다.
전원을 끄기 전에 점수를 저장해야겠죠!
프로그램 맨 위쪽에 EEPROM_write(1, 50); 처럼 작성해서 현재 점수를 1번 주소에 저장해둡니다.
그럼 전원을 껐다가 다시 켜도 이 점수는 사라지지 않고 EEPROM에 남아 있게 됩니다.
다음에는 이 점수를 다시 불러오면 이어서 게임을 할 수 있어요.
이어서 설명드릴게요. 이제 저장한 값을 어떻게 불러오는지!
위에 for문과 마찬가지로 직접 입력 블록 안에서도 새로운 변수를 선언하거나 초기화(int i = 0 등)할 수 없습니다.

그래서 우리는 위에서 해본 Variable(변수 블록)을 사용해야 해요!

int score = 0; 으로 변수 score를 먼저 만들어 두고,
직접 입력 블록에서 score = EEPROM_read(1); 을 사용하면,
저장했던 데이터를 다시 불러와서 변수 score에 넣을 수 있어요!
- INPORT
1. HIGH / LOW
CPU 블럭에 있는 A1, A2, A3, A4 포트는 원래는 입력용이에요.
하지만 LED를 켜거나, 전원을 보내야 할 때는 이 포트를 출력용으로 바꿔줘야 해요.
그래서 먼저 OUTPORT(A1); 이렇게 써서 A1을 출력으로 바꿔줘요!
이제 A1에 전기를 보내고 싶으면 HIGH(A1);
전기를 끊고 싶으면 LOW(A1);을 쓰면 돼요.
예시
2. PULLUP / PULLDOWN
A1 같은 포트는 기본적으로 입력 전용이에요.
그래서 따로 설정하지 않아도 INPORT 상태로 동작해요.
하지만, 만약 OUTPORT(PDA1);처럼 출력으로 바꾼 적이 있다면, 다시 입력으로 쓰기 위해 INPORT(PDA1); 블록을 꼭 써줘야 해요.
플로팅(Floating) 상태란,
입력 상태에서 센서가 없거나, 신호가 불안정할 때 A1 포트는 0인지 1인지 판단이 어려운 상태가 돼요.
이런 상태를 Floating 상태라고 해요.
· 0도 아니고, 1도 아니에요
· 외부 전기 신호에 따라 값이 오락가락할 수 있어요
· 작동이 불안정해져서 오류가 날 수도 있어요
이럴 땐 PULLUP()이나 PULLDOWN()을 써서 값이 안정적으로 유지되도록 도와줘야 해요
1) PULLUP(PDA1)
A1을 입력 상태로 바꾼 후, 기본값을 1(높음) 으로 유지해줘요.
대부분의 경우 GULC는 처음부터 PULLUP 상태예요.
하지만 출력으로 썼다가 다시 입력으로 바꿀 땐 꼭 써줘야 해요.
예시
목표 : 버튼을 누르면 LED 꺼짐.

2) PULLDOWN(PDA1)
INPORT(PDA1); 다음에 PULLDOWN(PDA1);을 쓰면 A1의 기본값을 낮은 상태(0)로 만들어줘요.
미세한 신호 변화를 감지하고 싶을 때 사용해요.
하지만 보통 사용하는 센서들은 이걸 쓰지 않아도 괜찮아요.
*주의
센서를 연결하지 않거나, 일부 센서를 사용할 땐 0과 1이 계속 왔다 갔다 하는 오작동이 일어날 수 있어요.
이럴 땐 PULLUP을 써주는 게 더 안전해요.
예시
목표 : 작은 신호 감지하면 LED 켬

3. INPORT(PDA1)
PDA1을 다시 입력 상태로 바꿔서 센서나 버튼의 신호를 읽을 수 있게 해줘요.
1) 언제 사용하나요?
· A1을 OUTPORT로 쓰다가 다시 입력으로 돌릴 때
· 센서를 연결해서 값을 읽고 싶을 때
2) 함께 사용하는 블록
· PULLUP(PDA1) → 기본값을 1로 유지
· PULLDOWN(PDA1) → 기본값을 0으로 설정 (민감한 감지용)
3) 예시
A1에 연결된 버튼을 누르면 B1 LED가 켜짐
버튼에서 손을 떼면 LED가 꺼짐

4. OUTPORT(PDA1)
PDA1은 원래 입력용 포트(A1)지만, 출력 포트가 부족할 때 출력용으로도 사용할 수 있어요.
1) 언제 사용하나요?
· LED 등을 A1에 연결해서 켜고 끌 때
· 출력 전용 포트(B1~B4)가 부족할 때
2) 함께 사용하는 블록
· HIGH(PDA1) → A1에서 1 출력 (전기 보내기)
· LOW(PDA1) → A1에서 0 출력 (전기 끄기)
3) 예시
출력 전용 포트가 부족해서 A1을 출력으로 사용
A1에 연결된 LED를 1초 간격으로 깜빡이게 함

5. OUTPORT → INPORT 전환 예시
이 코드는 PDA1 포트를 처음엔 출력(LED 제어) 으로 쓰고, 그 다음에 입력(버튼 감지) 으로 역할을 바꿔 쓰는 예시예요.
1) 동작 순서
A1에 LED를 연결해서 1초간 켰다가 끕니다.
→ 이때는 OUTPORT(PDA1) 상태
LED를 제거하고 버튼을 A1에 다시 꽂은 후
→ INPORT(PDA1)로 바꿔 입력값을 감지합니다.
버튼을 누르면 B1의 LED를 켜는 코드가 실행됩니다.
2) 중요한 포인트
하나의 포트(A1)를 출력용(LED) 으로도 쓰고, 그걸 다시 입력용(버튼) 으로 바꿔서 두 가지 용도로 사용하는 구조예요.
실제 회로에서는 LED를 제거하고 버튼을 새로 꽂아야 정확히 동작해요.
중간에 바꾸는 이유는 출력 포트가 부족할 때 하나의 포트를 재활용하는 유용한 방법이기 때문이에요.

- 직접 입력

명령문 및 기타 입력을 직접
타이핑할 수 있는 블럭입니다. 입력 줄 끝에 ‘;’를 자동으로 붙여줍니다.
(줄 끝에 ‘;’까지 입력 했다면 생략됩니다.)