2022-05-23 Arduino_12

2022. 5. 23. 00:56학부 강의/Arduino

디지털 게임기 프로젝트 조사 과제

 


1. Ping Pong Game

  • 아두이노 파일 :
#ifndef __DEVICE_CONF_H__
#define __DEVICE_CONF_H__

// DIGITAL PINS USED
enum DigitalPins{
  Right_button2 = 8,
  Left_button2,
  Right_button1,
  BUZZER,
  Left_button1
};
// ANALOG PINS
enum AnalogPins{
  POTENTIOMETER = 0
};
// DIGITAL PINS ON LCD
enum LCDPins{
  LCD_D7 = 2,
  LCD_D6,
  LCD_D5,
  LCD_D4,
  LCD_ENABLE,
  LCD_RS
};
// Dimensions of used LCD
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#define LCD_CHAR_WIDTH 5
#define LCD_CHAR_HEIGHT 8
#define LCD_PIXEL_WIDTH LCD_WIDTH*LCD_CHAR_WIDTH
#define LCD_PIXEL_HEIGHT LCD_HEIGHT*LCD_CHAR_HEIGHT
#define LCD_CUSTOM_CHARS_N 8

// Default serial bits-per-second
#define SERIAL_BAUD 9600

#endif

// ######## graphics.h ########

#ifndef __GRAPHICS_H__
#define __GRAPHICS_H__

// Add dot to graphical back-buffer
bool g_add_dot(const byte x, const byte y);
// Add horizontal left-to-right line to graphical back-buffer
bool g_add_hline(char x, const char y, const byte len);
// Add vertical top-to-bottom line to graphical back-buffer
bool g_add_vline(const char x, char y, const byte len);

// Draw back-buffer
void g_draw(void);
// Draw text directly
void g_draw_text(const byte x, const byte y, const String s);
// Clear back-buffer and display
void g_clear(void);

#endif

// ######## graphics.c ########

//#include "graphics.h"
#include <LiquidCrystal.h>
//#include "device_conf.h"

// Output device & memory
static LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
static struct LCDInitializer{LCDInitializer(struct LiquidCrystal* lcd){lcd->begin(LCD_WIDTH, LCD_HEIGHT);}} _lcd(&lcd);
static byte chars[LCD_HEIGHT][LCD_WIDTH][LCD_CHAR_HEIGHT] = {{{0}}};

static bool char_dot_position(const byte x, const byte y, byte* char_x, byte* char_y, byte* inner_x, byte* inner_y){
  if(x >= LCD_PIXEL_WIDTH || y >= LCD_PIXEL_HEIGHT)
    return false;
  const div_t div_x = div(x, LCD_CHAR_WIDTH),
        div_y = div(y, LCD_CHAR_HEIGHT);
  *char_x = div_x.quot;
  *char_y = div_y.quot;
  *inner_x = div_x.rem;
  *inner_y = div_y.rem;
  return true;
}
bool g_add_dot(const byte x, const byte y){
  byte char_x, char_y, inner_x, inner_y;
  if(!char_dot_position(x, y, &char_x, &char_y, &inner_x, &inner_y))
    return false;
  chars[char_y][char_x][inner_y] |= bit(LCD_CHAR_WIDTH-1) >> inner_x;
  return true;
}
bool g_add_hline(char x, const char y, const byte len){
  if(y >= 0)
    for(const char x2 = x+len-1; x <= x2; ++x)
      if(x >= 0)
        g_add_dot(x, y);
}
bool g_add_vline(const char x, char y, const byte len){
  if(x >= 0)
    for(const char y2 = y+len-1; y <= y2; ++y)
      if(y >= 0)
        g_add_dot(x, y);
}

void g_draw(void){
  // Characters to draw storage
  byte n_chars = 0;
  struct {byte x, y;} chars_pos[LCD_CUSTOM_CHARS_N];
  // Collect characters to draw
  for(byte y = 0; y < sizeof(chars)/sizeof(chars[0]); ++y)
    for(byte x = 0; x < sizeof(chars[0])/sizeof(chars[0][0]); ++x){
      const byte* current_char = chars[y][x];
      for(byte row = 0; row < sizeof(chars[0][0])/sizeof(chars[0][0][0]); ++row)
        if(current_char[row]){
          lcd.createChar(n_chars, (byte*)current_char);
          chars_pos[n_chars].x = x;
          chars_pos[n_chars++].y = y;
          if(n_chars == sizeof(chars_pos)/sizeof(chars_pos[0])) // Limit reached
            goto draw_chars;
          break;
        }
    }
  // Draw characters
  draw_chars:
  for(byte c = 0; c < n_chars; ++c){
    lcd.setCursor(chars_pos[c].x, chars_pos[c].y);
    lcd.write(c);
  }
}
void g_draw_text(const byte x, const byte y, const String s){
  lcd.setCursor(x, y);
  lcd.print(s);
}
void g_clear(void){
  memset(chars, 0, sizeof(chars));
  lcd.clear();
}

// ######## init.c ########

//#include "device_conf.h"
//#include "graphics.h"

// Initialize Arduino device
void setup(){
  // Set pin modes
  pinMode(Left_button1, INPUT);
  pinMode(Right_button1, INPUT);
  pinMode(Left_button2, INPUT);
  pinMode(Right_button2, INPUT);
  pinMode(BUZZER, OUTPUT);
  // Initialize serial connection
  Serial.begin(SERIAL_BAUD);
  while(!Serial) // Wait for device response
    delay(100);
  // Show welcome text
  g_draw_text(0, 0, "Ping-Pong Game");
  delay(3000);
}

// ######## math.h ########

#ifndef __MATH_H__
#define __MATH_H__

// Ranged random numbers
#define RANDOM_DIRECTION (((random() & 0x1) << 1) - 1)
#define RANDOM_STEP(start, end, step) (start + random() % int((end-start) / step + 1) * step)
// Swap numbers
#define SWAP(a,b) (a ^= b ^= a ^= b)
void swapf(float* a, float* b);
// Collision detection
bool line_x_hline(float x1, float y1, float x2, float y2, const float lx, const float ly, const float llen, float* cx);
bool line_x_vline(float x1, float y1, float x2, float y2, const float lx, const float ly, const float llen, float* cy);

#endif

// ######## math.c ########

//#include "math.h"

void swapf(float* a, float* b){
  const float temp = *a;
  *a = *b;
  *b = temp;
}

bool line_x_hline(float x1, float y1, float x2, float y2, const float lx, const float ly, const float llen, float* cx){
  // Both lines horizontal / parallel?
  if(y1 == y2)
    return false;
  // Sort line points top-to-bottom
  if(y1 > y2)
    swapf(&x1,&x2), swapf(&y1,&y2);
  // Lines can't cross vertical?
  if(ly < y1 || ly > y2)
    return false;
  // Lines crossing
  *cx = x1 == x2/*Vertical line?*/ ? x1 : (x2 - x1) / (y2 - y1) * (ly - y1) + x1;
  // Lines can cross horizontal?
  return *cx >= lx && *cx <= lx + llen;
}

bool line_x_vline(float x1, float y1, float x2, float y2, const float lx, const float ly, const float llen, float* cy){
  // Both lines vertical / parallel?
  if(x1 == x2)
    return false;
  // Sort line points left-to-right
  if(x1 > x2)
    swapf(&x1,&x2), swapf(&y1,&y2);
  // Lines can't cross horizontal?
  if(lx < x1 || lx > x2)
    return false;
  // Lines crossing
  *cy = y1 == y2/*Horizontal line?*/ ? y1 : (y2 - y1) / (x2 - x1) * (lx - x1) + y1;
  // Lines can cross vertical?
  return *cy >= ly && *cy <= ly + llen;
}

// Game properties
#define PLAYER_SIZE 7
#define MIN_UPDATE_DELAY 100
#define MAX_UPDATE_DELAY 2000
#define SOUND_FREQUENCY 1000
#define SOUND_DURATION 50
#define PLAYER1_X 0
#define PLAYER2_X LCD_PIXEL_WIDTH-1
// Game state
static byte player1_pos = 0,
            player2_pos = 0;
static float ball_pos_x = LCD_PIXEL_WIDTH / 2.0f,
             ball_pos_y = LCD_PIXEL_HEIGHT / 2.0f,
             ball_mov_x = RANDOM_DIRECTION * RANDOM_STEP(1, 3, 0.5f),
             ball_mov_y = RANDOM_DIRECTION * RANDOM_STEP(1, 3, 0.5f);
static bool change_action = true;

// Collision logic
static void player_reflect(const byte area){
  ball_mov_x = -ball_mov_x;
  switch(area){ // Upper-, mid- or lower area of player
    case 0:
      if(ball_mov_y > 0)
        ball_mov_y /= 2, ball_mov_x *= 2;
      else if(ball_mov_y < 0)
        ball_mov_y *= 2, ball_mov_x /= 2;
      else
        ball_mov_y = -abs(ball_mov_x);
      break;
    case 1:
      break;
    case 2:
    default:
      if(ball_mov_y > 0)
        ball_mov_y *= 2, ball_mov_x /= 2;
      else if(ball_mov_y < 0)
        ball_mov_y /= 2, ball_mov_x *= 2;
      else
        ball_mov_y = abs(ball_mov_x);
      break;
  }
}

// Arduino device idle callback
void loop(){
  // Profile current run
  const unsigned long profile_start_time = millis();
  // Update player position
  const byte Left_button1_pressed = digitalRead(Left_button1),
             Right_button1_pressed = digitalRead(Right_button1),
             Left_button2_pressed = digitalRead(Left_button2),
             Right_button2_pressed = digitalRead(Right_button2);
  if(Left_button1_pressed && !Right_button1_pressed && player1_pos != 0)
    --player1_pos, change_action = true;
  else if(!Left_button1_pressed && Right_button1_pressed && player1_pos != LCD_PIXEL_HEIGHT-PLAYER_SIZE)
    ++player1_pos, change_action = true;
  if(Left_button2_pressed && !Right_button2_pressed && player2_pos != LCD_PIXEL_HEIGHT-PLAYER_SIZE)
    ++player2_pos, change_action = true;
  else if(!Left_button2_pressed && Right_button2_pressed && player2_pos != 0)
    --player2_pos, change_action = true;
  // Update ball position
  float new_ball_pos_x = ball_pos_x + ball_mov_x,
        new_ball_pos_y = ball_pos_y + ball_mov_y,
      cy;
  if(line_x_vline(ball_pos_x, ball_pos_y, new_ball_pos_x, new_ball_pos_y, PLAYER1_X + 1, player1_pos, PLAYER_SIZE, &cy)){ // Hit player 1
    tone(BUZZER, SOUND_FREQUENCY, SOUND_DURATION);
    player_reflect((cy - player1_pos) / PLAYER_SIZE * 3);
    new_ball_pos_x = ball_pos_x + ball_mov_x;
    new_ball_pos_y = ball_pos_y + ball_mov_y;
  }else if(line_x_vline(ball_pos_x, ball_pos_y, new_ball_pos_x, new_ball_pos_y, PLAYER2_X, player2_pos, PLAYER_SIZE, &cy)){ // Hit player 2
    tone(BUZZER, SOUND_FREQUENCY, SOUND_DURATION);
    player_reflect((cy - player2_pos) / PLAYER_SIZE * 3);
    new_ball_pos_x = ball_pos_x + ball_mov_x;
    new_ball_pos_y = ball_pos_y + ball_mov_y;
  }else if(new_ball_pos_x < PLAYER1_X + 0.5f){  // Behind player 1
    g_clear();
    g_draw_text(0, 0, "Player 2 won!");
    while(true)
      delay(1000);
  }else if(new_ball_pos_x > PLAYER2_X + 0.5f){  // Behind player 2
    g_clear();
    g_draw_text(0, 0, "Player 1 won!");
    while(true)
      delay(1000);
  }
  if(new_ball_pos_y < 0.5f || new_ball_pos_y > LCD_PIXEL_HEIGHT-0.5f){  // Hit horizontal wall
    tone(BUZZER, SOUND_FREQUENCY, SOUND_DURATION);
    ball_mov_y = -ball_mov_y;
    new_ball_pos_y = ball_pos_y + ball_mov_y;
  }
  if(floor(ball_pos_x) != floor(new_ball_pos_x) || floor(ball_pos_y) != floor(new_ball_pos_y))  // Ball changed displayed position
    change_action = true;
  ball_pos_x = new_ball_pos_x;
  ball_pos_y = new_ball_pos_y;
  // Draw entities if needed
  if(change_action){
    g_clear();
    g_add_vline(PLAYER1_X, player1_pos, PLAYER_SIZE);
    g_add_vline(PLAYER2_X, player2_pos, PLAYER_SIZE);
    g_add_dot(ball_pos_x, ball_pos_y);
    g_draw();
  }
  change_action = false;
  // Pause between updates (setting - calculations duration)
  delay(map(analogRead(POTENTIOMETER), 0, 1023, MAX_UPDATE_DELAY, MIN_UPDATE_DELAY) - (millis() - profile_start_time));
}

// Serial data ready callback (blocked by loop)
void serialEvent(void){
  const String input = Serial.readString();
  // Ball position cheat
  unsigned bposx, bposy;
  if(sscanf(input.c_str(), "BPOS %u %u", &bposx, &bposy) == 2) // Scanning floats don't work without special compiler options
    ball_pos_x = bposx, ball_pos_y = bposy;
  // Pause game
  else if(input.equals("PAUSE"))
    do
      delay(1000);
    while(!Serial.available() || Serial.readString().length() == 0);
  else
    Serial.println("Invalid input!");
}
  • 사진 :

 

  • 동작 내용에 대한 설명 : LCD에 보이는 작은 공이 좌우로 움직인다. 이때 두 명의 플레이어는 각자 2개의 스위치를 통해 LCD상의 바를 움직여서 공을 상대방에게로 뜅겨낸다. 먼저 공을 놓치는 쪽이 진다.

2. Copy of Race game

  • 아두이노 파일 :
#include <Wire.h> 
#include <LiquidCrystal.h>
#define inicio 16

// largura = 16;
// altura  = 2;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//Define os pinos ligados ao lcd

byte linhaDeChegada[8] = {
  0x1B,
  0x15,
  0x1B,
  0x15,
  0x1B,
  0x15,
  0x1B,
  0x15
};

uint8_t aviaoMal[8] = {
  0x00,
  0x0C,
  0x0D,
  0x1F,
  0x1F,
  0x0D,
  0x0C,
  0x00
};

uint8_t aviaoBom[8] = {
  0x00,
  0x06,
  0x16,
  0x1F,
  0x1F,
  0x16,
  0x06,
  0x00
};

int scroll1 = inicio, scroll2 = inicio + 11;
int botao1, botao2, tempo=400, vertical[5], k;
int count = 0, posicao = 0, enemyP[2];//enemyP é a posicao do inimigo

void setup(){//inicia lcd e botões
  lcd.begin(16,2);
  lcd.createChar(1, aviaoBom);
  lcd.createChar(2, aviaoMal);
  lcd.createChar(3, linhaDeChegada);

  lcd.home();
  pinMode(8,INPUT);
  pinMode(7,INPUT);  
}

void loop(){
  botao1=digitalRead(8);//vai para a esquerda
  botao2=digitalRead(7);//vai para a direita

  if(botao1){//se apertar o botão 1, vai para a posição 0 (direita)
    posicao = 0;
    //ant=0;
  }
  if(botao2){//se apertar o botão 1, vai para a posição 1 (esquerda)
    posicao = 1;
    //ant=1;
  }
  //else posicao=ant;

  //Carrinho jogador:
  lcd.setCursor(0, posicao);
  lcd.write(1);

  //Posicao inimigos:
  enemyP[0]=scroll1;
  enemyP[1]=scroll2;

  //Carrinhos inimigos:
  lcd.setCursor(enemyP[0], 0);
  lcd.write(2);
  vertical[0]=0;

  lcd.setCursor(enemyP[1], 1);
  lcd.write(2);
  vertical[1]=1;

  delay(tempo);

  for(k=0; k<2; k++){
    if(enemyP[k] == 0 && vertical[k] == posicao){
     lcd.clear();
     lcd.print("Game Over!");
     delay(5000);
     scroll1 = inicio;
     scroll2 = inicio+21;
     tempo = 450;
     count = 0;
    }
  }

  lcd.clear();

  if(scroll1 > 0){
    scroll1--;
    tempo = tempo - 2;
    }
  else{
    scroll1 = scroll2 + 15;
    count++;
  }
  if(scroll2 > 0){
    scroll2--;
    tempo--;
  }
  else{
    scroll2 = scroll1 + 15;
  }
  if(count >= 2){
    lcd.clear();
    scroll1 = inicio;
    tempo = 350;
    while(scroll1 > 0){
      lcd.clear();
      //Carrinho jogador:
      lcd.setCursor(0, posicao);
      lcd.write(1);

      //Linha de Chegada
      lcd.setCursor(scroll1, 0);
      lcd.write(3);
      lcd.setCursor(scroll1, 1);
      lcd.write(3);

      delay(tempo);
      scroll1--;
    }
    lcd.clear();
    lcd.write(' ');
    lcd.setCursor(2, 0);
    lcd.print("FINISH!!!");
    lcd.setCursor(2, 1);
    lcd.print("    :)    ");
    delay(5000);
    scroll1 = inicio;
    scroll2 = inicio + 11;
    tempo = 450;
    count = 0;
  }
}
  • 사진 :

  • 동작 내용에 대한 설명 : LCD 상에서 마주오는 비행기를 피하는 게임이다. 2개의 tact switch를 이용해 상하로 조작할 수 있다.

3. shooting game display

  • 아두이노 파일 :
#include <LiquidCrystal.h>
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

int time = 10;

const int buzzer = 13;

unsigned long prevMillis;
int count;
short int i;
int score = 0; 
short int generateNextNum = 0;
volatile int stage = 1;
short int ranNum = 0;

void setup(){
    Serial.begin(9600);
    lcd.begin(16, 2);
    pinMode(3, OUTPUT); 
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(buzzer, OUTPUT); // Set buzzer - pin 13 as an output
   // pinMode(2, INPUT_PULLUP);
    pinMode(2, INPUT);
    attachInterrupt(digitalPinToInterrupt(2), reset_routine, RISING);  
}

void reset_routine()             
{
    if(stage == 1)
    {
        stage = 2;
    } else 
    if(stage == 3)
    {
        generateNextNum = 1;
        digitalWrite(ranNum,LOW);
    } else 
    if(stage == 4)
    {
        stage = 1;        
    }
}

void welcome_routine()                       
{
    digitalWrite(3,HIGH);
    lcd.clear();    
    lcd.setCursor(0, 0);
    lcd.print("Welcome. Press");
    lcd.setCursor(0, 1);
    lcd.print("button to start.");
    while(stage == 1){}
}

void start_routine()                       
{
    lcd.clear();
    for(i=0; i<=2; i++)
    {
        for(int x=3; x<=6; x++)
        {
            digitalWrite(x,HIGH);
        }
        lcd.setCursor(0, 0);
        if(i==0){
            lcd.print("Get ready");
        }else if(i==1){
            lcd.print("Set");        
        }else if(i==2){

            lcd.print("GO");        
        }
        tone(buzzer, 500); // Send 1KHz sound signal...
        delay(500);
        noTone(buzzer); 
        lcd.clear();

        for(int x=3; x<=6; x++)
        {
            digitalWrite(x,LOW);
        }
        delay(500);            
    }
    lcd.clear();
    stage = 3;
    score = 0; 
    count = time;
    ranNum = 0;
}

void finish_routine()                       
{
    stage = 4;
    digitalWrite(ranNum,LOW);
    lcd.clear();
    tone(buzzer, 500); // Send 1KHz sound signal...
    delay(100);
    noTone(buzzer); 
    lcd.setCursor(0, 0);
    lcd.print("Game Over.");
    lcd.setCursor(0, 1);
    lcd.print("Score:");
    lcd.setCursor(10, 1);
    lcd.print(score);
    delay(3000);
    digitalWrite(3,HIGH);
    while(stage == 4){}
}

void loop(){

  welcome_routine();    
  start_routine();    
  prevMillis = millis();  

  lcd.setCursor(0, 0);
  lcd.print("Time:");
  lcd.setCursor(10, 0);
  lcd.print(count);

  lcd.setCursor(0, 1);
  lcd.print("Score:");
  lcd.setCursor(10, 1);
  lcd.print(score);
  char countString[] = "";

  while(count > 0){

        if(ranNum != 0) 
        {
            score = score + 1;
        }
        int ranNumOld = ranNum;
        while(ranNumOld == ranNum)
          {
            ranNum = random(3,7);
        }     
        digitalWrite(ranNum,HIGH);
        generateNextNum = 0;    


        while(generateNextNum == 0 && count > 0)
        {
            unsigned long curMillis = millis();

            if(curMillis - prevMillis >= 300)
            {
                count -= 1;
                //countString[] = count+" ";
                //lcd.clear();
                lcd.setCursor(0, 0);
                lcd.print("Time:");
                lcd.setCursor(10, 0);
                lcd.print(String(count)+" ");
                lcd.setCursor(0, 1);
                lcd.print("Score:");
                lcd.setCursor(10, 1);
                lcd.print(score);
                prevMillis = prevMillis +300;
            }
        } 
  }
  finish_routine();
}
  • 사진 :

  • 동작 내용에 대한 설명 : 주어진 Time안에 led 불이 들어온 스위치를 눌러야 한다. 누른 스위치의 개수만큼 score를 획득한다.

4. Higher&Lower Game

  • 아두이노 파일 :
#include <LiquidCrystal.h>

#define PIN_BUTTON 2
#define PIN_AUTOPLAY 1
#define PIN_READWRITE 10
#define PIN_CONTRAST 12

LiquidCrystal lcd(11, 9, 6, 5, 4, 3);

int answer;
int score;
boolean check = true;

void setup(){

  pinMode(PIN_READWRITE, OUTPUT);
  digitalWrite(PIN_READWRITE, LOW);
  pinMode(PIN_CONTRAST, OUTPUT);
  digitalWrite(PIN_CONTRAST, LOW);
  pinMode(PIN_BUTTON, INPUT);
  digitalWrite(PIN_BUTTON, HIGH);
  pinMode(PIN_AUTOPLAY, OUTPUT);
  digitalWrite(PIN_AUTOPLAY, HIGH);

  // Diital pin 2 maps to interrupt 0



  lcd.begin(16, 2);
  pinMode(A0,INPUT);
  pinMode(A1,INPUT);
  pinMode(A5,INPUT);



  while(check)
  {        lcd.setCursor(0,0);
         lcd.print("Your value:");
        lcd.print(analogRead(A0));          
           if (analogRead(A5)== 0)
        {
         lcd.clear();
         lcd.setCursor(0,0);
          lcd.print("Answer: "); 
           answer = analogRead(A0);
         lcd.print(answer);
         delay(2500);
         check = false;
        }
           delay(200);
           lcd.clear();
  }

}

void loop()

{ 
 int value;
 score = 0;
 check = true;
 lcd.setCursor(0,0);
 lcd.print("Game started");
 delay(2500);
 while (check)
 { 
   value = analogRead(A1);
   lcd.setCursor(0,0);
   lcd.print("Youe value: ");
   lcd.print(value);
   lcd.setCursor(13,1);
   lcd.print(score);
   lcd.setCursor(0,1);
   if (analogRead(A5) == 0)
   {
     score = score + 1;
     if (value < answer)
     {
       lcd.print("Lower");
       delay(500);
     }
     if (value > answer)
     {
       lcd.print("Higher");
       delay(500);
     }
     if (value == answer)
     {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Correct");
       lcd.setCursor(0,1);
       lcd.print("Your score: ");
       lcd.print(score);
       delay(5000);
       check = false;
     }
     while(analogRead(A5) == 0)
     {/*button hold protection*/}
   }
   delay(200);
   lcd.clear();      
 } 
}
  • 사진 :

  • 동작 내용에 대한 설명 : 좌측에 위치한 가변저항기로 선책한 0~1023사이의 숫자를 오른쪽 가변저항기로 맞추는 게임이다. 오른쪽 가변저항기로 값을 추측한 값을 입력하고 우측하단의 버튼을 누르면 정답인지 오답인지 알려준다. 오답인 경우 LCD에 표시된 시도횟수를 1만큼 상승하고 입력한 값이 정답과 비교해서 큰지 작은지 LCD에 표시한다. 정답인 경우 총 시도 횟수를 표시하고 게임을 종료한다.

5. Binary Game

  • 아두이노 파일 :
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

const int Pin0 = 6;  // Binary number 2^1 or 1
const int Pin1 = 5;  // Binary number 2^2 or 2
const int Pin2 = 4;  // Binary number 2^3 or 4
const int Pin3 = 3;  // Binary number 2^4 or 8
const int Pin4 = A4; // Binary number 2^5 or 16
const int Pin5 = A3; // Binary number 2^6 or 32
const int Pin6 = A2; // Binary number 2^7 or 64
const int Pin7 = A1; // Binary number 2^8 or 128
const int easyMode = A0; // Easy mode is 0-15, Hard is 0-255

int BinaryValue; // Value for adding up numbers to compare to random number

int correctNumber = 0; // Flag to see if the number was correct
int wrongNumber = 0; // Flag to see if the number was wrong

const int buzzer = 13; //Buzzer pin
int freq; //frequency out

const int buttonPin = 2;     // the number of the pushbutton pin

int buttonState;         // variable for reading the pushbutton status
long randNumber;         // variable for the random number

void setup() {

  lcd.begin(16, 2); // set up the LCD's number of columns and rows

  pinMode(Pin0, INPUT_PULLUP);
  pinMode(Pin1, INPUT_PULLUP);
  pinMode(Pin2, INPUT_PULLUP);
  pinMode(Pin3, INPUT_PULLUP);
  pinMode(Pin4, INPUT_PULLUP);
  pinMode(Pin5, INPUT_PULLUP);
  pinMode(Pin6, INPUT_PULLUP);
  pinMode(Pin7, INPUT_PULLUP);

  pinMode(easyMode, INPUT_PULLUP);

  pinMode(buttonPin, INPUT_PULLUP);

  pinMode(buzzer, OUTPUT); // Set buzzer pin as OUTPUT

  // if analog input pin 5 is unconnected, random analog
  // noise will cause the call to randomSeed() to generate
  // different seed numbers each time the sketch runs.
  // randomSeed() will then shuffle the random function.
  randomSeed(analogRead(5));

  if (digitalRead(easyMode) == HIGH)
  {
    randNumber = random(0, 15);
  }
  else
  {
    randNumber = random(0, 255);
  }

  // Print a message to the LCD.
  lcd.print("Your number is");

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);

  lcd.print(randNumber); // Print the random number

}

void checkNumber() // Check switches for correct number
{
  if (digitalRead(Pin0) == HIGH)
  {
    BinaryValue = 1;
  }
  else
  {
    BinaryValue = 0;
  }

  if (digitalRead(Pin1) == HIGH)
  {
    BinaryValue = BinaryValue + 2;
  }

  if (digitalRead(Pin2) == HIGH)
  {
    BinaryValue = BinaryValue + 4;
  }

  if (digitalRead(Pin3) == HIGH)
  {
    BinaryValue = BinaryValue + 8;
  }

  if (digitalRead(Pin4) == HIGH)
  {
    BinaryValue = BinaryValue + 16;
  }

  if (digitalRead(Pin5) == HIGH)
  {
    BinaryValue = BinaryValue + 32;
  }

  if (digitalRead(Pin6) == HIGH)
  {
    BinaryValue = BinaryValue + 64;
  }

  if (digitalRead(Pin7) == HIGH)
  {
    BinaryValue = BinaryValue + 128;
  }

  if (BinaryValue == randNumber) // Check if switches match random number
  {
    correctNumber = 1;
  }
  else
  {
    wrongNumber = 1;
  }

}

void printBinary() // Displays status of switches
{
  if (digitalRead(Pin7) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }

  if (digitalRead(Pin6) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  if (digitalRead(Pin5) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  if (digitalRead(Pin4) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  lcd.print(" ");
  if (digitalRead(Pin3) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  if (digitalRead(Pin2) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  if (digitalRead(Pin1) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
  if (digitalRead(Pin0) == LOW)
  {
    lcd.print("0");
  }
  else
  {
    lcd.print("1");
  }
}

void loop() {

  attachInterrupt(digitalPinToInterrupt(buttonPin), checkNumber, FALLING); // Wait for pushbutton to be pressed, when pressed check to see if correct number is inputted

  lcd.setCursor(7, 1);

  printBinary(); // Display status of switches

  if (wrongNumber == 1)
  {

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Try again");
    lcd.setCursor(0, 1);
    lcd.print(randNumber);
    tone(buzzer, 200); // Play wrong answer tone
    delay(400);        
    noTone(buzzer);     // Stop sound...
    wrongNumber = 0;
    correctNumber = 0;
  }

  if (correctNumber == 1)
  {
    tone(buzzer, 600); // Play correct answer tone
    delay(100);       
    tone(buzzer, 1000); 
    delay(100);        
    tone(buzzer, 800); 
    delay(100);        
    noTone(buzzer);     // Stop sound...
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Correct!");
    lcd.setCursor(0, 1);
    lcd.print(randNumber);
    lcd.print(" is ");

    printBinary(); // Display status of switches

    delay(3000);       

    lcd.clear();
    lcd.setCursor(0, 0);
    // Print a message to the LCD.
    lcd.print("Your number is");
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);

    if (digitalRead(easyMode) == HIGH)
    {
      randNumber = random(0, 15);
    }
    else
    {
      randNumber = random(0, 255);
    }

    lcd.print(randNumber);

    correctNumber = 0;
    wrongNumber = 0;
  }
}
  • 사진 :

  • 동작 내용에 대한 설명 : 주어진 십진수 숫자를 2진수로 변환하는 게임이다. 슬라이드 스위치를 끄고 켜는 것으로 1과 0을 표현할 수 있다. 원하는 2진수를 표현했다면 tact 스위치를 눌러서 정답인지 확인한다.

'학부 강의 > Arduino' 카테고리의 다른 글

2022-06-22 팀프로젝트_리듬스타  (0) 2022.06.22
2022-05-27 Arduino_13  (0) 2022.05.27
2022-05-21 Arduino_11  (0) 2022.05.21
2022-05-17 Arduino_10  (0) 2022.05.17
2022-05-12 Arduino_9  (0) 2022.05.12