Problème réception message midi

Bonjour, je me présente, je m’appel Mickael, j’essai de réaliser un contrôleur MIDI avec une arduino MEGA 2560.

Je m’excuse d’avance pour les brûlures oculaire que risque d’occasionner mes multiples faute d’orthographe pour certain. Mais ça n’a jamais été mon fort donc je préfère prévenir d’office.

Alors!!! j’essai de créer un code pour recevoir des messages midi de type Pitch bend venant de cubase via le Protocol mackie control, en gros je doit lire le pitch bend du cannal 1. Avec se code j’arrive à recevoir le message voulu mais une seul fois. Je ne suis pas sur mais j’ai l’impression qu’il ne reçois pas en continu les messages entrant. Voila le code que j’utilise.

byte commandByte;
byte Data1;
byte Data2;
int pitchbend = B11100000;//11100000 in binary, pitchbend command channel 1
int value;

void setup(){
  Serial1.begin(31250);
  Serial.begin(9600);
}

void checkMIDI(){
  do{
    if (Serial1.available()){
      commandByte = Serial1.read();//read first byte
      Data1 = Serial1.read();//read next byte
      Data2 = Serial1.read();//read final byte
    }
  }
  while (Serial1.available() > 0);//when at least three bytes available
   if (commandByte == pitchbend){value = (((Data2 << 7) + Data1)*0.0625);
  }
}
    

void loop(){
  checkMIDI();
  Serial.println(value);
}

Si quelqu’un pouvait m’aider à comprendre mon erreur. Je lui en serait reconnaissant. Merci

Ton code attend qu'il n'y ait plus rien de disponible sur le MIDI. Si tu reçois une bordée de messages, tu les traites tous dans ta boucle do... while, jusqu'au dernier. Là tu sors de la boucle, tu calcules la valeur du bend et tu l'imprime. Le dernier, uniquement.

Ha!! Ok, j'ai oublié de préciser que je début!!! mais j'imagine que ça doit se voir lol. bref!!!!

Bon ben déjà merci pour ta réponse. Y aurait-il une solution pour palier se problème?

Louta: Ha!! Ok, j'ai oublié de préciser que je début!!! mais j'imagine que ça doit se voir lol. bref!!!!

Bon ben déjà merci pour ta réponse. Y aurait-il une solution pour palier se problème?

bonsoir Tu gere mal ce qui est dans le buffer hard serial1 (configuré en entrée MIDI) - tu dois verifier qu'au moins 3 bytes sont dispo dans le buffer - ensuite verifier et affecter selon l'ordonnancement attendu extrait d'un code midi tournant sur mega et a adapter à ton cas

if (Serial1.available() > 2) { // au moins 3 bytes dispo dans le buffer d'entrée
    inByte = Serial1.read();
    if (inByte > 127) { // le byte entrant est le byte de status MIDI
      
      inByte = Serial1.read(); // lecture du byte de data 1 MIDI
      
      inByte = Serial1.read(); // lecture du byte de data 2 MIDI
      
    }
  }

Merci Artouste, mais je dois t'avouer que là!!! tu ma parler en "chinois" ou presque. ça fait que très peut de temps que j'utilise une arduino et que je programme d’ailleurs. Je comprend se que tu me dit de faire mais je n'ai aucune idée de comment on doit faire.

Dans le morceau de code que tu ma donné j'ai juste l'impression qu'il y à trois fois les même donnée pourtant dans le descriptif des lignes, la même phrase à un objectif différent. et à partir de là je suis paumé.

Je vous remercie vraiment de m'aider mais j'ai besoin d'explication pour débutant.

En fait je ne comprend pas pourquoi ils s'appel tous "inByte". Ils ne doivent pas avoir des noms différents?

Louta: En fait je ne comprend pas pourquoi ils s'appel tous "inByte". Ils ne doivent pas avoir des noms différents?

C'est juste un exemple non-fonctionnel. A toi de leur donner des noms différents (octet1, octet2, octet3 par ex.) et de les utiliser selon ton besoin.

C'est se que j'ai fait du coup. Mais j'ai beau tourner se code (et tout ceux que j'ai trouvé sur le web d'ailleurs ) dans tout les sens, j'arrive toujours au même résultat. Voir pire des fois. Si je faisais une video de mon problème ça pourrait peut être vous aider à comprendre mon souci, non?

On peut poster des videos directement sur le forum?

Louta:
C’est se que j’ai fait du coup. Mais j’ai beau tourner se code (et tout ceux que j’ai trouvé sur le web d’ailleurs ) dans tout les sens, j’arrive toujours au même résultat. Voir pire des fois. Si je faisais une video de mon problème ça pourrait peut être vous aider à comprendre mon souci, non?

On peut poster des videos directement sur le forum?

bonjour
le code ci- dessous doit repondre à ce que tu attend
j’ai commenté au mieux pour que tu comprenne
compile OK
pas testé

byte inByte;
byte Data1;
byte Data2;
byte pitchbend = B11100000;//11100000 in binary, pitchbend command channel 1
int value;

void setup() {
  Serial1.begin(31250);//entree midi
  Serial.begin(9600); // sortie Monitoring 
}

void loop() {


  if (Serial1.available() > 2) { // au moins 3 bytes dispo dans le buffer d'entrée
    inByte = Serial1.read();
    if (inByte > 127) { // le byte entrant est un  byte de status MIDI

      Data1 = Serial1.read(); // lecture du byte de data 1 MIDI

      Data2 = Serial1.read(); // lecture du byte de data 2 MIDI

    }
    if (inByte == pitchbend) {  // pitchbend sur canal1 trouvé

      value = Data2 ;
      value = value << 7; //MSB
      value = value + Data1; //+LSB
      Serial.println(value); //(monitoring sur serial)
    }
  }
}

Merci à vous deux pour le temps que vous passez à m’aider. J’ai essayé ton code et le résultat est le même. Par contre ça me rassure parce qu’ou moins je voie que j’avais bien compris se qu’il fallait faire.

j’ai juste du modifier l’endroit du serial.print sinon ça me donnais aucune info.

comme ça:

byte inByte;
byte Data1;
byte Data2;
byte pitchbend = B11100000;//11100000 in binary, pitchbend command channel 1
int value;

void setup() {
  Serial1.begin(31250);//entree midi
  Serial.begin(9600); // sortie Monitoring 
}

void loop() {


  if (Serial1.available() > 2) { // au moins 3 bytes dispo dans le buffer d'entrée
    inByte = Serial1.read();
    if (inByte > 127) { // le byte entrant est un  byte de status MIDI

      Data1 = Serial1.read(); // lecture du byte de data 1 MIDI

      Data2 = Serial1.read(); // lecture du byte de data 2 MIDI

    }
    if (inByte == pitchbend) {  // pitchbend sur canal1 trouvé

      value = Data2 ;
      value = value << 7; //MSB
      value = value + Data1; //+LSB

    }
  }
        Serial.println(value); //(monitoring sur serial)
}

J’ai essayé plein de truc et rien n’y fait!!! vous avez d’autre idée?

Louta: Merci à vous deux pour le temps que vous passez à m'aider. J'ai essayé ton code et le résultat est le même. Par contre ça me rassure parce qu'ou moins je voie que j'avais bien compris se qu'il fallait faire.

j'ai juste du modifier l'endroit du serial.print sinon ça me donnais aucune info.

A priori mon code etait ok - est tu sur d'injecter correctement ta trame midi pitchbnd ? - est tu sur déjà d'injecter du midi(conforme) dans le serial1 de ta mega ? comment verifie tu cela ?

Ci dessous un petit code tout simple pour verifier si il y a de l'info un peu coherente midi qui entre dans la mega. -entrée midi sur serial1 de la mega - monitoring sur serial de la mega : NB : j'ai passé la vitesse de à 115200 fais un log du serial , lorsque tu injecte du midi (pitch bend ou autre) et poste le resultat

byte inByte;
byte Data1;
byte Data2;


void setup() {
  Serial1.begin(31250);//entree midi
  Serial.begin(115200); // sortie Monitoring
}

void loop() {


  if (Serial1.available() > 2) { // au moins 3 bytes dispo dans le buffer d'entrée
    inByte = Serial1.read();
    if (inByte > 127) { // le byte entrant est un  byte de status MIDI
      Serial.print("-C: ");
      Serial.print(inByte, HEX);
      Serial.print(" D1:");
      Data1 = Serial1.read(); // lecture du byte de data 1 MIDI
      Serial.print(Data1, HEX);
      Data2 = Serial1.read(); // lecture du byte de data 2 MIDI
      Serial.print(" D2:");
      Serial.print(Data2, HEX);
      Serial.println();
    }

  }
}

OK!!!!! Bon alors merci pour ton code, j'aurai pue y penser avant c'était pas très compliquer et en plus ça ma permis de comprendre d'autre choses.

Bon alors du coup se qu'il se passe c'est qu'il envoi une seul fois le message identifiant le pitch bend (224) et en suite il n'envoi que les bytes de donnée.

Du coup avec le code que j'ai il déclenche la lecture uniquement quand il reçois le bytes pitch bend et lis les deux bytes suivant et après il s'arrête.

Il faut donc que je trouve un moyen de déclenche le bytes de pitch bend et après qu'il lise en boucle les donnée qui entre même si c'est pas des pitch bend mais du coup il faut aussi qu'il lise que les messages data1 et 2 du pitch bend et pas les autres messages entrant.

Bon!!! à partir de là j'ai plus qu'a trouver la bonne formulation.

Louta:

Bon alors du coup se qu’il se passe c’est qu’il envoi une seul fois le message identifiant le pitch bend (224) et en suite il n’envoi que les bytes de donnée.

Du coup avec le code que j’ai il déclenche la lecture uniquement quand il reçois le bytes pitch bend et lis les deux bytes suivant et après il s’arrête.

Il faut donc que je trouve un moyen de déclenche le bytes de pitch bend et après qu’il lise en boucle les donnée qui entre même si c’est pas des pitch bend mais du coup il faut aussi qu’il lise que les messages data1 et 2 du pitch bend et pas les autres messages entrant.

Bon!!! à partir de là j’ai plus qu’a trouver la bonne formulation.

Bonsoir
:grin:

C’est quoi ce “il” ?

dans la mesure où , “on” ne sait pas ce que tu veux faire avec ta mega à la suite d’une réception d’une trame midi .

le dernier code "valide " simplement que de la reception de messages MIDI coherents est effectuée sur serial1 !

Après… 8)

Je l'ai indiqué dans mon premier post, le "il" c'est cubase qui envoi des messages midi via le Protocol mackie control universel.

Pour en dire plus:

La Mackie Control Universal où "MCU" est une surface de Control hardware qui pilote des logiciels de musique (ou autre d’ailleurs) qui communique en midi.

le but étant de réceptionner ses messages afin de piloter un fader (ou potentiomètre à glissière) motorisé pour lui indiquer la position ou il devrait être.

Et tout ça dans le but d'automatiser un table de mixage que je suis en train de me fabriquer.

Dans le flux MIDI que tu reçois sur l'Arduino, y-a-t-il des messages autres que le pitch bend ? Tous les messages MIDI ne font pas forcément 3 octets, par exemple les messages Program Change font deux octets. Il existe également un mode "Running Status" dans lequel l'octet de commande n'est pas émis s'il est identique à celui du précédent message. Ce que ferais, c'est commencer par examiner le flux MIDI octet par octet, pour être bien sûr de ce que tu reçois.

void loop () {
  if ( Serial1.avalaible() ) {
    uint8_t octet = Serial1.read();
    if ( octet >= 0x80 )
      Serial.println ( "" );

    Serial.print ( octet, HEX ); Serial.print ( " " );
  }
}

Oui il y a beaucoup de message, le protocole mackie control envoi continuellement des donnée "systemEX" et autre surtout quand on passe Cubase en lecture, la ça envoi dans tout les sens.

Dans ce cas, il va falloir traiter tout ce qui est reçu par l'Arduino, c-à-d identifier tous les messages MIDI pour sauter ceux qui ne t'interessent pas, en tenant compte des longueurs différentes selon les messages. Ca va faire un programme bien plus compliqué que ceux vus sur ce fil de discussion !