【Arduino】LED打地鼠

【Arduino】LED打地鼠

小時候會玩打地鼠的遊戲機,地鼠會隨機從洞裡跑出來,看到地鼠跑出來就用槌子去打,是一個考驗反應的小遊戲。

而這次來用LED跟按鈕來模擬打地鼠的遊戲,LED會隨機亮起,表示地鼠出現,透過按下對應按鈕來讓LED滅掉,成功的話分數就會加1。

這個項目也可以延伸到反應訓練燈,是用來訓練運動員的工具,有興趣的朋友也可以去查訊看看。

LED打地鼠影片

線路連接

在這裡會需要用到”按鈕開關”以及”LCD”,若是還沒有使用過,可以去參考下列文章哦~

【Arduino】LCD I2C模組使用教學

Arduino 按鈕控制LED

程式說明

首先要先弄出LED隨機閃爍

我現在有5個LED,並且希望能夠隨機亮起三個燈,所以我要先亂數生出1~5且不重複的三個數字

找資料的過程中,發現了這個教學影片!!!

根據影片的亂數產生方式,我們再另外加工一下~

把LED腳位等等先設置好,再利用millis()的寫法來固定時間產生一組亂數,並將亂數產生的ledPin來點亮。

就會變成下面的程式啦~

**這裡要注意random(5)實際上只會隨機產生0~4的數字,請參考random()

int ledPin[]={12,11,10,9,8};
unsigned long time_now;
int i,j;
int n[5]={};

void setup() {
   for(int i=0;i<5;i++){
    pinMode(ledPin[i], OUTPUT);
  }
  
  for(int i=0;i<5;i++){
    digitalWrite(ledPin[i],LOW);
  }

  time_now=millis();
  
}

void loop() {
  //改變time_now後面加的時間,就可以改變閃爍的頻率
  if(millis()>=time_now+1500){
    for(int i=0;i<5;i++){
      digitalWrite(ledPin[i],LOW);
    }
    time_now=millis();
    for(i=0; i<3; i++){
      do{
        n[i]=random(5);
        for(j=0; j<i; j++){
          if(n[i]==n[j]){
            break;
          }
        }      
      }while(j!=i);
      digitalWrite(ledPin[n[i]],HIGH);
    }
    
  }

}

按下按鈕讓對應的LED熄滅,並累加分數

從上述的程式中,我們可以知道n[5]這個陣列中會存入3個隨機亂數,實際上會從0~4隨機選3個,這代表著陣列中的位置。

ledPin[]、ButtonPin[],位置對應的表格如下:

ledPin[]12111098
ButtonPin[]76543
陣列位置[0][1][2][3][4]

假設當亂數選完後,我得到的n[0]=3, n[1]=1, n[2]=4,我只需要去檢查ButtonPin[3], ButtonPin[1], ButtonPin[4]這三個按鈕是否有被按下就可,若被按下則讓對應的led關閉並且分數+1。

最後再加入LCD來顯示分數。

  //檢查選取到的LED對應按鈕是否被按下,若被按下則分數加1
  for(i=0;i<3;i++){
    if(digitalRead(ButtonPin[n[i]])==LOW&&ledState[i]==HIGH){
      digitalWrite(ledPin[n[i]],LOW);
      ledState[i]=LOW; 
      score++; 
    }
  }

  //將分數顯示在LCD上
  Serial.println(score);
  lcd.setCursor(2, 0); // 從第一排的第三個位置開始顯示
  lcd.print("score:");
  lcd.print(score); 

完整程式碼

#include <Wire.h> // I2C程式庫
#include <LiquidCrystal_I2C.h> // LCD_I2C模組程式庫
// LCD I2C位址,默認為0x27或0x3F,依據背板的晶片不同而有差異,16、2為LCD顯示器大小。
LiquidCrystal_I2C lcd(0x27, 16, 2); 

int ledPin[]={12,11,10,9,8};
int ButtonPin[]={7,6,5,4,3};
boolean ledState[]={0,0,0,0,0};
int n[5]={};
unsigned long time_now;
int i,j;
int score=0;


void setup() {
  // 初始化LCD
  lcd.init();
  lcd.backlight();
  
  Serial.begin(9600);
  
  for(int i=0;i<5;i++){
    pinMode(ledPin[i], OUTPUT);
    pinMode(ButtonPin[i], INPUT_PULLUP);
  }
  
  for(int i=0;i<5;i++){
    digitalWrite(ledPin[i],LOW);
  }
  
  time_now=millis();
}


void loop() {
  //每1500ms執行一次
  if(millis()>=time_now+1500){
    
    //先將所有LED關閉
    for(i=0;i<5;i++){
      digitalWrite(ledPin[i],LOW);
    }
    
    time_now=millis();
    
    //執行亂數選取,並將選取到的LED點亮
    for(i=0; i<3; i++){
      do{
        n[i]=random(5);
        for(j=0; j<i; j++){
          if(n[i]==n[j]){
            break;
          }
        }      
      }while(j!=i);
      digitalWrite(ledPin[n[i]],HIGH);
      ledState[i]=HIGH;
    }
  }

  //檢查選取到的LED對應按鈕是否被按下,若被按下則分數加1
  for(i=0;i<3;i++){
    if(digitalRead(ButtonPin[n[i]])==LOW&&ledState[i]==HIGH){
      digitalWrite(ledPin[n[i]],LOW);
      ledState[i]=LOW;
      score++;
    }
  }

  //將分數顯示在LCD上
  Serial.println(score);
  lcd.setCursor(2, 0); // 從第一排的第三個位置開始顯示
  lcd.print("score:");
  lcd.print(score); 
 
  
}

網上相關作品影片

打地鼠PK遊戲機

反應訓練燈

最後!! 你喜歡這篇文章,或是這篇文章對你有幫助的話,也歡迎分享出去給需要的人,訂閱免費電子報獲得最新資訊😄😄😄

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *