Westernduino, create a game with arduino


Today we gonna to create a game with arduino, a shoot game call Westernduino !

I participate to a challenge call “challenge des makers” ( french website http://ouiaremakers.com/ ) and i create a game and now all step for realise it.
If you like french you can see my french website http://retroetgeek.com/
And sorry for my bad english !

// PIN
int cible0=A0;
int cible1=A1;
int cible2=A2;
int pinServo1 = 5;
int pinServo2 = 6;
int pinServo3 = 7;
int pinBoutonStart = 8;
int pinBuzzer = 9;

// variable moyenne capteur lumiere
int moyennecible0=0;
int moyennecible1=0;
int moyennecible2=0;

// tableau pour savoir quelle cible est levee et peut etre toucher
int cibleCapteur[]={0,0,0};

int i = 0;
int start = 0;

// ronud de jeu tableau multi { temps en ms , numero servo , angle en degre } 15 pour plat et 90 pour levé , ajout valeur hors cadre a la fin
int round1[ ][ 3 ] = { { 1000, 0, 90 }, { 4000, 0, 15 } ,{ 4000, 2, 90 },{ 7000, 2, 15 },{ 7000, 1, 90 },{ 10000, 1, 15 },{ 11000, 0, 90 },{ 11000, 2, 90 },{ 14000, 0, 15 },{ 14000, 2, 15 },{ 15000, 1, 90 },{ 16000, 2, 90 },{ 18000, 1, 15 },{ 19000, 2, 15 },{ 20000, 2, 90 },{ 21000, 1, 90 },{ 22000, 0, 90 },{ 29000, 2, 15 },{ 29000, 1, 15 },{ 29000, 0, 15 },{ 61000, 0, 15 } };
int round2[ ][ 3 ] = { { 1000, 0, 90 },{ 3000, 1, 90 },{ 3000, 0, 15 },{ 5000, 1, 15 },{ 7000, 2, 90 },{ 7000, 0, 90 },{ 10000, 2, 15 },{ 10000, 0, 15 },{ 12000, 1, 90 },{ 13000, 0, 90 },{ 14000, 2, 90 },{ 15000, 1, 15 },{ 16000, 0, 15 },{ 17000, 2, 15 },{ 18000, 2, 90 },{ 19000, 1, 90 },{ 20000, 0, 90 },{ 20000, 2, 15 },{ 21000, 1, 15 },{ 22000, 0, 15 },{ 22000, 1, 90 },{ 23000, 0, 90 },{ 24000, 2, 90 },{ 29000, 0, 15 },{ 29000, 1, 15 },{ 29000, 2, 15 },{ 61000, 0, 15 } };
// temps des round , premier a 0 car se base sur la variable start ( start = 0 a l'init ) 
int tempsRound[]= {0,30000,30000};

// temps et step pour les sequences
long tempsdebut = 0;
long stepSequence = 0;

// points 
int points = 0;
int pointsManche = 0;

#include "pitches.h"
#include < Servo.h >

Servo monServo0;
Servo monServo1;
Servo monServo2;
Servo mesServos[]={monServo0,monServo1,monServo2};

// variable pour jouer les melodies
int numeroMelody = 0;
int numeroNote = 0;
int numeroNoteBefore = 9;
long tempsMelody = 0;
long pauseNotes;
bool boolMelody = 1;

// 2 melodies
int melody[][37] = {{
  NOTE_E4, NOTE_A4, NOTE_E4, NOTE_A4, NOTE_E4, NOTE_C4, NOTE_D4,NOTE_A3 ,0 
  ,NOTE_E4, NOTE_A4, NOTE_E4, NOTE_A4, NOTE_E4, NOTE_C4, NOTE_D4,NOTE_G4,0,
  NOTE_E4,NOTE_A4, NOTE_E4, NOTE_A4,NOTE_A4,NOTE_C5,NOTE_B4,NOTE_A4,NOTE_G4,0 
  ,NOTE_E4, NOTE_A4, NOTE_E4, NOTE_A4, NOTE_E4,0,NOTE_D4,NOTE_A3,NOTE_A3
},
{NOTE_E3,NOTE_A3,NOTE_E4,NOTE_C4,NOTE_G4,NOTE_G4,0}
}
;
// duree des notes des melodies
int noteDurations[][37] = {{
  16, 16, 16, 16, 2, 4, 4, 2,2 ,16, 16, 16, 16, 2, 4, 4, 2,2  ,16, 16, 16, 16,2,4,8,8,2,2,16,16,16,16,4,4,4,8,1
},{8,8,8,8,8,2,999} };



void setup() {

  Serial.begin(9600);
  pinMode(cible0,INPUT);
  pinMode(cible1,INPUT);
  pinMode(cible2,INPUT);  
  pinMode(pinBoutonStart,INPUT);

  // attacher les servos a leur pins
  unlockServos();

  delay(1000);
  // detache les servos de leur pins
  lockServos();

  // initialise les variables moyenne pour les capteur de luminosité
  //initSensorLight();
}

void loop() {

  // demarrer le jeu ?
  if(digitalRead(pinBoutonStart) == HIGH){
    start = 1;
    stopMusique();
    points = 0;
    
  }


  switch (start) {
    case 1:
    // round 1
        demarrerRound(tempsRound[start],round1);
      break;
    case 2:
    // round 2
        delay(2000);
        demarrerRound(tempsRound[start],round2);
      break;
    default: 
      // joue la melodie toutes les 60 scondes si le jeu n'est pas lancé
      if(millis() > tempsMelody+60000 ){
        numeroMelody=0;
        boolMelody = 1;
        numeroNote = 0;
        numeroNoteBefore = 9;       
      }
      // appelle jouer de la musique     
      jouerMusique();
    break;
  }

}


// initialisation des capteurs de lumiere pour capter le laser en phase de jeu
void initSensorLight(){
  int totalCible=0;
  //for each sensor catch 10 value for better aim
  for (i=0;i<10;i++) {
    totalCible+=analogRead(cible0);
  }
  moyennecible0=totalCible/10;
  totalCible=0;
  //for each sensor catch 10 value for better aim
  for (i=0;i<10;i++) {
    totalCible+=analogRead(cible1);
  }
  moyennecible1=totalCible/10;
  totalCible=0;
  //for each sensor catch 10 value for better aim
  for (i=0;i<10;i++) {
    totalCible+=analogRead(cible2);
  }
  moyennecible2=totalCible/10;
  totalCible=0; 

}


// avant de demarrer le jeu
void preStart(){
  
  pointsManche = 0;
  initSensorLight();
  
  Serial.println("3");
  tone(pinBuzzer,NOTE_FS4, 500);
  delay(1000);
  Serial.println("2");
  tone(pinBuzzer,NOTE_FS4, 500);
  delay(1000);
  Serial.println("1");
  tone(pinBuzzer,NOTE_FS4, 500);
  delay(1000);
  tone(pinBuzzer,NOTE_F5, 500);
}

// detacher les servo pour eviter les tremblements
void lockServos(){
  monServo0.detach();
  monServo1.detach();
  monServo2.detach();  
}
// attacher les servo pour les utiliser
void unlockServos(){
  monServo0.attach(pinServo1);
  monServo1.attach(pinServo2);
  monServo2.attach(pinServo3);
    
  monServo0.write(15);
  monServo1.write(15);
  monServo2.write(15);
}

// affiche le score de la manche( pour la v2 ) et jouer musique
void scoreManche(){

int tempsScore = millis ();
numeroMelody=1;
boolMelody = 1;
numeroNote = 0;
numeroNoteBefore = 9;
while(jouerMusique()== true){
   
}
// on joue la meoldie fin du stage

  Serial.print("Score Manche ");
  Serial.println(pointsManche);
  
}


// fonction qui gere les position des cible et les shots, an parametre le temps du round et le tableau des positions des servos 
void demarrerRound(int tempsTempo,int tempoRound[][3]){
  
      unlockServos();
      preStart();
      tempsdebut=millis();
      stepSequence = 0;
      while((millis()-tempsdebut) < tempsTempo){
        if(( millis() - tempsdebut ) >= tempoRound[ stepSequence ][ 0 ]){   
            
          mesServos[tempoRound[ stepSequence ][1]].write(tempoRound[ stepSequence ][2]);
          
          // autoriser un tir sur cible si valeur degré >89 ok pour cible sinon desactivé
          if(tempoRound[ stepSequence ][2]> 89){
            cibleCapteur[tempoRound[ stepSequence ][1]]=1;
          }
          else{
            cibleCapteur[tempoRound[ stepSequence ][1]]=0;
          }
          
          stepSequence++;
        }
        
        // sequence pour receptionner les signaux
        if(cibleCapteur[0] == 1 ){
            if(analogRead(cible0)> moyennecible0 + 50){
                monServo0.write(15); 
                pointsManche++;
                  // init cible pour eviter plusieurs tirs et points
                cibleCapteur[0] = 0;
                Serial.println(" Cible 0 Touche");
                tone(pinBuzzer,NOTE_DS8, 500);                
            }
        }

        if(cibleCapteur[1] == 1 ){
            if(analogRead(cible1)> moyennecible1 + 50){
                monServo1.write(15); 
                pointsManche++;
                  // init cible pour eviter plusieurs tirs et points
                cibleCapteur[1] = 0;
                Serial.println(" Cible 1 Touche");
                tone(pinBuzzer,NOTE_DS8, 500); 
            }
        }

        if(cibleCapteur[2] == 1 ){
            if(analogRead(cible2)> moyennecible2 + 50){
                monServo2.write(15); 
                pointsManche++;
                  // init cible pour eviter plusieurs tirs et points
                cibleCapteur[2] = 0;
              Serial.println("Cible 2 Touche");
              tone(pinBuzzer,NOTE_DS8, 500); 
            }
        }

        
      }
      
      start++;
      lockServos();
      scoreManche(); 

}

// fonction jouer de la musique pour jouer le theme hors jeu et pendant les phases de score
bool jouerMusique(){

  if( boolMelody == 1 ){


  // depart du temps de reference de la melodie au temps 0
        if(numeroNote == 0){
          tempsMelody=millis();
        }

          // durée de la note en cours
        int noteDuration = 1000 / noteDurations[numeroMelody][numeroNote];

        if(numeroNote != numeroNoteBefore){
            numeroNoteBefore=numeroNote;     
            tone(pinBuzzer, melody[numeroMelody][numeroNote], noteDuration);
  
        // ici on calcule le temps qu'il faut avant de passer a la step suivante ( note suivante )
        pauseNotes = (noteDuration * 1.30) ;
        pauseNotes+=tempsMelody;

        }
  
        if(millis() >= pauseNotes){
            numeroNote+=1;
            tempsMelody=millis();
        }
        if(numeroNote >= (sizeof(noteDurations[numeroMelody])/sizeof(int)) || noteDurations[numeroMelody][numeroNote] == 999 ){
           boolMelody = 0;
           numeroNote = 0;
           numeroMelody = 0;
           numeroNoteBefore = 9;
           noTone(pinBuzzer);
           return false;
        }
  }  
  return true;
}

// arrete la musique
void stopMusique(){
  boolMelody = 0;
  numeroNote = 0;
  numeroMelody = 0;
}

What we need :
– 2 arduino ( mini pro 5v)
– 3 voltage regulator 5 V L7805
– 6 capacitor 25v 10μF
– 1 capacitor 16V 470μF
– 3 resistor 1kΩ
– 3 resistor 220Ω
– 3 photoresistor
– 2 buttons
– 3 servo 9g S90
– 1 buzzer
– 1 transistor TIP120
– 1 laser module 5V
– 1 power supply 12V
– 1 battery 9v
– wires

Circuit for target
– A0 A1 A2 , pin for photoresistor
– 5,6,7, pin for servo
– 8 pin for Start button
– 9 pin for buzzer
Circuit for gun
– 3 pin for shoot button
– 4 pin for transistor tip120

Let’s see the circuit diagram.
For the target you need a power supply 12V minimum 1A ( recommended 2A, I will add later matrix led ).
We convert 12V in 5V with voltage regulator L7805, I put 2 regulator because servo need power.
I add some capacitor 25v 10μF for regulate voltage.
For start button I use pull down system and it connected to pin 8.
Buzzer is connected to pin 9.
One part of photoresistor is connected to 5v and other is connected to pin A0 to pin A2 and connected to ground with resistor ( 220Ω ).
WARNING arduino mini pro are 5v or 3.3V they dont have Vin you need to supply the with required voltage here 5V (I use 5v arduino) !

For the gun we use voltage regulator and we got a 5V.
The button is in pull down and connected to pin 3 .
On pin 4 I connect resistor 1kΩ to the transistor TIP120 and connect laser to 5V.

Now the code !

Code for target (on right)
In the beginning i define pin for target, servo, button and buzzer .
I use some variable for the average of my photoresistor, an array to control witch target is up and some other vaviable.
Round are array where the command for the servo are, it is the sequence for the game.
Three information inside, time in ms, number of servo, angle for the servo .
In tempsRound i put duration for each round ( first is 0, not used ).
And some variable of time for the game, we will use later.

I dont use point in game actually, I count them but not used for V1.
We included 2 library, one for notes and one for servo
I call my servo and put the in an array.

You find different variable for play melody, an array multidimensionnal contain actually 2 melody and you have an array with note.

Part setup I define pin in input .
The function unlockServos is for attach servo and ini them down.
LockServos detach servo because low quality servo jitter.
initSensorLight is commented in setup because we will use it in every start of game.

Part loop I check start button for start the game when it is HIGH position and I define start to 1, point goes to 0 and i stop music if it play.
The switch is for the round choice, when start value is to 1 we start round 1, start=2 round 2 and default for play music when we don’t play.

Let see function , initSensorLight  for made an average value of the sensor target , we got 10 value of each photoresistor and we create an average for a better laser detection.

Function preStart, init score of round to 0, call initSensorLight and countdown before launch the round.

Other function scoreManche in the end of game sequence, play a melody and show score.

Function demarrerRound is the most important, here the heart of game, you call it with some values.
I unlock servo with unlockServos and I preStart to lauch the countdown.
I have a loop during auu the time of round,I will activate all action during time and move servo and control value of sensor. When servo go up, I will activate sensor and deactivates it when servo is down.
I control my different targent when they are activated and check if value is superior thant the average value + 50 .
When a target is shootit goes down, a ringing bip and score +1 point.
When my loop is over I increase start value for next sequence, I detach my servo and I call scoreManche.

Another function now for play music with jouerMusique , function return true or false when music is over.
boolMelody is a boolean for play music ,my function jouerMusique use time for not and not delay like that my arduino can continue to do other things
If one note duration is equal to 999 the melody is over, because I use 2 melody and one is shorter than other.
And last function for stop music is stopMusique.

Code for gun (under)
Like code for target we ini pin for our arduino, the button for shoot and pin to command laser.
After some variable to prevent laser stay on, we use tempsLaser and tempsPause for duration of laser and time between new shoot.
In setup part we init button in INPUT and laser in OUTPUT .
In loop I have a condition for control is my button is down and mulsiShoot is more than 2 (prevent multishoot). When my button is up I increase multiShoot and it need to be more than 3 for a new shoot.
Last condition activate or not laser during a time and turn off.

 



int pinBouton = 3;
int pinLaser = 4;

bool shootLaser = 0;
int multiShoot = 2;

long tempsLaser = 500;
long tempsPause = 100 ;


void setup() {
  pinMode(pinBouton,INPUT);
  pinMode(pinLaser,OUTPUT);
}

void loop() {
  if(digitalRead(pinBouton) == HIGH && multiShoot > 2){
    shootLaser = 1;
    multiShoot = 0;
  }
  else if(digitalRead(pinBouton) == LOW){
    shootLaser = 0;
    if(multiShoot < 3 ){
      multiShoot++;
    }
  }

  if(shootLaser == 1 ){
    digitalWrite(pinLaser,HIGH);
    delay(tempsLaser);
    digitalWrite(pinLaser,LOW);
    delay(tempsPause); 
    multiShoot = 0;
    shootLaser = 0;
  }

}
 
Part of code is over, it is heavy to explain but I hope you understand the essential ( it is a french translation, english is not my birth language ).
I give you code to realise your own westernduino, you can add round and do what you want with code.

Download codeWesternduino_V1

How to make it :

I use wood for base and hot glue for servo, for target i use some ice cream stick and glue photoresistor. And i use foam bord for the cowboy.
I will make a better look for version 2.

Download cowboys :

I buy the gun in a costume shop, i choose a gun with an empty space inside for electronic parts.

If you want to create this game find your material, there are a lot of way to create your own.

 

Now is your turn, share your game with the community with hashtag #westernduino.
Share the video if you think it might interest someone, because it take time to create a game so why not to be used by a maximum.
I create this game for a challenge of website ouiaremakers.com (french website) .

You can follow me on instagramtwitter , facebook ,youtube ;
You can follow me on my main channel and website but in french RetroetGeek.com and my channel
Thank you


 

bulbcleanIdea

noun
1. any conception existing in the mind as a result of mental understanding, awareness, or activity.
2. a thought, conception, or notion:

rocketcleanCrazy

adjective, crazier, craziest.
1. mentally deranged; demented; insane.
2. Informal. unusual; bizarre; singular
3. Slang. wonderful; excellent; perfect

ciblecleanAchieve

verb, achieved, achieving.
1. to bring to a successful end; carry through; accomplish
2. to get or attain by effort; gain; obtain

” When I was a child, I made things with what I had in my hand.
Now I’ve grown a lot and decided to make my childhood dreams come true.
I imagine and make objects, concepts, whether technological or not.
You have a project ? An idea ? Let’s work together to make it happen! “
For professionnal contact, complete the form.
Language spoken : english, french, other ( google translate 😉 )