Go Down

Topic: Utilisation shield midi in/out (Read 1 time) previous topic - next topic

FoNeTiK47

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é :

https://www.thomann.de/fr/miditech_midistart_music_25.htm

Le câble qui relie le clavier au shield :

https://www.amazon.fr/gp/product/B07DDGD53V/ref=oh_aui_detailpage_o03_s01?ie=UTF8&psc=1

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 !  :smiley-confuse:

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 ? ( :D joke of course !)


Leptro

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+







FoNeTiK47

Quote
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... ^^'

Quote
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.

Quote
Un arduino avec minimum 2 uart serait plus approprié ( ex: arduino uno R4 )
C'est quoi des "uart" ?

al1fch

#3
Oct 30, 2018, 10:47 am Last Edit: Oct 30, 2018, 10:49 am by al1fch
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









Zlika

#4
Oct 30, 2018, 06:24 pm Last Edit: Oct 30, 2018, 08:38 pm by Zlika
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.
Si ça coince, forcez. Si ça casse, ça devait probablement être réparé, de toute façon.

FoNeTiK47

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 !

Quote
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 ?

Quote
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é.

Quote
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...

Zlika

#6
Oct 31, 2018, 09:37 am Last Edit: Oct 31, 2018, 09:41 am by Zlika
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.
Si ça coince, forcez. Si ça casse, ça devait probablement être réparé, de toute façon.

hbachetti

#7
Oct 31, 2018, 11:15 am Last Edit: Oct 31, 2018, 11:16 am by hbachetti
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.

Quote
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).

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

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

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

FoNeTiK47

Quote
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.

Quote
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.



FoNeTiK47

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) :

Code: [Select]
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 :

Code: [Select]
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 ?

hbachetti

Code: [Select]
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 ?

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Zlika

#12
Nov 01, 2018, 03:03 pm Last Edit: Nov 01, 2018, 03:13 pm by Zlika
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
Si ça coince, forcez. Si ça casse, ça devait probablement être réparé, de toute façon.

FoNeTiK47

Quote
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 ?

Quote
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 !

Quote
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 ?

Zlika

#14
Nov 01, 2018, 03:29 pm Last Edit: Nov 01, 2018, 03:40 pm by Zlika
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.
Si ça coince, forcez. Si ça casse, ça devait probablement être réparé, de toute façon.

Go Up