Utilisation shield midi in/out

Bonjour la communauté de l'a(rdui)nneau ! clap clap clap clap

Je viens juste de recevoir ce shield midi in/out dont voici le lien :

https://www.ebay.fr/itm/MIDI-IN-OUT-Port-Shield-Breakout-Board-For-Arduino-Uno-AVI-PIC-Digital-Interface/162465034334?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

Je l'ai acheté dans le but de pouvoir récupérer les "signaux" d'un clavier midi afin de créer une petite énigme (une mélodie / combinaison de notes déclenche une action).

Le clavier que j'ai acheté :

Le câble qui relie le clavier au shield :

Alors, une fois tout ça en main, hop !

  1. Le shield monté sur l'arduino (j'ai supposé qu'il fallait faire correspondre les pin : pin digital 0 du shield sur pin digital 0 de ma carte arduino, etc.)
  2. Le câble midi alimenté en usb par mon pc avec le midi in sur le in du shield et le midi out sur le out du clavier
  3. Un câble usb du pc vers l'arduino pour l'alimenter et pour la liaison série
  4. Et enfin, une alim' secteur pour alimenter le clavier.

Et là... je me retrouve comme un gland ! :confused:

Je n'ai pas la moindre foutue idée de comment récupérer le signal des touches du clavier ! L'idée dans un premier temps ce serait juste de les visualiser sur le moniteur série de l'IDE.

Des conseils pour une victime de plus du rêve américain vendu par arduino ? ( :smiley: joke of course !)

Bonjour,

Le lien du shield midi ne montre aucun schéma du circuit.

Au vu de la description, je suppose que les lignes TX et RX de l'Arduino sont utilisées pour le midi (là c'est logique).

Ce sera compliqué d'afficher quelque chose dans le moniteur série.

Un arduino avec minimum 2 uart serait plus approprié ( ex: arduino uno R4 )

A+

Au vu de la description, je suppose que les lignes TX et RX de l'Arduino sont utilisées pour le midi (là c'est logique).

Si tu le dis... ^^'

Ce sera compliqué d'afficher quelque chose dans le moniteur série.

Zut. Après, ceci n'était qu'une étape qui me semblait nécessaire pour programmer ma combinaison. Si je peux faire sans, ce n'est plus un problème.

Un arduino avec minimum 2 uart serait plus approprié ( ex: arduino uno R4 )

C'est quoi des "uart" ?

Bonjour

UART (article de Wikipedia) est le nom du module hardware dans le microcontrolleur qui gère un TX et un RX
Certains microcontrolleurs intègrent plusieurs UART, donc plusieurs paires RX/TX

Bonjour,

Avant tout, il faut comprendre ce que l'on veut manipuler. Je te conseil de faire un tour ici.

Une librairie est disponible ici.

Pfiou, les gars, j'vous jure je suis largué ! J'y mets pas de la mauvaise volonté, vraiment pas ! Mais là, j'ai l'impression qu'il me manque de grosses bases en électronique...

Allez, on se ressaisit et on ne se décourage pas !

UART (article de Wikipedia) est le nom du module hardware dans le microcontrolleur qui gère un TX et un RX
Certains microcontrolleurs intègrent plusieurs UART, donc plusieurs paires RX/TX

C'est quoi cette histoire de RX et TX ? De ce que j'en ai compris, TX c'est pour transmission et RX pour réception ? Donc RX est le pin qui "pilote" mon plug MIDI in et TX pour le plug MIDI out ?

Jusqu'à présent, j'ai toujours déclaré dans tous mes projets Arduino les pins que j'utilisais dans mon void setup sans me soucier de ce TX et RX. Qu'est ce que ça change en fait ?

Avant tout, il faut comprendre ce que l'on veut manipuler. Je te conseil de faire un tour ici.

J'avais déjà lu ça il y a quelques jours. Mais j'ai du mal à voir en quoi ça peut m'aider concrètement... Je l'ai relu mais je ne suis pas plus avancé.

Une librairie est disponible ici.

Pour le coup, ça, je vais en avoir besoin à un moment ou à un autre. Mais pour le moment, je ne sais absolument pas m'en servir...

Une communication midi permet d'échanger des données entre par exemple un clavier et un logiciel de musique. hors, si j'ai bien compris, tu veux te substituer au clavier avec un arduino pour dire au logiciel de jouer une séquence de notes.
Tu dois donc apprendre à communiquer avec le logiciel dans son langage et c'est la norme standard MIDI qui va te dire quoi envoyer pour, par exemple, jouer une note.
La librairie est une partie de code que tu intègres dans ton programme. Tu n'est pas le premier à vouloir communiquer avec un clavier, d'autre l'on déjà fait, et dans leur grande bonté, ils ont mis cette partie de code à disposition sur le net.
Ce code a été développer pour simplifier au mieux les échanges de données, on ne gère pas la vitesse de transition des données, ou les trames. on appelle juste une fonction de la librairie pour jouer une note, ce qui est beaucoup plus simple, mais encore faut-il savoir quelle fonction.
Toute la documentation est fourni avec la librairie. il faut juste la potasser pour trouver les fonctions qui te seront utiles. Il y aura, évidemment, une partie configuration qui te permettra de faire le lien avec les broches de l'arduino car il faut bien relier ton shield.

Salut

Je pense que tu trouveras tout ce qu'il te faut ICI :

Send-and-Receive-MIDI-with-Arduino

L'auteur n'utilise pas de shield, mais le câblage est fait sur le RX TX de l'ARDUINO comme ton shield.

Précision le RX et TX de la UNO sont les pins digitales 0 et 1.
Regarde bien la sérigraphie de la UNO. Tu verras 0 -> RX et 1 <- TX.

Ce sera compliqué d'afficher quelque chose dans le moniteur série.

Étant donné que l'UART de l'ARDUINO est utilisé par le shield MIDI, il va être impossible d'envoyer les données vers le PC par le câble USB de la UNO, car l'USB utilise aussi les pins RX TX donc D0 D1.

Deuxièmement, le téléchargement du programme que tu vas développer dans la mémoire FLASH de la UNO passe aussi par le câble USB. Il va te falloir trouver une autre solution.

Tu pourrais par exemple charger le programme à l'aide d'un programmateur USBASP ou USBTINY. C'est extrêmement simple à utiliser.

Comme tu le vois, cela coince à deux endroits. Il va falloir utiliser plutôt une carte avec plusieurs UARTS, une ARDUINO MEGA par exemple.

La ligne série correspondant au port USB sera réservée au chargement du programme et moniteur série.

Mais le shield ne pourra pas être branché dessus directement. Il faudra le câbler sur la deuxième UART avec des fils. Pas très compliqué.

La librairie sera tout de même utilisable, car elle peut utiliser un port série alternatif (Serial1 ou Serial2 ou Serial3 de la MEGA).

@+

Tu devrais quand même préciser quel est le rôle de l'ARDUINO dans le montage final CLAVIER / ARDUINO / PC.

@+

si j'ai bien compris, tu veux te substituer au clavier avec un arduino pour dire au logiciel de jouer une séquence de notes.

Ce n'est pas tout à fait ça : la séquence de notes sera jouée directement sur le clavier midi. Le rôle de l'Arduino sera d'analyser la séquence de notes jouée et de valider (ou pas) en exécutant une action (allumage d'une led verte par exemple). Après, pour le retour sonore de l'appui sur une touche du clavier, ce n'est pas un problème. Je peux le simuler avec l'Arduino et un buzzer.

Tu devrais quand même préciser quel est le rôle de l'ARDUINO dans le montage final CLAVIER / ARDUINO / PC.

J'ajoute que dans mon montage final, il n'y a plus de pc : seulement l'Arduino, le circuit et le clavier. Voyez le clavier comme une suite de boutons poussoirs avec chacun leur "signature" en fait.

J'essaierai de travailler un semblant de programme Arduino demain pour vous montrer exactement ce que je compte faire, ce sera surement plus parlant.

Merci pour vos nombreux conseils en tout cas.

Re, les Hobbits !

Voilà ce que j'ai fait (je précise à l'avance, c'est bourré d'erreurs mais qu'importe, c'est juste pour vous donner une idée) :

int DO = ?? ;//code binaire correspondant au do sur le clavier
int RE = ?? ;//code binaire correspondant au ré sur le clavier
int MI = ?? ;//code binaire correspondant au mi sur le clavier
int FA = ?? ;//code binaire correspondant au fa sur le clavier
int SOL = ?? ;//code binaire correspondant au sol sur le clavier

//============

const int LedPin1 = 13;      // LED rouge
const int LedPin5 = 9;      // LED verte

//============

const int SizeCode = 5;

int Code[SizeCode] = {DO, RE, MI, FA, SOL};   
int CodeActuel[SizeCode] = {0};

//délai de sécurité : si il y a plus de temps entre deux appuis,le Code est effacé
unsigned long DernierAppui;
const unsigned long Delai = 20E3; // 5000 ms = 10 s

void setup()
{
  Serial.begin(9600);
  
  pinMode(LedPin1, OUTPUT);   
  pinMode(LedPin5, OUTPUT);

  pinMode(pin de mon plug midi, INPUT);
  
  DernierAppui = millis();

  tempsDep = millis(); // initialisation du temps de départ
}

void loop() 
{
  lireBoutons();
  
  if( comparerCodes() == true )
  {
    ouvrirPorte();
    //on raz le chrono de sécurité pour ne pas que la porte se referme seule ( il faudra appuyer un des boutons pour la refermer )
    DernierAppui = millis();
  }
  else
    fermerPorte();
  
  if (millis() - Delai > DernierAppui)
    remplirCode(0);
}

//====================

void ouvrirPorte()
{  
  digitalWrite(LedPin5, HIGH);  //Allumage de la led verte signalant l'ouverture de la porte
  digitalWrite(LedPin1, LOW);  //Extinction de la led rouge
}

void fermerPorte()
{
  digitalWrite(LedPin5, LOW);    //Extinction de la led verte
  digitalWrite(LedPin1, HIGH);    //Allumage de la led rouge
  p=0;// retour au début du tableau
}


void lireBoutons()
{ 
  for(int i = 0; i < NbNotes; i++)
    if (commandByte == noteOn) //bouton appuyé ?
    {
      delay(30); //anti-rebond
      while (commandByte == noteOff) {} //on attends d'avoir relaché le bouton
      remplirCode( i+1 ); //et on stocke le numéro du bouton dans le tableau
    }
    
    //si on est arrivé là, c'est qu'aucun bouton n'était appuyé : on retourne 0
}

void remplirCode(int valeur)
{
  //on décale les cases vers la première, qui est CodeActuel[0], car les index commencent toujours à 0 :
  for(int i = 1; i < SizeCode; i++) 
    CodeActuel[i-1]=CodeActuel[i];
  
  //et on remplit la dernière, donc à l'index taille du tableau -1 puisque que l'index commence à 0 :
  CodeActuel[SizeCode-1]=valeur; 
  
  //et enfin on raz le chrono de sécurité
  DernierAppui = millis();
}

bool comparerCodes()
{
  for(int i=0; i < SizeCode; i++)
    if (CodeActuel[i] != Code[i])
      return false; //dès qu'une des valeurs est fausse, quitte et retourne faux
    
    return true; //si on est arrivé là, c'est que le Code est ok, on retourne vrai
}

Pour l'expliquer quand même un minimum, ma déclaration des "int" au début n'est pas adaptée. Ce que j'aimerais, c'est faire correspondre chaque note à un son appellation (DO1 au lieu de me retaper les 3 bytes à chaque fois). Je peux par exemple utiliser ça pour chaque note :

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  Serial.begin(31250);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void checkMIDI(){
  do{
    if (Serial.available()){
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      if (commandByte == noteOn){//if note on message
        //check if note == 60 and velocity > 0
        if (noteByte == 60 && velocityByte > 0){
          digitalWrite(13,HIGH);//turn on led
        }
      }
    }
  }
  while (Serial.available() > 2);//when at least three bytes available
}
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(13,LOW);//turn led off
}

Dans cet exemple, si on joue la séquence DO RE MI FA SOL, la led verte s'allume. (en tout cas c'est le résultat que j'AIMERAIS obtenir)
Je suis sur une bonne piste ?

const unsigned long Delai = 20E3; // 5000 ms = 10 s

Une valeur binaire s'écrit 0x20E3
Aucun intérêt ici. Autant écrire 10000 pour 10s.

Effectivement c'est une ébauche.
Pas de déclaration pour NbNotes, commandByte, etc.
Mais tu verras tout ça lors de la première compilation.

D'un point de vue matériel, tu as fait des choix ?

@+

Attention, si tu fais le contrôle du code après l'appui de 5 touches, tu risques de te retrouver dans un problème de synchronisation /décalage à chaque essai. Il faudra bien déterminer le temps de réinitialisation du code.

Pense à gérer la pression de plusieurs touches en même temps. Un Key On n'est pas forcément suivi par un Key Off.

Édit: ça sent l'escape room version goonies

D'un point de vue matériel, tu as fait des choix ?

Euh... Il me semble avoir tout détaillé dans mon post initial. Tu vois des éléments manquants ?

Attention, si tu fais le contrôle du code après l'appui de 5 touches, tu risques de te retrouver dans un problème de synchronisation /décalage à chaque essai. Il faudra bien déterminer le temps de réinitialisation du code.

Normalement non. J'avais justement pensé mon programme pour que le tableau ne garde en mémoire que les 5 dernières touches appuyées. Donc si tu joues "do mi sol do ré mi do ré mi fa sol", ton tableau gardera "do ré mi fa sol" en mémoire et la led verte s'allumera. Par contre, un appui de plus sur une touche rebasculera sur la led rouge. Mais ça me va !

Pense à gérer la pression de plusieurs touches en même temps. Un Key On n'est pas forcément suivi par un Key Off.

Arf ! Je n'avais pas pensé ça... Comment ça se passe côté MIDI quand 2 touches sont appuyées en même temps ? C'est considéré comme 2 octets simultanés ou comme un seul octet qui fusionne les 2 notes ?

Tu reçois le premier Key On de la première touche enfoncée puis le Key On de la seconde. Idem pour les Keys Off.

Édit: tu peux éventuellement ne détecter que les Keys On. A Partir du moment où les touches sont enfoncées dans le bon ordre, relâchées ou non, ça valide.

Édit: tu peux éventuellement ne détecter que les Keys On. A Partir du moment où les touches sont enfoncées dans le bon ordre, relâchées ou non, ça valide.

OK super ! Je vais essayer de partir sur ça alors.

Sinon ça vous semble possible de "programmer" chaque note en amont avant de les utiliser dans ma boucle de code ?

Et j'ai une autre question : comment on fait, une fois le shield posé sur l'Arduino, pour cabler le reste du circuit. Plus aucun pin n'est dispo du coup ?

Les notes ne sont que des données que tu compares à d'autres. Chaque note est exprimée par un entier de 0 à 127 donc l'ensemble représente ton clavier.

Pour le shield, j'imagine que toutes les broches ne sont pas utilisées, n'y a t'il pas un moyen de repiquer les signaux ?

Édit: sur la photo de ton lien, on peut voir qu'un emplacement est prévu pour reprendre les signaux des broches. A toi de rajouter des connecteurs type dupont pour exploiter les autres broches de l'arduino.

FoNeTiK47:
OK super ! Je vais essayer de partir sur ça alors.

Sinon ça vous semble possible de "programmer" chaque note en amont avant de les utiliser dans ma boucle de code ?

Et j'ai une autre question : comment on fait, une fois le shield posé sur l'Arduino, pour cabler le reste du circuit. Plus aucun pin n'est dispo du coup ?

Bonsoir
Tu viens de mettre le doigt sur la principale limitation du concept là de "shield "
le besoin de connexion entre un arduino et ton shield MIDI se limite à 4 "fils"

  • +5V
  • GND
    -TX
    -RX

Les TX et RX de ton shield peuvent tres bien etre dirigés vers autre chose que les pin 0/1 de ton arduino
par exemple pour gérer du MIDI en serial software.
Le debit du MIDI est en 31250 , on peut déjà faire pas mal de chose (comme ce qu tu envisage ) avec la lib MIDI

le besoin de connexion entre un arduino et ton shield MIDI se limite à 4 "fils"

Tu veux dire que si je mets ça sur une breadboard à côté et que je relie ces 4 fils comme il faut, ça peut le faire ? Ou bien que si j'avais fait le montage moi-même ça ne m'aurait pris que 4 pins ?

sur la photo de ton lien, on peut voir qu'un emplacement est prévu pour reprendre les signaux des broches. A toi de rajouter des connecteurs type dupont pour exploiter les autres broches de l'arduino.

Tu parles de ce qu'on voit en bas de la carte ? Ce n'est ni plus ni moins que le report de mes pins inutilisés par le shield ?

FoNeTiK47:
Tu veux dire que si je mets ça sur une breadboard à côté et que je relie ces 4 fils comme il faut, ça peut le faire ? Ou bien que si j'avais fait le montage moi-même ça ne m'aurait pris que 4 pins ?

Pour faire court : oui