Portal Gun

Je m'attaque à un gros projet : un Portal Gun. Je souhaite le fabriquer à taille réelle, ainsi que de lui faire émettre la lumière bleu ou orange, et les sons associés.
Pour émettre les sons, j'utilise un module SOMO II qui a besoin d'une carte micro SD, d'une alimentation 5V et d'un petit haut-parleur.

Une fois les composants achetés, j'ai regardé pour utiliser plus de son que juste les 2 sons du Portal Gun, et je me suis mis dans la tête de faire la "potato Glados" en supplément et qu'elle parle comme dans le jeu.
Il faut donc que je crée une connexion entre le module SOMO II et un arduino pour envoyer les ordres sonores.
Je rajoute un potentiomètre relié à l'arduino pour contrôler la puissance du son.

Résultat, je souhaite avoir un module arduino qui contrôle les LED orange et bleu, et qui envoie les informations sonores au SOMO II par une liaison série.

Au début, aucune LED allumé.J’appuie sur le bouton poussoir gauche, la LED Bleu s'allume, et le son "Bleu" est émis. Que la LED bleu, la LED orange doit être éteinte.J'appuie sur le bouton poussoir droit, la LED orange s'allume, et le son "Orange" est émis. Que la LED orange, la LED bleu doit être éteinte.La puissance sonore doit varier en fonction du potentiomètre.Toutes les 60 a 180s, un message aléatoire de Glados patate doit être émis (tempo aléatoire à redéfinir à chaque émission d'un message Glados"
Pas besoin d'attendre un message retour sur le port série (si le message n'est pas bien recu, ce n'est pas important).


MAJ du 20/01/2017 : J'ai fini le programme, il fonctionne exactement comme je le souhaitais, mais je rajouterais peut-être quelques fonctions, à voir.
#include 
// declaration des constantes pour les nom des broches ; selon le schema
const int btn_gauche = 2;
const int btn_droit = 3;
const int led_bleu = 10;
const int led_orange = 11;
const int btn_glados = 7;
const int Rx_pin = 4;
const int Tx_pin = 5;
// le potentiometre, branche sur la broche analogique 0
const int potar = 0;
// nombre de pistes audio de Glados -- A MODIFIER --
const int nombre_pistes = 20;

// declaration des variables utilisees

//variable pour stocker la valeur lue apres conversion
int valeurLue;
int piste;
//on convertit cette valeur en une tension
float valeur_son;

// le nombre qui determine la couleur de la led
int couleur_led = 0;

long duree_seconde = 5;  // premiere duree forcee a 15s
long duree_milis = duree_seconde * 1000;
long tempoDepart = 0;  // on initialise la tempo depart
int memoire_son = 0;

// lecture de l'etat des boutons (un seul a la fois mais une variable suffit)
int etat_bouton;

int memoire_droit = HIGH; // etat relâche par defaut
int memoire_gauche = HIGH;

// create the object for the virtual serial port. In this case, it's called Somo
SoftwareSerial Somo(Rx_pin,Tx_pin);
// define a structure for holding the bytes that will be passed to the SOMO
typedef struct _ControlMsg
{
  byte  start;
  byte  cmd;
  byte  feedback;
  byte  para1;
  byte  para2;
  byte  checksum1;
  byte  checksum2;
  byte  end;
} ControlMsg;

/* initilisation des broches en entree/sortie */
void setup()
{
  pinMode(btn_gauche, INPUT_PULLUP);
  pinMode(btn_droit, INPUT_PULLUP);
  pinMode(led_bleu, OUTPUT);
  pinMode(led_orange, OUTPUT);
  pinMode(btn_glados, INPUT_PULLUP); 
  Initialize_SOMO();
  Serial.begin(9600);
  randomSeed(analogRead(1));
  }

void loop()
{
  // lecture de l'etat du bouton gauche
  etat_bouton = digitalRead(btn_gauche);

  // Si le bouton a un etat different que celui enregistre ET
  // que cet etat est "appuye"
  if((etat_bouton != memoire_gauche) && (etat_bouton == LOW))
  {
    // on indique quelle LED on allume
    couleur_led = 1;
    Play_Gun(1);
    Serial.println("Bouton gauche activé, la led bleu s'allume");
  }

  // on enregistre l'etat du bouton pour le tour suivant
  memoire_gauche = etat_bouton;

  // et maintenant pareil pour le bouton droit
  etat_bouton = digitalRead(btn_droit); // lecture de son etat

  // Si le bouton a un etat different que celui enregistre ET
  // que cet etat est "appuye"
  if((etat_bouton != memoire_droit) && (etat_bouton == LOW))
    {
    // on indique quelle LED on allume
    couleur_led = 2;
    Play_Gun(2);
    Serial.println("Bouton droit activé, la led orange s'allume");
  }
  // on enregistre l'etat du bouton pour le tour suivant
  memoire_droit = etat_bouton;

  // appel de la fonction affiche() que l'on aura creee
  // on lui passe en parametre la valeur de la couleur de LED a eclairer
  affiche(couleur_led);
  
  // Si le bouton Glados est actif,
  if ( digitalRead(btn_glados) == LOW ) 
  {
    
    // Et si il s'est ecoule entre 60 et 180 secondes,
    if ( ( millis() - tempoDepart ) >= duree_milis )
    {
      
      // Alors on lance une des musique de glados
      piste = random(1, nombre_pistes);
      Play_Glados(piste);
      Serial.print("Glados va jouer la piste n ");
      Serial.println(piste);

      // Et on redemare la temporisation pour ne pas afficher ce message une seconde fois
      duree_seconde = random(60, 120);
      duree_milis = duree_seconde * 1000;
      tempoDepart = millis();
      Serial.print("Prochaine musique dans ");
      Serial.print(duree_seconde);
      Serial.println(" secondes");
      Serial.println("");
    }
  }
  
  //on convertit en nombre binaire la tension lue en sortie du potentiometre
  valeurLue = analogRead(potar);

  //on traduit la valeur brute en valeur du son (1-30)
  valeur_son = map(valeurLue, 1, 1024, 1, 30);
  
  //si la valeur du son est modifie, on sauvegarde cette valeur et on emet la valeur au module SOMO II
  if (valeur_son != memoire_son)
  {
    memoire_son = valeur_son;
    Envoi_son(memoire_son);
    Serial.print("la valeur du son est de : ");
    Serial.println(memoire_son);
    Serial.println("");
    }
    
}
// Fonction d'initialisation du SOMO II
void Initialize_SOMO()
{
  // initialise le module SOMO II
  Somo.begin(9600);
  delay(500);
}

void affiche(int valeur_recue)
{ if(valeur_recue == 0)
  {
    digitalWrite(led_bleu, HIGH);
    digitalWrite(led_orange, HIGH);
  }
  if(valeur_recue == 1)
  {
    digitalWrite(led_bleu, LOW);
    digitalWrite(led_orange, HIGH);
    }
  if(valeur_recue == 2)
  {
    digitalWrite(led_bleu, HIGH);
    digitalWrite(led_orange, LOW);
  }
}

// Cette fonction permet de lire les fichier du Portal Gun
void Play_Gun(byte gun)
{
  ControlMsg ctrlMsg;   // structure
  // set variables for playing a track
  byte cmd = 0x0F;     // sets the "Play a specified folder & track" command
  byte feedback = 0;   // sets the feedback requirement to off
  byte para1 = 1;      // sets it to folder "01" on the microSD card
  byte para2 = gun;  // sets the track number  (1 to 255)
  // populate structure with the bytes
  ctrlMsg.start = 0x7E;    //  always use this starter byte
  ctrlMsg.cmd = cmd;  
  ctrlMsg.feedback = feedback; 
  ctrlMsg.para1 = para1;  
  ctrlMsg.para2 = para2;  
  // Sending instructions to the SOMO requires the use of a checksum
  // Checksum (2 bytes) = 0xFFFF – (CMD + Feedback + Para1 + Para2) + 1
  word chksum = 0xFFFF - ((word)cmd + (word)feedback + (word)para1 + (word)para2) + 1;  
  ctrlMsg.checksum1 = (byte)(chksum >> 8); // upper 8 bits
  ctrlMsg.checksum2 = (byte)chksum; // lower 8 bits
  ctrlMsg.end = 0xEF;     // always use this end byte
  // Now we write the structure to the SOMO MP3 Module
  Somo.write((const byte*)&ctrlMsg, sizeof(ctrlMsg));
  Somo.flush();
}

// Cette fonction permet de lire les fichier de Potato Glados
void Play_Glados(byte track)
{
  ControlMsg ctrlMsg;   // Create structure
  // set variables for playing a track
  byte cmd = 0x0F;     // sets the "Play a specified folder & track" command
  byte feedback = 0;   // sets the feedback requirement to off
  byte para1 = 2;      // sets it to folder "01" on the microSD card
  byte para2 = track;  // sets the track number  (1 to 255)
  // populate structure with the bytes
  ctrlMsg.start = 0x7E;    //  always use this starter byte
  ctrlMsg.cmd = cmd;  
  ctrlMsg.feedback = feedback; 
  ctrlMsg.para1 = para1;  
  ctrlMsg.para2 = para2;  
  // Sending instructions to the SOMO requires the use of a checksum
  // Checksum (2 bytes) = 0xFFFF – (CMD + Feedback + Para1 + Para2) + 1
  word chksum = 0xFFFF - ((word)cmd + (word)feedback + (word)para1 + (word)para2) + 1;  
  ctrlMsg.checksum1 = (byte)(chksum >> 8); // upper 8 bits
  ctrlMsg.checksum2 = (byte)chksum; // lower 8 bits
  ctrlMsg.end = 0xEF;     // always use this end byte
  // Now we write the structure to the SOMO MP3 Module
  Somo.write((const byte*)&ctrlMsg, sizeof(ctrlMsg));
  Somo.flush();
}

// Cette fonction donne envoi la valeur du son
void Envoi_son(byte sound)
{
  ControlMsg ctrlMsg;   // Create structure
  // parametre pour le son
  byte cmd = 0x06;
  byte feedback = 0;   // sets the feedback requirement to off
  byte para1 = 0;      // sets it to modifie sound
  byte para2 = sound;  // sets the sound  (1 to 30)
  // populate structure with the bytes
  ctrlMsg.start = 0x7E;    //  always use this starter byte
  ctrlMsg.cmd = cmd;  
  ctrlMsg.feedback = feedback; 
  ctrlMsg.para1 = para1;  
  ctrlMsg.para2 = para2;  
  // Sending instructions to the SOMO requires the use of a checksum
  // Checksum (2 bytes) = 0xFFFF – (CMD + Feedback + Para1 + Para2) + 1
  word chksum = 0xFFFF - ((word)cmd + (word)feedback + (word)para1 + (word)para2) + 1;  
  ctrlMsg.checksum1 = (byte)(chksum >> 8); // upper 8 bits
  ctrlMsg.checksum2 = (byte)chksum; // lower 8 bits
  ctrlMsg.end = 0xEF;     // always use this end byte
  // Now we write the structure to the SOMO MP3 Module
  Somo.write((const byte*)&ctrlMsg, sizeof(ctrlMsg));
  Somo.flush();
}
Ce code est libre d'utilisation, à vous d'en faire ce que bon vous semble

Ouverture du site

Voici le début de ce site, que je vais essayer de faire vivre autant que je le peux ;-)

Je laisse les commentaires activés, sans besoin d'adresse email, et je me réserve le droit de supprimer les messages injurieux, ainsi que ceux qui n'ont rien à faire sur ce site (pub).

Vie privée


Comme tous les sites web, le mien conserve les historiques des connexions comprenant la date, l’heure, l’adresse IP et la signature de votre navigateur. Ces données ne sont — et ne seront jamais — exploitées et encore moins diffusées ou vendues.

Edit du 17/01/2018 : Recréation du site web sur un Raspberry PI avec Yunohost en OS et PluXML en CMS
Bonne visite ;)