Let’s play, daddy – Family Feud

I was inspired by a simple DIY game seen on the web (I can’t find the link now) and despite the fact that original version was based on greatly simpler PIC I decided to build it with Arduino Starter Kit.

The rules are simple – the one, who will press his button faster after a diode lights up, gets a score. If the button will be pressed before the diode lights up, a point goes to opponent. The game continues, until someone gets five points. Let’s see it in action:

Simple game with Arduino from Starter Kit on Vimeo.

Beside the diode, which will be watched, we need also two diodes to indicate who gets the point and who has won the whole duel, buzzer to play simple melody at the end of the game and two buttons.

Here is connection scheme designed in Fritzing (the colors of wires changed only to increase readability):

Family Feud - connection scheme
Family Feud - connection scheme

Here is photo of real circuit, because the details aren’t visible on the movie:

Physical connection on a breadboard
Physical connection on a breadboard

The scheme generated in Fritzing differs from the real construction in a few points:

  • resistors connected to diodes indicating the winner are connected directly to cathode and ground, without any additional wires
  • ground is directed to switches using cutted off terminals from other resistors – such a short wires are perfectly suitable for making jumpers

This time – buttons connected without resistors. Why? Someone asked me out in comment, Arduino (ATmega328) has pull-up resistors included in digital inputs. The only thing we have to do is turning it on in setup procedure using the following sequence:

  pinMode(playerA, INPUT);
  digitalWrite(playerA, HIGH);

what stands for defining the pin as input and setting it in high state. Such a sequence turns the internal pull-up resistor on and now we can connect a button directly to digital input.

The application consists of setup section and a loop loop (as usual). In the loop we are lighting the diode up in a random way. Next, we check if someone has pressed the button. Depending on state of the diode (lighted or not) a point is granted to winner. Afterwards, buzzer and flashing diode indicates the winner and the number of wins (held in total_wins table) is increased, and then check_winner, which checks if someone has already five points, is evoked. In case he has, winner_total plays melody known from article about buzzer) and flashes the diode. Game over and we play again.

The code:

int outLED = 4;
int playerA = 2;
int playerB = 3;
int aLED = 5;
int bLED = 6;
int st = LOW;
int total_wins[] = {0,0};

int speakerPin = 11;
int length = 15; // the number of notes
char notes[] = "ccggaagffeeddc "; // a space represents a rest
char champs[] = "fadbc";
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 150;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

void flashLED(int no) {
  digitalWrite(no, !digitalRead(no) );
}

void winner(int pl) {
    int tempo = 400;
    digitalWrite(pl+aLED, HIGH);
    for (int i = 0; i < 2; i++) {

      playTone(1600 , tempo);

    // pause between notes
    }
    st = LOW;
    digitalWrite(pl+aLED, LOW);
    digitalWrite(outLED, st);
    delay(500);
    total_wins[pl]++;
    check_winner();
}

void check_winner() {
 if(total_wins[0] >= 5) {
   total_wins[0]=0;
   total_wins[1]=0;
   winner_total(0);
 }
 if(total_wins[1] >= 5) {
   total_wins[0]=0;
   total_wins[1]=0;
   winner_total(1);
 }

}
void winner_total(int pl) {
    for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
      delay(beats[i] * tempo); // rest
    } else {
      playNote(notes[i], beats[i] * tempo);
      flashLED(pl+aLED);
    }

    // pause between notes
    delay(tempo / 2);
    }
 //   st = LOW;
  //  digitalWrite(outLED, st);
//    delay(500);

};

void setup () {
  pinMode(outLED, OUTPUT);
  pinMode(speakerPin, OUTPUT);
  pinMode(aLED, OUTPUT);
  pinMode(bLED, OUTPUT);
  digitalWrite(outLED, HIGH);
  pinMode(playerA, INPUT);
  digitalWrite(playerA, HIGH);
  pinMode(playerB, INPUT);
  digitalWrite(playerB, HIGH);

  Serial.begin(9600);
};

void loop(){
  if (random(2000) < 1) {
    st = HIGH;
    digitalWrite(outLED, st);
  }
  if (st == HIGH) {
    if(digitalRead(playerA) == LOW) {
      Serial.println("A!!!!!!!!");
      winner(0);

    }
    if(digitalRead(playerB) == LOW) {
      Serial.println("B!!!!!!!!");
      winner(1);

    }
  } else {
    if(digitalRead(playerB) == LOW) {
      winner(0);
    }
    if(digitalRead(playerA) == LOW) {
      winner(1);
    }
  }

  delay(1);

};

Part list (all included in Starter Kit):

Arduino1      Arduino Diecimila
Breadboard1   Generic Bajillion Hole Breadboard
J1            Piezo Speaker
LED1          Red LED - 5mm
LED1          Red LED - 5mm
LED1          Red LED - 5mm
R1            270Ω Resistor
R1            270Ω Resistor
R1            270Ω Resistor
R1            270Ω Resistor
S1            Pushbutton
S1            Pushbutton

Shopping List

Quantity	Part

4		270 Ω Resistor
1		Arduino Diecimila
1		Generic Bajillion Hole Breadboard
1		Piezo Speaker
2		Pushbutton
3		Red LED

Of course Starter Kitu contains Arduino Duemilanove, not Diecimila (previous model) Fritzing stubbornly has Diecimila in the kit. Instead of speaker we are using a buzzer.