페이지

2026년 1월 3일 토요일

2.4.3. 미니 피아노 만들기

안녕하세요! 여러분의 AI-IT 멘토, '파이컴'입니다. 😊

지난번 아두이노가 연주해 주는 '학교 종' 멜로디, 다들 잘 들어보셨나요? 이번에는 우리가 직접 연주자가 되어보는 시간을 가져볼 거예요. 바로 버튼 3개를 피아노 건반처럼 사용해서 '도, 레, 미' 음계를 연주하는 미니 피아노를 만들어 볼 거랍니다!

자, 그럼 저와 함께 나만의 작은 악기를 만들어볼까요?

Slide 1: 03. 미니 피아노 만들기

이번 시간에는 [2장 기본 부품과 C언어 체험하기]의 네 번째 주제, 피에조 부저를 활용한 프로젝트를 진행해요. 바로 '미니 피아노 만들기'입니다!

이전에는 코드를 업로드하면 아두이노가 정해진 멜로디를 자동으로 연주했지만, 이번에는 우리가 버튼을 누를 때마다 해당하는 소리가 나도록 만들 거예요. 즉, 우리가 직접 연주자가 되어 간단한 동요 정도는 연주할 수 있는 멋진 악기를 만드는 거죠! 정말 기대되지 않나요?

Slide 2: 미니 피아노 만들기 - 회로

가장 먼저 악기를 만들어야 연주를 할 수 있겠죠? 하드웨어, 즉 회로부터 차근차근 구성해 볼게요.

✅ 준비물

  • 아두이노 UNO
  • 피에조 부저 1개
  • 푸시 버튼 3개
  • 브레드보드 및 점퍼선

✅ 회로 구성 방법

슬라이드에 보이는 회로도를 자세히 살펴볼까요?

  1. 피에조 부저 연결: 부저는 이전 실습과 똑같아요. 긴 다리(+)는 아두이노 11번 핀에, 짧은 다리(-)는 GND에 연결해주세요.
  2. 버튼 연결: 3개의 버튼이 각각 '도', '레', '미' 건반 역할을 할 거예요.
    • 첫 번째 버튼은 아두이노 2번 핀에 연결해요.
    • 두 번째 버튼은 아두이노 3번 핀에 연결해요.
    • 세 번째 버튼은 아두이노 4번 핀에 연결해요.
  3. 버튼의 나머지 다리 연결: 버튼의 반대쪽 다리들은 모두 한데 묶어 아두이노의 GND에 연결해주세요.

어? 그런데 뭔가 이상한 점을 발견하셨나요? 맞아요! LED를 연결할 때와는 다르게 버튼에 저항이 없어요!

이게 가능한 이유는 바로 아두이노 내부에 있는 저항을 빌려 쓰는 '내부 풀업(INPUT_PULLUP)' 방식을 사용할 것이기 때문이에요. 이 방식을 사용하면 외부 저항 없이도 버튼의 상태를 안정적으로 읽을 수 있어서 회로가 훨씬 간단해진답니다. 이 부분은 코드에서 다시 한번 설명해 드릴게요!

Slide 3: 미니 피아노 - 코드

자, 이제 피아노에 생명을 불어넣을 소프트웨어, 즉 코드를 작성할 시간이에요. 버튼을 누를 때마다 정해진 음계 소리가 나도록 만들어볼게요.

✅ 버튼별 음계 할당

  • 2번 핀 버튼: '도' (262Hz)
  • 3번 핀 버튼: '레' (294Hz)
  • 4번 핀 버튼: '미' (330Hz)

✅ 전체 소스 코드

CODE 2.12 | 미니 피아노 만들기 코드
01// CODE 2.12 | 미니 피아노 만들기 코드
02
03void setup() {
04 pinMode(2, INPUT_PULLUP);
05 pinMode(3, INPUT_PULLUP);
06 pinMode(4, INPUT_PULLUP);
07}
08
09void loop() {
10 if (!(digitalRead(2) == HIGH)) { // 2번 버튼(도)이 눌렸는지 확인
11 tone(11, 262, 100); // '도' 음을 0.1초간 연주
12 }
13
14 if (!(digitalRead(3) == HIGH)) { // 3번 버튼(레)이 눌렸는지 확인
15 tone(11, 294, 100); // '레' 음을 0.1초간 연주
16 }
17
18 if (!(digitalRead(4) == HIGH)) { // 4번 버튼(미)이 눌렸는지 확인
19 tone(11, 330, 100); // '미' 음을 0.1초간 연주
20 }
21}

✅ 코드 해설

  1. setup() 함수 (3~7줄)
    • pinMode(2, INPUT_PULLUP); : 2번, 3번, 4번 핀을 모두 INPUT_PULLUP 모드로 설정했어요. 이렇게 설정하면 아두이노 내부의 저항이 활성화되어, 버튼을 누르지 않았을 때는 HIGH 신호가, 버튼을 눌렀을 때는 LOW 신호가 입력돼요. 덕분에 외부 저항이 필요 없었던 거죠!
  2. loop() 함수 (9~21줄)
    • 세 개의 if문이 각각 2번, 3번, 4번 버튼의 상태를 계속 확인해요.
    • if (!(digitalRead(2) == HIGH)) : 이 부분이 조금 낯설죠? 바로 오늘 배울 핵심 문법이에요. 간단히 말해 "2번 핀의 상태가 HIGH가 아니라면 (즉, LOW라면)" 이라는 뜻이에요. INPUT_PULLUP 모드에서는 버튼을 눌렀을 때 LOW 상태가 되므로, 이 조건문은 "2번 버튼이 눌렸다면"과 같은 의미가 됩니다.
    • tone(11, 262, 100); : 만약 버튼이 눌렸다면, 11번 핀에 연결된 부저로 262Hz('도') 음을 100ms(0.1초) 동안 연주해요.
    • 나머지 버튼들도 같은 원리로 '레'와 '미' 음을 연주한답니다.

코드를 업로드하고 버튼을 하나씩 눌러보세요. '도-레-미' 소리가 경쾌하게 들릴 거예요!

Slide 4: 논리 부정 연산자 (!)

방금 코드에서 봤던 느낌표 !의 정체가 궁금하셨죠? C언어에서 !는 아주 재미있는 역할을 하는 '논리 부정 연산자(Logical NOT Operator)'랍니다.

✅ 역할: 뭐든지 반대로! "청개구리 연산자"

! 연산자는 마치 청개구리처럼 모든 것을 반대로 뒤집어 버려요.

  • 참(True)을 만나면 거짓(False)으로
  • 거짓(False)을 만나면 참(True)으로

컴퓨터가 알아듣는 신호인 1과 0으로 보면, 1을 0으로, 0을 1로 바꾸는 마법사 같은 존재죠.

✅ 사용 예시: 우리 코드 다시 보기

if (!(digitalRead(2) == HIGH)) 이 코드를 차근차근 분석해 볼게요.

  1. 버튼을 누르지 않았을 때
    • digitalRead(2) 값은 HIGH가 들어와요.
    • 괄호 안의 (digitalRead(2) == HIGH)(HIGH == HIGH)가 되므로, 결과는 참(True)이 됩니다.
    • 하지만 앞에 청개구리 !가 붙어서 이 참(True)거짓(False)으로 뒤집어 버려요.
    • 결론적으로 if문의 조건이 거짓이 되므로, 안쪽의 tone() 함수는 실행되지 않아요. (소리가 안 남)
  2. 버튼을 눌렀을 때
    • digitalRead(2) 값은 LOW가 들어와요.
    • 괄호 안의 (digitalRead(2) == HIGH)(LOW == HIGH)가 되므로, 결과는 거짓(False)이 됩니다.
    • !가 이 거짓(False)참(True)으로 확 뒤집어 버리죠!
    • 결론적으로 if문의 조건이 참이 되므로, 안쪽의 tone() 함수가 실행됩니다. (소리가 남)

이제 왜 ! 기호를 썼는지 완벽하게 이해되셨죠? "HIGH가 아닐 때" 라는 조건을 만들어 "버튼이 눌렸을 때"를 감지하기 위함이었답니다.

오늘은 버튼과 피에조 부저를 이용해 나만의 미니 피아노를 만들어 보았어요. 단순히 소리를 듣는 것을 넘어, 직접 버튼을 눌러 연주까지 해보니 정말 재미있지 않았나요?

오늘 배운 내용을 정리해 볼게요.

  • INPUT_PULLUP을 이용해 외부 저항 없이 버튼 회로를 간단하게 구성했어요.
  • if 조건문tone() 함수를 사용해 각 버튼에 다른 음계를 할당했어요.
  • 논리 부정 연산자 !가 어떻게 조건을 반대로 뒤집어 주는지 확실하게 배웠어요.

이제 여러분은 '도, 레, 미'를 연주할 수 있는 연주자가 되었어요! "학교 종"이나 "비행기" 같은 간단한 동요를 한번 연주해보는 건 어떨까요? 더 나아가 버튼을 추가해서 더 높은 음계를 만들어보는 것도 멋진 도전이 될 거예요!

오늘도 정말 수고 많으셨습니다. 다음 시간에 더 재미있는 프로젝트로 만나요! 👋

이 포스팅의 내용은 교재 [주니어 공학교실 아두이노의 기초] 150-152 페이지에 수록된 내용입니다.

댓글 없음:

댓글 쓰기