Bonjour!
Il s'agit ici de fabriquer un géné…oui, bon, tu as déjà lu le titre… Ce sera un appareil physique, avec une sortie MIDI physique donc, pas USB mais en jack 3.5.
Ce projet est né suite au dépoussiérage d'un vieux sampler qui a une connectique MIDI complète.
Donc, à force de fouiller l'intermouette, on fini par tomber sur des projets déjà existant, qui ressemblent comme deux gouttes d'eau à ce qu'on avait en tête. Et pour nous cela donne ceci: Midi Random Sequence Generator
Les crédits de cette image reviennent à l'auteur de la page Instructable.
C'est basé sur un Arduino Nano. L'idée du projet est de générer des séquences de notes MIDI aléatoires. Plusieurs longueurs pour ces séquences sont disponibles: 4, 7, 8 et 16 pas. Il est possible de stopper la génération de séquence avec le premier des interrupteurs et de faire tourner en boucle infinie la séquence en cours avec le second interrupteur.
Voici le code:
#include <MIDI.h> #define redLed 13 #define pot A7 #define fourth 7 #define seventh 8 #define eighth 9 #define switchOne 11 #define switchTwo 10 MIDI_CREATE_DEFAULT_INSTANCE(); int notes[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int scale[] = {0, 2, 3, 5, 7, 9, 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 27, 29, 31, 33, 34, 36}; int seqLength; int range = 21; int bpm; int rootNote = 35; int potValue; int four; int seven; int eight; int hold; int loops = 4; int count = 1; void setup() { pinMode(redLed, OUTPUT); pinMode(pot, INPUT); pinMode(fourth, INPUT); pinMode(seventh, INPUT); pinMode(eighth, INPUT); pinMode(switchOne, INPUT); pinMode(switchTwo, INPUT); digitalWrite(0, LOW); //Serial.begin(115200); MIDI.begin(MIDI_CHANNEL_OFF); potValue = analogRead(pot); randomSeed(potValue); } void loop() { //Serial.println(count); hold = digitalRead(switchOne); if (count == 1){ digitalWrite(redLed, HIGH); four = digitalRead(fourth); seven = digitalRead(seventh); eight = digitalRead(eighth); hold = digitalRead(switchOne); if (four == 1){ seqLength = 4; } else if (seven == 1){ seqLength = 7; } else if (eight == 1){ seqLength = 8; } else { seqLength = 16; } for (int i = 0; i < seqLength; i++){ notes[i] = scale[random(0,range)]; } digitalWrite(redLed, LOW); } if (count <= loops){ for (int i = 0; i < seqLength; i++){ potValue = analogRead(pot); bpm = 60 + potValue * 0.72265625; // 60 - 800 bpm quarter notes int pause = digitalRead(switchTwo); while (pause == 1){ delay(50); pause = digitalRead(switchTwo); } MIDI.sendNoteOn(rootNote + notes[i], 127, 1); digitalWrite(redLed, HIGH); //Serial.println(notes[i]); //Serial.println(potValue); //Serial.println(bpm); //Serial.println(""); delay(60000/bpm*0.75); MIDI.sendNoteOff(rootNote + notes[i], 0, 1); digitalWrite(redLed, LOW); delay(60000/bpm*0.25); } //Serial.println(""); hold = digitalRead(switchOne); if (count == loops && hold == 1){ count = loops; } else{ count += 1; } } if (count > loops && hold == 0){ count = 1; } }
Après avoir testé le montage sur une plaque d'essais, il semble que les interrupteurs et le sélecteur de durée de séquence ne fonctionnent pas. Ce qui confirme le ressenti lors de l'écoute. Le reste roule parfaitement, donc on ne change rien de ce côté pour le moment…
Le matériel est donc testé physiquement en dehors du montage. Un simple test de continuité fera l'affaire dans ce cas et, effectivement, pas de pannes de ce côté-ci. Les interrupteurs ouvrent et ferment le circuit, le sélecteur rotatif de même.
Donc, allons voir du coté de la perspicacité du montage en lui-même, à savoir si les branchements entre les différents composants font ce qu'ils doivent faire en fonction du code.
La méthode qui suit a été gentillement soufflée à l'oreille par une porte logique à barbe…
Alors, pour cela nous allons garder le même montage mais changer le code dans le Nano. Nous allons
tester que tous les petits bidules d'interaction (boutons, pots, etc) fonctionnent correctement hors de la logique du code, il faudrait tester avec un code de ce type qui permettra de le vérifier :
#define redLed 13 #define pot A7 #define fourth 7 #define seventh 8 #define eighth 9 #define switchOne 11 #define switchTwo 10 int count; // compteur utile pour ne pas surcharger d'info le moniteur série void setup() { pinMode(pot, INPUT); pinMode(fourth, INPUT); pinMode(seventh, INPUT); pinMode(eighth, INPUT); pinMode(switchOne, INPUT); pinMode(switchTwo, INPUT); Serial.begin(9600); } void loop() { // Tester les boutons un par un if (digitalRead(switchOne)) Serial.println("switch one on"); if (digitalRead(switchTwo)) Serial.println("switch two on"); if (digitalRead(fourth)) Serial.println("fourth on"); if (digitalRead(seventh)) Serial.println("seventh on"); if (digitalRead(eighth)) Serial.println("eighth on"); // Envoyer la valeur du pot une fois sur 50 ( = 50 x delay(10) = 2 fois par secondes if (count%50 == 0) Serial.println(analogRead(pot)); count ++; // augmenter le compteur delay(10); // petite pause 10 millisecondes }
Une fois que le code est injecté dans le Nano, nous pouvons observer plusieurs choses dans le moniteur série:
Cela donnera pour cette première version du projet quelque chose comme ça:
Sur la photo ci-dessus nous pouvons voir plusieurs choses:
Sur cette seconde photo, nous avons: