Table des matières:

Projet Guitar Hero Arduino : 12 étapes (avec photos)
Projet Guitar Hero Arduino : 12 étapes (avec photos)

Vidéo: Projet Guitar Hero Arduino : 12 étapes (avec photos)

Vidéo: Projet Guitar Hero Arduino : 12 étapes (avec photos)
Vidéo: drone #shorts 2024, Novembre
Anonim
Projet Guitar Hero Arduino
Projet Guitar Hero Arduino
Projet Guitar Hero Arduino
Projet Guitar Hero Arduino
Projet Guitar Hero Arduino
Projet Guitar Hero Arduino

Wij zijn Maarten Vrebos, Justin Cavanas et Wannes Stroobandt et nous étudions le multimédia et la communicationtechnologie. Voor een groepsproject voor het vak Audiovisual & IT Principles hebben wij een Guitar Hero-gitaar gehackt en gebruikt als behuizing voor onze MIDI-controller. Het was onze bedoeling om de bestaande knoppen op de gitaar intern te vervangen. Onze controller zal vastgehouden et bespeeld worden als een normal gitaar. Aangezien we iets hebben gehackt hebben we er niet veel extra materiaal in moeten verwerken.

In de afbeelding kan u onze allereerste schets op paper zien van hoe het eindproduct er zou moeten uitzien met daarnaast een foto van de gitaar die als behuizing zal worden gebruikt.

Wij hebben ons voor dit project gebaseerd op volgende bronnen:

slapyak.wordpress.com/guitar-hero-midi-con…

www.instructables.com/id/Converting-a-rescu…

gizmodo.com/391834/turn-your-guitar-hero-g…

Benodigdheden voor dit projet

  • 6 boutons poussoirs simples
  • 7 résistances de 1kohm
  • 1 gele LED 1
  • LED bleu
  • 1 Arduino Uno R3
  • 1 LED verte
  • 2 leds montées
  • 1 schuifschakelaar
  • 1 planche à pain
  • 1 potentiomètre
  • 1 protobord
  • 1 guitare Guitar Hero
  • Literie Voldoende
  • Materiaal om te soldren/dremelen/
  • Schroevendraaier

Étape 1: Componenten Verzamelen

Composants Verzamelen
Composants Verzamelen

Voor ons prototype (op breadboard) hebben we volgende componenten gebruikt:

6 boutons poussoirs

7 résistances 1kohm

1 LED jaune

1 LED bleue

1 Arduino Uno R3

1 LED verte

2 DEL rouges

1 Schuifschakelaar

1 planche à pain

1 potentiomètre

Étape 2: Prototyper Bouwen

Prototype Bouwen
Prototype Bouwen
Prototype Bouwen
Prototype Bouwen
Prototype Bouwen
Prototype Bouwen

Om ons prototype te bouwen hebben nous avons al onze componenten gebruikt op een breadboard, deze breadboard dient dan als testobject zodat we niet meteen in de behuizing te werk moeten gaan. Dit prototype hebben nous dan ook gedigitaliseerd via tinkercad.com, op deze manier hadden we een duidelijk overzicht van ons prototype dat elk groepslid ook kon bewerken.

Er worden 5 kleine boutons-poussoirs gebruikt die fungeren als 5 snaren en een grote poussoir die in combinatie rencontré één de meerdere 'snaren' moet worden ingedrukt om een auditief effect te krijgen. De verschillende LED-lampjes dienen gewoon als visuel controle om er zeker van te zijn dat de interactie succesvol werkt.

Étape 3: Coder le prototype

Prototype de code
Prototype de code

Globale variabelen

Dans het eerste deel van de code initialiser je global variabelen voor de pins van arduino uno waar alle pushbuttons mee verbonden zijn.

// zet les numéros de broche waar mainButton(snaar) et andere boutons aan verbonden zijn:const int mainButton = A1; // gitaar snaar const int lightSensor = A0; const int boutonPin1 = 2; // nummer van pushbutton1 const int buttonPin2 = 3; // nummer van pushbutton2const int buttonPin3 = 4; // nummer van pushbutton3const int buttonPin4 = 5; // nummer van pushbutton4const int buttonPin5 = 6; // bouton poussoir numéro 5

Hierna worden er twee arrays aangemaakt voor de namen van de pushbuttons en hun pinnummer.

const int aantalKnoppen = 5;const String namenKnoppen[aantalKnoppen] = {"knop 1", "knop 2", "knop 3", "knop 4", "knop 5"}; const int knopPinnen[aantalKnoppen] = {2, 3, 4, 5, 6};

En dan nog variabelen voor de pins van de LED lichtjes.

const int ledPin1 = 13; // le numéro de la LED pin 13

const int ledPin2 = 12; // le nombre de LED pin 12 const int ledPin3 = 11; // le nombre de LED pin 11 const int ledPin4 = 10; // le nombre de LED pin 10 const int ledPin5 = 9; // le nombre de LED pin 9 const int potPin = A5; // le nombre de LED pin A5

De laatste globale variabelen dienen als 'states' voor de sensor (zijn de pushbuttons ingedrukt of niet? potentiometer, lichtsensor).

// initialiser buttonStates voor de knoppen (ingedrukt of niet)int mainButtonState = 0; int buttonState1 = 0; int buttonState2 = 0; int buttonState3 = 0; int buttonState4 = 0; int buttonState5 = 0; int lightSensorState = 0; int potValue = 0; int lightValue = 0;

Installer

Aucune fonction de configuration de volgt de void. Deze est de type van het void (geeft geen waarde terug) en de instructies hierin worden maar 1 keer uitgevoerd.

Bij elke functie est commentaar geschreven wat er concreet gedaan wordt. Extra uitleg over wat een specifieke functie concrètement doet is te vinden in de arduino reference

void setup() { // débit de données par seconde (baud) pour la transmission de données en série Serial.begin(9600); // Initialiseer de ledPin variabelen als output pinMode(ledPin1, OUTPUT); pinMode(ledPin2, SORTIE); pinMode(ledPin3, SORTIE); pinMode(ledPin4, SORTIE); pinMode(ledPin5, SORTIE); // initialise tous les boutons poussoirs comme entrée: pinMode(mainButton, INPUT); pinMode(boutonPin1, INPUT); pinMode(boutonPin2, INPUT); pinMode (boutonPin3, INPUT); pinMode (boutonPin4, INPUT); pinMode (boutonPin5, INPUT); pinMode(potPin, INPUT); pinMode(lightSensor, INPUT); }

Fonction vide

La fonction setup() volgt de loop() functie, les instructions die hierin staan gaan herhaald uitgevoerd worden.

void loop() { // lees de staat van de pushbuttons uit (ingedrukt of niet) mainButtonState = digitalRead(mainButton); buttonState1 = digitalRead(buttonPin1); buttonState2 = digitalRead(buttonPin2); buttonState3 = digitalRead(buttonPin3); buttonState4 = digitalRead(buttonPin4); buttonState5 = digitalRead(buttonPin5);

// tous les statuts des boutons poussoirs dans un tableau

int buttonStates = {buttonState1, buttonState2, buttonState3, buttonState4, buttonState5};

// leest de waarde uit van de potentiometer en de lichtsensor

potValue = analogRead(potPin); lightValue = analogRead(lightSensor);

// declareer een array mainStates en geef die de standaard waarden 0 in.

int mainStates = {0, 0, 0, 0, 0};

// boucle sur le tableau aantalKnoppen

for(int i = 0; i < aantalKnoppen; i++){ pinMode(knopPinnen, INPUT); // initialiser alle knopPinnen als input digitalRead(knopPinnen); // lees de waarde van alle knoppinnen uit // indien de mainwitch (snaar) ingedrukt is, print alle knopnamen, alle buttonstates if(mainButtonState == HIGH){ Serial.print(namenKnoppen); Serial.print(", "); Serial.println(buttonStates); } }

Étape 4: Prototype Uittesten

Nadat het prototype gebouwd est volgens ons model en de code geschreven is in Processing, is het tijd om het prototype uit te testen. Op de video is te zien dat alle knoppen een reactie geven op de bijhorende ledjes en dat ook combinaties van knoppen mogelijk zijn.

Dans la vidéo de tweede se trouve te zien hoe onze tremolo werkt aan de hand van een potentiometer in de gitaar en hoe de waardes worden uitgelezen in Processing.

Étape 5: Behuizing "ontmantelen" En Kijken Welke Componenten Gebruikt Gaan Worden

Behuizing
Behuizing
Behuizing
Behuizing
Behuizing
Behuizing
Behuizing
Behuizing

Als de code correct werkte op het prototype zijn we begonnen rencontré het "ontmantelen" van onze Guitar Hero-gitaar. Nous hebben de gitaar opengemaakt rencontré een schroevendraaier en bekeken welke originele componenten we eventueel nog zouden kunnen hergebruiken voor onze controller. Uiteindelijk hebben we onze eigen pushbuttons in de bestaande boutons gekregen (zie volgende stap). Nous hebben de tremolo ook gebruikt voor ons eindproduct en voor onze hoofdbutton (initiële button om als een combinatie af te spelen) hebben we ook de originele twee Buttons gebruikt(zie vierde foto). De LEDjes zullen verdwijnen (deze waren enkel ter indicatie zodat we zagen dat alle knoppen correct werkten.

Étape 6: Werking Boutons Originele + Dremelen

Boutons Werking Originele + Dremelen
Boutons Werking Originele + Dremelen

Op de bijhorende video is of wijze te zien waarop de twee originele knoppen werken als een soort van schakelaar die wij gebruiken om een effect te genereren bij combinatie van knoppen.

Om onze eigen Buttons te verwerken in de originele knoppen hebben we de binnenkant van de originlen er grotendeels uitgehaald zoals te zien is op de foto.

Étape 7: Souderen + boutons Vastlijmen

Bedrading Solderen + Boutons Vastlijmen
Bedrading Solderen + Boutons Vastlijmen
Bedrading Solderen + Boutons Vastlijmen
Bedrading Solderen + Boutons Vastlijmen
Bedrading Solderen + Boutons Vastlijmen
Bedrading Solderen + Boutons Vastlijmen

Omdat we niet meer met een breadboard werken moeten de draden gesoldeerd worden om zo de verschillende componenten met elkaar te verbinden. Nadat dit gebeurd is kunnen we de button vastlijmen zoals te zien is op de foto's. Eens dit gebeurd is kunnen we doorgaan naar de volgende stap.

Étape 8: Plaats Maken à De Behuizing

Plaats Maken à De Behuizing
Plaats Maken à De Behuizing
Plaats Maken à De Behuizing
Plaats Maken à De Behuizing
Plaats Maken à De Behuizing
Plaats Maken à De Behuizing

Omdat dit Guitar Hero-model redelijk krap was om mee te werken hebben we extra plaats moeten maken d.m.v. dremelen. Zo hebben we uit de achterkant van de gitaar een hele strook verwijderd zodat er meer plaats ontstaat voor de bedrading in de gitaar. Omdat er overal in de binnenkant obstakels waren, waaronder veel buisjes om de vijzen in te bevestigen, hebben we die ook verwijderd om optimaal van de gegeven ruimte gebruik te kunnen maken. Op de vierde en vijfde foto is te zien dat we in de achterkant van de gitaar een doorgang hebben gecreëerd voor de draden die naar debuttons gaan omdat de gitaar anders niet meer te sluiten was. En op de laatste foto is te zien dat we de draden die rechtstreeks verbonden worden met de Arduino door een gat in de onderkant van de gitaar de behuizing verlaten.

Étape 9: Bedrading Aansluiten Op Protobord

Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord
Bedrading Aansluiten Op Protobord

Om alle componenten met elkaar te verbinden hebben we gebruik gemaakt van een protobord. Dit is een bordje dat eigenlijk op net dezelfde manier werkt als een breadbord, maar dan betrouwbaarder en efficiënter. We hebben de bedrading aan het bordje gesoldeerd zoals te zien is op de derde foto. Dit bord is het centrale punt van waaruit al onze verbindingen vertrekken en samenkomen (zie foto 2).

Étape 10: Verstevigen

Verstevigen
Verstevigen

La touche finale est également het verstandig om de losse delen te verstevigen voor extra stabiliteit. Op deze foto is te zien hoe we het deel dat we er hebben uitgehaald d.m.v. dremelen achteraan de button verstevigen met stukjes karton.

Étape 11: Code Voor Het Communiceren Met Reaper

Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper
Code Voor Het Communiceren Met Reaper

Le code de Deze est opgedeeld dans twee delen, het eerste deel est dans de arduino IDE (environnement de développement interactif) geschreven. Die code wordt geüpload naar arduino zelf en dient om alle waarden van de sensor van de midi controller uit te lezen en door te sturen naar processing.

Le traitement est het tweede gedeelte. Deze code dient om alles wat arduino doortuurt te ontvangen en door te sturen naar Reaper.

Arduino

/* Ce code est une esquisse de base pour communiquer avec Processing via Serial.

C'est un plan dans lequel vous pouvez mettre votre propre code

spécifié pour vos propres boutons, potentiomètres ou capteurs.

Il a une poignée de main pour s'assurer que nous avons le contact

et le format dans lequel nous communiquons est décidé

Il est important de construire le message de la même manière, afin que Processing sache comment le déconstruire et envoyer des messages OSC corrects à notre DAW

fait pour werkcollege AV&IT

octobre 2017

*

/ débit en bauds

const long baudRate = 115200;

// temps d'attente en ms entre les sondages aux broches

const int loopPauseTime = 200; // millisecondes

// valeurs de début et de fin du message envoyé sur Serial

const String startString = "*", endString = "#";

const char contactCharacter = '|';

// identifiants de broche

// autres variables globales

const int aantalKnoppen = 5; const String namenKnoppen[aantalKnoppen] = {"knop 1", "knop 2", "knop 3", "knop 4", "knop 5"}; const int knopPinnen[aantalKnoppen] = {2, 3, 4, 5, 6}; const int mainButton = A1;

int mainButtonState = 0;

int potValue = 0;

// capteurs analogiques

const int potPin = A5; // pin voor trémolo

// Nous avons besoin de cette fonction pour établir le contact avec le Processing sketch

// Gardez-le ici voidestablishContact() { while (Serial.available() <= 0) { Serial.print(contactCharacter); // envoie un caractère et attend une réponse… delay(loopPauseTime); } Serial.read(); }

void setup() {

// définit les pinModes pour toutes les broches for(int i = 0; i < aantalKnoppen; i++){ pinMode(knopPinnen, INPUT); } pinMode(mainButton, INPUT); // Décommentez si vous utilisez des capteurs qui fonctionnent sur 3V au lieu de 5V // vous devrez également câbler la broche 'ext' à 3,3V // analogReference(EXTERNAL);

// initialise les communications série

Serial.begin(baudRate); tandis que (!Série); // attend l'établissement de la poignée de mainestablishContact(); }

boucle vide() {

// ÉTAPE 1: LIRE LES BOUTONS // interroger toutes les broches et mapper la lecture sur la plage appropriée int buttonStates[aantalKnoppen]; /* buttonStates[0] = digitalRead(knopPinnen[0]); buttonStates[1] = digitalRead(knopPinnen[1]); buttonStates[2] = digitalRead(knopPinnen[2]); buttonStates[3] = digitalRead(knopPinnen[3]); buttonStates[4] = digitalRead(knopPinnen[4]); */ mainButtonState = digitalRead(mainButton); for(int i = 0; i < aantalKnoppen; i++){ buttonStates = digitalRead(knopPinnen); } potValue = analogRead(potPin); // exemples: // float v0 = map(bpm, 0, 1023, 60, 250); // si vous souhaitez utiliser un float normalisé (par exemple pour le volume) // float v1 = map(analogRead(pin2), fromMin, fromMax, 0, 100) / 100.0;

// ÉTAPE 2: ÉCRIRE UN MESSAGE

Serial.print(startString); // démarre une séquence de messages for(int i = 0; i < aantalKnoppen; i++){ if(mainButtonState == HIGH){ Serial.print(namenKnoppen); Serial.print(", "); Serial.print(buttonStates); if(i < aantalKnoppen - 1){ Serial.print(", "); } }else{ buttonStates = 0; Serial.print(nomKnoppen); Serial.print(", "); Serial.print(buttonStates); if(i < aantalKnoppen - 1){ Serial.print(", "); } } } Serial.print(", "); Serial.print("tremolo"); Serial.print(", "); Serial.print(map(potValue, 0, 1023, 0, 100)); // écrit la fin du message Serial.print(endString);

// attendre un moment..

delay(loopPauseTime); }

Traitement

Avis de non-responsabilité: Niet alle code van de processing sketch staat hier in geschreven, voor de volledige code zie het bestand: ProcessingSoundControl_handout_v6_1.pde in bijlage

De volgende instructies moeten aangepast worden (indien nodig):

// Baudrate moet hetzelfde zijn zoals in de arduino sketch

débit en bauds int final = 115200;

// Zoek naar het IP address in reaper (zie screenshots in bijlage)

// Traitement stuurt naar dit andres en reaper luistert hier naar //

//chaîne finale remoteIP = "192.168.1.43"; //par exemple. "127.0.0.1";

chaîne finale remoteIP = "10.3.209.60";

// Prenez note du sendPort et remplissez-le dans Reaper.

// Il s'agit du port auquel Processing envoie et que Reaper écoute.

int final listenPort = 12000, port d'envoi = 12000;

// Le listenPort ici est à déboguer activement.

// les portNames sont également là pour déboguer.

//chaîne finale nom_port = "/dev/ttyACM0";

chaîne finale nom_port = "COM5"; // "/dev/ttyUSB0";

//////////////////// FIN DES PARAMETRES UTILISATEUR //////////////////////// ////

import processing.serial.*;

importer java.util.*;

importer oscP5.*;

importer netP5.*;

OscP5 oscP5;

NetAddress myRemoteLocation;

Port de communication série; // Le port série

booléen messageArrivé = false;

Chaîne entrante = "", IncomingOSCMessage = "";

caractère final startChar = '*', endChar = '#'; caractère final contactCharacter = '|';

// Pour s'assurer que nous n'envoyons que les paramètres (valeurs) qui changent

// ces variables globales sont supprimées ici mais ne doivent // pas être initialisées ici ! HashMap oldParams, newParams, toSendParams;

// Nous devons séparer le message à chaque virgule

void processIncoming () { String resVec = entrant.split(", "); // on obtient des paires nom + valeur // donc pour chaque nom (+2)… try{ for (int i = 0; i< resVec.length; i+=2) { float value = Float.parseFloat(resVec[i+ 1]); // les place dans la nouvelle table de hachage newParams.put(resVec, value); } } // si une erreur se produit, attrapons-la et sortons. catch(Exception ex){ println("Message d'exception: " + ex); printArray(resVec); sortir(); } }

// Pour filtrer nos messages

/* Nous nous assurons qu'il n'y a qu'un message de sortie OSC lorsque * le message d'entrée (Série) change * C'est-à-dire: si nous tournons/appuyons sur le bouton et qu'il change de valeur. * Nous filtrons donc les valeurs entrantes qui changent réellement * note: nous n'éviterons pas de sauter des valeurs * comme provenant par exemple d'accéléromètres ou de capteurs de distance * vous devrez les lisser vous-même dans Arduino */ void filterParams () { toSendParams = new HashMap(); for (String key: newParams.keySet()) { // si la clé est déjà présente if (oldParams.containsKey(key)) { // clé présente et valeur différente, puis mettez à jour si (!oldParams.get(key).equals(newParams.get(key))) { toSendParams.put(key, newParams.get(key)); } } else{ // la clé n'est pas présente dans les anciens paramètres, alors mettez-la ! toSendParams.put(clé, newParams.get(clé)); } oldParams.put(clé, newParams.get(clé)); } }

void makeOSC() {

for (String key: toSendParams.keySet()) { OscMessage myMessage = new OscMessage("/"+ key); monMessage.add(toSendParams.get(clé)); /* envoyer le message */ oscP5.send(myMessage, myRemoteLocation); } }

void translateMessage() {

processusEntrant(); filterParams(); makeOSC(); } // Lorsque nous voulons imprimer dans la fenêtre void ShowIncoming() { // pour voir le message entrant, tel que défini dans le texte HashMap ("Incoming from Arduino", 20, 20); entier y = 20; for (String key: newParams.keySet()) { y = y+20; text(clé, 20, y); text(newParams.get(clé), 300, y); } }

void showOsc() {

text(IncomingOSCMessage, 300, 200); IncomingOSCMessage =""; }

void setup() {

taille(1000, 800); // Remplissage de la taille de la scène (255); arrière-plan(0); oldParams = new HashMap(); newParams = new HashMap(); //printArray(Serial.list()); commsPort = new Serial(this, portName, baudRate);

/* démarrer oscP5, écouter les messages entrants */

oscP5 = new OscP5(this, listenPort);

/* myRemoteLocation est une NetAddress. une NetAddress prend 2 paramètres, * une adresse IP et un numéro de port.myRemoteLocation est utilisé comme paramètre dans * oscP5.send() lors de l'envoi de paquets osc à un autre ordinateur, périphérique, * application. utilisation voir ci-dessous. à des fins de test, le port d'écoute * et le port de l'adresse de l'emplacement distant sont les mêmes, vous devrez donc * renvoyer des messages à cette esquisse. */ myRemoteLocation = new NetAddress(remoteIP, sendPort); }

tirage nul () {

if (messageArrivé) { background(0); translateMessage(); AfficherEntrant(); messageArrivé= false; } showOsc(); }

void serialEvent (Serial commsPort) {

// lit un octet depuis le port série: char inChar = commsPort.readChar(); switch (inChar) { case contactCharacter: commsPort.write(contactCharacter); // demande plus println("start…"); Pause; case startChar: entrant=""; Pause; case endChar: messageArrived = true; //println("fin du message"); Pause; par défaut: entrant += inChar; Pause; } }

/* les messages osc entrants sont transmis à la méthode oscEvent. */

void oscEvent(OscMessage theOscMessage) { float value = theOscMessage.get(0).floatValue(); // obtient le 1er argument osc

MessageOSC entrant += "\n" +

String.format("### a reçu un message osc: " + " addrpattern: " + theOscMessage.addrPattern() + ": %f", value); println(IncomingOSCMessage); }

Étape 12: Contrôleur Uittesten

Nu alles est aangesloten, alle code est geschreven en alles is gedubbelcheckt est het eindelijk tijd om de controller z'n werk te laten doen. Zoek een paar leuke effecten op Reaper en geniet van de voltooide Guitar Hero MIDI Controller!

Conseillé: