brunch

You can make anything
by writing

C.S.Lewis

by Cylogic Aug 26. 2020

20. 네 번째 장난감:나 따라 하기3- 빛과 소리

부저와 LED를 이용한 장난감

앞의 두 강좌에서 회로를 꾸미고 효과음과 효과 빛을 사용하는 방법을 배웠다.

이제는 전체 프로그램의 구조를 짜서 앞에서 만든 함수를 연결하는 방법을 배워 보자.

프로그램의 흐름은 아래와 같다.


LED와 소리의 효과에 대해서는 앞선 강좌에서 이야기했으므로 이제는 어떻게 게임을 만들고, 그 게임을 풀어나갈지에 대한 이야기로 네 번째 장난감 강좌를 마무리해 보자.


먼저 버튼을 누르면 해당 버튼에 연결된 LED를 켜고 부저를 울리게 하는 부분을 구현하면,


int active_btn(){

  for (int i=0; i<4; i++){                    // 연결된 4개의 버튼을 검사하여

    if (digitalRead(btn[i])==LOW){ // 이 중 하나의 버튼이라도 눌렸으면      

        digitalWrite(led[i], HIGH);     // 해당 LED를 켜고 

        tone(sPin,note[i*2],300);       // 해당 음을 0.3초간 부저로 울리고

        delay(300);                                // 0.3초 후 

        digitalWrite(led[i], LOW);       // LED를 끈다

        return i;                                      // 현재 눌려진 버튼이 몇 번인지를 return한다.

     }

   }  

  return -1;                                         // 버튼이 눌리지 않았으면 -1을 return 한다.

}


4개의 버튼 중 어떤 버튼인 눌릴지 모르므로 4개를 모두 검사하여 버튼이 눌린 것을 감지하면 해당 LED를 켜고 해당 음을 재생한다.


전체 프로그램의 구조를 살펴볼 수 있는 

loop 함수를 보자.


void loop() {

  while(1){                           

    int val=random(4);          // 임의의 숫자를 발생

    if (num[stage-1]!=val){   // num에 이전에 들어온 값과 같은지 비교

      num[stage]=val;            // 같지 않으면 num의 현재 stage에 저장

      stage++;                          // stage 번호 증가

      break;

    }

  }  

  for (int i=0;i<stage;i++){     

     digitalWrite(led[num[i]], HIGH);   // 새로운 stage까지 해당 led를 켜서 보여줌

     tone(sPin,note[num[i]*2],500);    // 해당 소리 발생

     delay(500);

     digitalWrite(led[num[i]], LOW);

  }

  if (solve_game()){                                  

    if (stage==10){                       // 게임을 성공적으로 풀어

      Serial.println("succeed");                    

      reset_all();                           // 그 stage가 10이면 성공- 게임 리셋

    }

  }

  else {

    Serial.println("FAIL");          //  solve_game에서 false 값이 돌아오면

    fail_sign();                              // 실패 신호 

    reset_all();                             // 게임 리셋

  }

}


게임을 풀어 나가는 방법을 살펴보자.


boolean solve_game(){

  int gstage=0;                          // 몇 번 stage까지 풀었는지 추적하는 변수

  char str[30];                           

  while(1){

    int ab=active_btn();            // 몇 번 버튼이 눌렸는지 확인하는 변수

    if (ab==-1) continue;           // 눌리지 않았으면 다시 진행

    if (num[gstage]== ab){        // 버튼이 num에 저장된 번호와 같은지 확인

      sprintf(str, "stage = %d, gstage = %d", stage, gstage);

      Serial.println(str);

      gstage++;                             // 진행한 stage 번호 증가

      if (gstage==stage) break;    // 저장된 stage와 현재 stage가 같은 지 확인

      continue;

    }

    else{  //눌린 버튼이 num에 저장된 번호와 다름 실패

      return false;

    }

  }

  delay(200);

  return true;

}



이제 전체 코드를 한눈에 보자.

위의 코드에서는 전체적인 게임의 구성을 볼 수 있다.

아래의 코드에서는 게임을 풀어나가고 LED와 음향 효과를 실행하는 부분을 볼 수 있다.


이 모든 코드를 종합하여 구성하면 아래의 영상과 같은 장난감이 완성되는 것이다.

아마 처음으로 코딩 강좌를 따라오시는 분이라면 이번 강좌는 쉽지 않았을 것이다.

그래도 하나의 디지털 장난감을 만드는 전 과정을 한번 따라 해 보는 것이 디지털 메이킹을 이해하는 좋은 방법이라고 생각하여 보여 드린 것이니, 어렵다고 포기하지 마시고 다음 강좌를 확인해 보시기 바란다.


다음 강좌에서는 앞서 배운 초음파 센서와 모터를 이용한 아주 쉬운 응용 장난감을 만들어 볼 예정이다.




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari