Se connecter
Se connecter

ou
Créer un compte

ou
FR
EN
Les Mains dans le Cambouis

Un contrôleur midi 100 basé sur Arduino

  • 90 réponses
  • 20 participants
  • 23 088 vues
  • 26 followers
Sujet de la discussion Un contrôleur midi 100 basé sur Arduino

Suite a la discussion sur ce contrôleur:https://fr.audiofanzine.com/surface-de-controle-midi/cme/BitStream-3X/forums/t.541700,mais-ou-le-trouver.html

Je viens jeter ici les bases pour la construction d'un contrôleur midi basé sur Arduino.

Certains pensaient que vu le nombre d'entrée analogique limitée sur une carte Arduino elle ne permettait pas l'utilisation de cette plateforme pour ce genre d'application. Ce n'est évidement pas le cas, il suffit de connaître un peu l'électronique et la programmation pour arriver a un résultat ma fois pas trop mal et peu coûteux.

Comme le montre l'image ci-dessous en utilisant des multiplexer il est possible de multiplier le nombre d'entrée/sortie avec en théorie un maximum de 1024 E/S sur une Arduino Mega.

Donc l'idée de ce fil est de jeter sur le papier le minimum requis pour une interface Midi

Sachant que l'arduino est limité en terme de mémoire (SRAM 2Kb au max) ce qui limite les variables (on en discute ?)

Sachant que l'Arduino est limité en terme de puissance "électrique", 40ma par PIN (on en discute ?)

Liste "A faire"

  1. Gestion EEPROM
  2. Alimentation externe
  3. Calcul d'un boucle sur 80 contrôle

[ Dernière édition du message le 13/09/2013 à 13:00:28 ]

Afficher le sujet de la discussion
26
En effet ce n'est pas sur le schéma mais il faut connecter 6, 7 et 8 a la masse. Je corrige histoire de ne pas mettre les éventuelles intéressés dans l'erreur.

[ Dernière édition du message le 18/09/2013 à 19:04:29 ]

27
image.php

Voici donc la maquette qui va servir pour la mise au point du code.
28
image.php
29
Voici le code pour tester la maquette.

Ca fonctionne particulièrement bien.
J'ai remarqué que j'avais monté la polarité de mes potentiomètres a l'envers.
On peux facilement bouger deux, voir trois potentiomètres en même temps, sans aucun problème.
Je prépare le code définitif avec le code MIDI permettant l'utilisation en situation réelle.

int selection0MuxPrimaire = 3;
int selection1MuxPrimaire = 4;
int selection2MuxPrimaire = 5;
int selection0MuxSecondaire = 6;
int selection1MuxSecondaire = 7;
int selection2MuxSecondaire = 8;

int sel0;
int sel1;
int sel2;

int bouclePrimaire;
int boucleSecondaire;

int boutonEntre = 9;
int bouton[4];
int boutonEtat[4]={0, 0, 0, 0};
int boutonCC[4]={10, 20, 30, 40};

int potentiometreEntre = 0;
int potentiometre[8];
int potentiometreCC[8]={11, 21, 31, 41, 51, 61, 71, 81};

// Canal midi de 176 à 191
int midiChannel = 176;

void setup(){
// Ouverture du port serie proche de la vitesse du Midi(31250) pour debut seulement
Serial.begin(28800);
// Configuration des ports Arduino E/S
pinMode(selection0MuxPrimaire, OUTPUT);
pinMode(selection1MuxPrimaire, OUTPUT);
pinMode(selection2MuxPrimaire, OUTPUT);
pinMode(selection0MuxSecondaire, OUTPUT);
pinMode(selection1MuxSecondaire, OUTPUT);
pinMode(selection2MuxSecondaire, OUTPUT);
pinMode(boutonEntre, INPUT);
}

void loop(){
// Scan et lecture des boutons
//Boucle de selection du Mux B1 pour 4 boutons
for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){
    // Transformation en binaire de la variable boucleSecondaire
    sel0 =bitRead(boucleSecondaire, 0) ;
    sel1 =bitRead(boucleSecondaire, 1) ;
    sel2 =bitRead(boucleSecondaire, 2) ;
    // Selection du port sur le 4051 Mux B3
    digitalWrite(selection0MuxSecondaire, sel0);
    digitalWrite(selection1MuxSecondaire, sel1);
    digitalWrite(selection2MuxSecondaire, sel2);
    // Delay d'attente avant capture du port Data, valeur à mettre au plus bas possible.
      delayMicroseconds(90);
  

        // Echange entre 0 ou 127
        if (boutonEtat[bouclesecondaire] == 0 && digitalRead(boutonEntre) == HIGH) {
        boutonEtat[bouclesecondaire]= 1;
        bouton[bouclesecondaire]= !bouton[bouclesecondaire];
        // Envois vers le port Serie pour debug, sera remplacé par le code MIDI
        Serial.print (" Pression sur le bouton ");
        Serial.print (boucleSecondaire+1);
             Serial.print (" > ");
             Serial.print("176 ");
             Serial.print(boutonCC[bouclesecondaire]);
             Serial.print(" ");
             Serial.println(bouton[bouclesecondaire]*127);
        }
        // Si bouton relacher, pret a capturer une nouvelle valeur  
           if (boutonEtat[bouclesecondaire] == 1 && digitalRead(boutonEntre) == LOW){
           boutonEtat[bouclesecondaire]=0;
          }
     }



// Scan et lecture des potentiometres
// Boucle de selection du Mux B2 ou Mux B3
for (bouclePrimaire = 0; bouclePrimaire < 2; bouclePrimaire++){
    // Transformation en binaire de la variable bouclePrimaire
    sel0 =bitRead(bouclePrimaire, 0) ;
    sel1 =bitRead(bouclePrimaire, 1) ;
    sel2 =bitRead(bouclePrimaire, 2) ;
    // Selection du port sur le 4051 Mux A
    digitalWrite(selection0MuxPrimaire, sel0);
    digitalWrite(selection1MuxPrimaire, sel1);
    digitalWrite(selection2MuxPrimaire, sel2);

    // Boucle de lecture Mux Bn pour 4 entrees
    for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){
        // Transformation en binaire de la variable boucleSecondaire
        sel0 =bitRead(boucleSecondaire, 0) ;
        sel1 =bitRead(boucleSecondaire, 1) ;
        sel2 =bitRead(boucleSecondaire, 2) ;
        // Selection du port sur le 4051 Mux Bn
        digitalWrite(selection0MuxSecondaire, sel0);
        digitalWrite(selection1MuxSecondaire, sel1);
        digitalWrite(selection2MuxSecondaire, sel2);
        // Delay d'attente avant capture du port Data, valeur à mettre au plus bas possible.
        delayMicroseconds(75);


            // Lecture de la valeur du potentiometre(n)
            // Verification de la valeur ancienne et valeur actuelle base sur 4 potentiometre par mux
            if (analogRead(potentiometreEntre) != potentiometre[bouclesecondaire + (bouclePrimaire * 4)]){
                potentiometre[bouclesecondaire + (bouclePrimaire * 4)] = analogRead(potentiometreEntre);
                Serial.print("Potentiometre ");
                                Serial.print(boucleSecondaire +(bouclePrimaire * 4));
                                Serial.print(" > ");
                                Serial.print(midiChannel);
                                Serial.print(" ");
                                Serial.print(potentiometreCC[bouclesecondaire + (bouclePrimaire * 4)]);
                                Serial.print(" ");
                                Serial.println(potentiometre[bouclesecondaire + (bouclePrimaire * 4)]);
            }
           }
}

[ Dernière édition du message le 19/09/2013 à 08:50:31 ]

30
Ca prend forme, très bien !

Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com

31
Et le code finale que je décortiquerai dans un prochain poste:


int selection0MuxPrimaire = 3;
int selection1MuxPrimaire = 4;
int selection2MuxPrimaire = 5;
int selection0MuxSecondaire = 6;
int selection1MuxSecondaire = 7;
int selection2MuxSecondaire = 8;

int sel0;
int sel1;
int sel2;

int bouclePrimaire;
int boucleSecondaire;

int boutonEntre = 9;
int bouton[4];
int boutonEtat[4]={
  0, 0, 0, 0};
int boutonCC[4]={
  10, 20, 30, 40};

int potentiometreEntre = 0;
int potentiometre[8];
int potentiometreCC[8]={
  11, 21, 31, 41, 51, 61, 71, 81};

// Canal midi de 176 à 191
int midiChannel = 176;

void setup(){
  // Ouverture du port serie proche de la vitesse du Midi(31250) pour debut seulement
  Serial.begin(31250);
  // Configuration des ports Arduino E/S
  pinMode(selection0MuxPrimaire, OUTPUT);
  pinMode(selection1MuxPrimaire, OUTPUT);
  pinMode(selection2MuxPrimaire, OUTPUT);
  pinMode(selection0MuxSecondaire, OUTPUT);
  pinMode(selection1MuxSecondaire, OUTPUT);
  pinMode(selection2MuxSecondaire, OUTPUT);
  pinMode(boutonEntre, INPUT);
}

void loop(){
  // Scan et lecture des boutons
  //Boucle de selection du Mux B1 pour 4 boutons
  for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){
    // Transformation en binaire de la variable boucleSecondaire
    sel0 =bitRead(boucleSecondaire, 0) ;
    sel1 =bitRead(boucleSecondaire, 1) ;
    sel2 =bitRead(boucleSecondaire, 2) ;
    // Selection du port sur le 4051 Mux B3
    digitalWrite(selection0MuxSecondaire, sel0);
    digitalWrite(selection1MuxSecondaire, sel1);
    digitalWrite(selection2MuxSecondaire, sel2);
    // Delay d'attente avant capture du port Data, valeur à mettre au plus bas possible.
    //delayMicroseconds(90);


    // Echange entre 0 ou 127
    if (boutonEtat[bouclesecondaire] == 0 && digitalRead(boutonEntre) == HIGH) {
      boutonEtat[bouclesecondaire]= 1;
      bouton[bouclesecondaire]= !bouton[bouclesecondaire];
      // Envois vers le port Serie pour debug, sera remplacé par le code MIDI
      Serial.write(midiChannel);
      Serial.write(boutonCC[bouclesecondaire]);
      Serial.write(bouton[bouclesecondaire]*127);
    }
    // Si bouton relacher, pret a capturer une nouvelle valeur  
    if (boutonEtat[bouclesecondaire] == 1 && digitalRead(boutonEntre) == LOW){
      boutonEtat[bouclesecondaire]=0;
    }
  }



  // Scan et lecture des potentiometres
  // Boucle de selection du Mux B2 ou Mux B3
  for (bouclePrimaire = 0; bouclePrimaire < 2; bouclePrimaire++){
    // Transformation en binaire de la variable bouclePrimaire
    sel0 =bitRead(bouclePrimaire, 0) ;
    sel1 =bitRead(bouclePrimaire, 1) ;
    sel2 =bitRead(bouclePrimaire, 2) ;
    // Selection du port sur le 4051 Mux A
    digitalWrite(selection0MuxPrimaire, sel0);
    digitalWrite(selection1MuxPrimaire, sel1);
    digitalWrite(selection2MuxPrimaire, sel2);

    // Boucle de lecture Mux Bn pour 4 entrees
    for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){
      // Transformation en binaire de la variable boucleSecondaire
      sel0 =bitRead(boucleSecondaire, 0) ;
      sel1 =bitRead(boucleSecondaire, 1) ;
      sel2 =bitRead(boucleSecondaire, 2) ;
      // Selection du port sur le 4051 Mux Bn
      digitalWrite(selection0MuxSecondaire, sel0);
      digitalWrite(selection1MuxSecondaire, sel1);
      digitalWrite(selection2MuxSecondaire, sel2);
      // Delay d'attente avant capture du port Data, valeur à mettre au plus bas possible.
      //delayMicroseconds(75);


      // Lecture de la valeur du potentiometre(n)
      // Verification de la valeur ancienne et valeur actuelle base sur 4 potentiometre par mux
      if (analogRead(potentiometreEntre)/8 != potentiometre[bouclesecondaire + (bouclePrimaire * 4)]){
        potentiometre[bouclesecondaire + (bouclePrimaire * 4)] = analogRead(potentiometreEntre)/8;
       Serial.write(midiChannel);
       Serial.write(potentiometreCC[bouclesecondaire + (bouclePrimaire * 4)]);
       Serial.write(potentiometre[bouclesecondaire + (bouclePrimaire * 4)]);
      }
    }
  }
}


En tournant un potentiomètre très vite j'obtiens des valeurs de timing plus qu'honnête.
Entre 2 et 5 millisecondes c'est vraiment pas mal.
Sans la fonction "delay" je n'ai aucune erreur de lecture des potentiomètres ou des boutons.
En l'état cette maquette fonctionne parfaitement.


09:50:54.878 From UltraLite mk3 Hybrid MIDI Port Control 1 81 4
09:50:54.880 From UltraLite mk3 Hybrid MIDI Port Control 1 81 3
09:50:54.884 From UltraLite mk3 Hybrid MIDI Port Control 1 81 2
09:50:54.888 From UltraLite mk3 Hybrid MIDI Port Control 1 81 1
09:50:54.893 From UltraLite mk3 Hybrid MIDI Port Control 1 81 0

Comme je n'ai pas de processus qui permet de retenir la position des potentiomètres a l'extinction, si je fais un reset ou bien je fais un cycle éteindre/allumer. L'interface MIDI envois vers le canal choisis la valeur actuelle des potentiomètres. Et là c'est de l'ordre de la milliseconde.

10:03:06.634 From UltraLite mk3 Hybrid MIDI Port Control 1 11 23
10:03:06.635 From UltraLite mk3 Hybrid MIDI Port Control 1 21 11
10:03:06.636 From UltraLite mk3 Hybrid MIDI Port Control 1 31 2
10:03:06.636 From UltraLite mk3 Hybrid MIDI Port Control 1 51 19
10:03:06.637 From UltraLite mk3 Hybrid MIDI Port Control 1 61 35
10:03:06.638 From UltraLite mk3 Hybrid MIDI Port Control 1 71 55
10:03:06.639 From UltraLite mk3 Hybrid MIDI Port Control 1 81 12
32
Citation :
int selection0MuxPrimaire = 3;
int selection1MuxPrimaire = 4;
int selection2MuxPrimaire = 5;
int selection0MuxSecondaire = 6;
int selection1MuxSecondaire = 7;
int selection2MuxSecondaire = 8;

Cette première partie sélectionne les ports de l'Arduino où sont connectés les ports de sélection des ports d'entrés des 4051.
Vous remarquerez que pour ma part j'ai du commencer au port 3 alors que le schéma montre le port 2.
Le miens, de port 2, est mort, je me suis donc adapté.

Citation :
int sel0;
int sel1;
int sel2;

Les trois variables ou seront stockés la valeurs des ports de sélections.

Citation :
int bouclePrimaire;
int boucleSecondaire;

Les variables pour les deux boucles.

Citation :
int boutonEntre = 9;
int bouton[4];
int boutonEtat[4]={
0, 0, 0, 0};
int boutonCC[4]={
10, 20, 30, 40};

Les variables pour les boutons.
BoutonEntre est le port ou les données arrive sur l'Arduino en provenance du port de sortie du 4051.
Bouton[] et le tableau des valeurs actuelle des boutons. Ici de 1 à 4.
BoutonsEtat et une valeur indicative sur le dernier état du bouton pour éviter un phénomène de rebond.
BoutonCC est la valeur CC de chaque bouton.

Citation :
int potentiometreEntre = 0;
int potentiometre[8];
int potentiometreCC[8]={
11, 21, 31, 41, 51, 61, 71, 81};

Les variables pour les potentiomètres.
Potentiomètre[] est la valeur actuelle du potentiomètre[n]
potentiomètreCC est le valeur CC pour chaque potentiomètre.

Citation :
int midiChannel = 176;

Numéro du canal MIDI de destination des CC. 176 à 191 pour 1 à 16.

Citation :
void setup(){
Serial.begin(31250);

Ouverture du port série avec une vitesse de 31250 kb/s qui est la vitesse d'un port MIDI.

Citation :
pinMode(selection0MuxPrimaire, OUTPUT);
pinMode(selection1MuxPrimaire, OUTPUT);
pinMode(selection2MuxPrimaire, OUTPUT);
pinMode(selection0MuxSecondaire, OUTPUT);
pinMode(selection1MuxSecondaire, OUTPUT);
pinMode(selection2MuxSecondaire, OUTPUT);
pinMode(boutonEntre, INPUT);
}

Les ports logique d'un arduino doivent être configurer soit en sortie, soit en entré.
PinMode en est la commande. Les ports de sélections sont des sorties pour l'Arduino alors que BoutonEntre est un port d'entré.


Citation :
void loop(){

Boucle principale du programme

Citation :
// Scan et lecture des boutons
for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){

Cette boucle sert a scanner les ports d'entrés du 4051 pour les boutons (Mux B1).
Comme il y a 4 boutons, cette boucle se fait 4 fois.

Citation :
// Transformation en binaire de la variable boucleSecondaire
sel0 =bitRead(boucleSecondaire, 0) ;
sel1 =bitRead(boucleSecondaire, 1) ;
sel2 =bitRead(boucleSecondaire, 2) ;

Stockage de la valeur en binaire.

Citation :
digitalWrite(selection0MuxSecondaire, sel0);
digitalWrite(selection1MuxSecondaire, sel1);
digitalWrite(selection2MuxSecondaire, sel2);

Ouverture du port par selection sur les pin du 4051.

Citation :
if (boutonEtat[bouclesecondaire] == 0 && digitalRead(boutonEntre) == HIGH) {
boutonEtat[bouclesecondaire]= 1;

Par défaut boutEtat[n] est à zéro. Si la valeur du port est différente alors on considére que le bouton est poussé et on continue. Sinon on passe a la ligne suivante (après la fermeture du braquet plus bas)

Citation :
bouton[bouclesecondaire]= !bouton[bouclesecondaire];

On inverse la valeur du bouton: si il est à 0 alors 1, si il est à 1 alors 0.

Citation :
Serial.write(midiChannel);
Serial.write(boutonCC[bouclesecondaire]);
Serial.write(bouton[bouclesecondaire]*127);

Ici on envois sur le port série les trois valeurs : le canal midi, la valeur CC du bouton pressé et la valeur 0 ou 1 mulitplié par 127.

Serial.write écrit en mode binaire et c'est ce qui est attendu par le port d'entré de votre interface midi que vous voulez commander.
Serial.print écrit en mode ASCII pour pouvoir être lu par un humain.

}

Braquet de fermeture de la condition bouton pousser.

Citation :
if (boutonEtat[bouclesecondaire] == 1 && digitalRead(boutonEntre) == LOW){
boutonEtat[bouclesecondaire]=0;

Si le bouton est relaché alors on passe le bouton Etat à Zero permettant l'entré d'une nouvelle valeur 0 ou 1. Sinon on passe a la ligne suivante (après le braquet de fermeture de cette condition)

Citation :
}

Braquet de fermeture de la condition bouton relaché

Citation :
}

Braquet de fermeture de la boucle


Citation :
for (bouclePrimaire = 0; bouclePrimaire < 2; bouclePrimaire++){
sel0 =bitRead(bouclePrimaire, 0) ;
sel1 =bitRead(bouclePrimaire, 1) ;
sel2 =bitRead(bouclePrimaire, 2) ;
digitalWrite(selection0MuxPrimaire, sel0);
digitalWrite(selection1MuxPrimaire, sel1);
digitalWrite(selection2MuxPrimaire, sel2);
for (boucleSecondaire = 0; boucleSecondaire < 4; boucleSecondaire++){
sel0 =bitRead(boucleSecondaire, 0) ;
sel1 =bitRead(boucleSecondaire, 1) ;
sel2 =bitRead(boucleSecondaire, 2) ;
digitalWrite(selection0MuxSecondaire, sel0);
digitalWrite(selection1MuxSecondaire, sel1);
digitalWrite(selection2MuxSecondaire, sel2);

Comme nous avons deux 4051 connectés sur un autre 4051 il faut deux boucles.
Une première boucle pour sélectionner le port d’écoute du premier 4051 et a l’intérieur de cette boucle, une seconde qui écoute les ports du second étage 4051.

Donc :
Premier passage:
MUX A port 1
Mux B2 port 1
Mux B2 port 2
Mux B2 port 3
Mux B2 port 4

Second passage:
Mux A port 2
Mux B3 port 1
Mux B3 port 2
Mux B3 port 3
Mux B3 port 4

Si il y avait un ou deux 4051 supplémentaire il faut alors changer la valeur bouclePrimaire < 2 en bouclePrimaire < 4
Si il y avait 8 potentiomètres par 4051 il faut alors changer la valeur boucleSecondaire < 4 en boucleSecondaire < 8

Citation :
if (analogRead(potentiometreEntre)/8 != potentiometre[bouclesecondaire + (bouclePrimaire * 4)]){

Par défaut et au démarrage, la valeur des potentiomètres est de Zéro, nous vérifions ici la valeur du potentiomètre et si elle est différente alors on procède sinon on passe au suivant.

Citation :
potentiometre[bouclesecondaire + (bouclePrimaire * 4)] = analogRead(potentiometreEntre)/8;

On écrit la valeur du potentiomètre dans la variable potentiomètre[n] le calcul est le suivant :
Pour le premier potentiomètre qui est connecté sur le MUX B2 nous avons comme valeur :
boucleSecondaire = 0
BouclePrimaire = 0
Ce qui donne 0+(0*4) = 0 ce qui correspond au premier potentiomètre.

Pour le 6ème qui lui est connecté sur le port 2 du mux B3 nous aurons les valeurs :
boucleSecondaire = 2
BouclePrimaire = 1
Ce qui donne 1+(1*4) = 5 ce qui correspond au sixième potentiomètre, vous aurez deviné que nous comptons a partir de ZERO et non de UN.

Citation :
Serial.write(midiChannel);
Serial.write(potentiometreCC[bouclesecondaire + (bouclePrimaire * 4)]);
Serial.write(potentiometre[bouclesecondaire + (bouclePrimaire * 4)]);

Envois des données vers le port série.

Et on retourne a ligne Void Loop(){
33
C'est ce qu'on appelle du commentaire :bravo:

Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com

34
Petite précision pour ceux que cela effraie. J'ai fait une approche empirique du problème, je n'ai pas de formation spécifique en programmation ou bien encore en électronique. J'ai pris une carte Arduino et suivi quelques tutoriels sur internet. De cette manière j'ai pu explorer le langage et me familiariser avec la plateforme. Je savais au départ ce que je voulais et j'ai donc analysé les différentes possibilités. J'ai simplifié au maximum et tenté d'utiliser la plateforme dans sa plus simple expression. Par exemple il existe une librairie MIDI pour l'Arduino, mais a qui sait faire elle est inutile et prend de la mémoire. Et parlons du coup, car c'est ici que ce genre d'interface devient intéressante. Dans l'état cette interface coute 50€, si on veut ajouter un boitier il faut compter le prix du boitier et la visserie. Pour ceux qui n'ont pas de fer a souder, ça coute pas grand chose et apprendre a souder prend quelques minutes. Il suffit de commencer par les potentiomètres et de lire l'un ou l'autre site web qui traite du sujet. Peut on y mettre de la mémoire ? oui Peut on y mettre des sysex ? oui mais il faut de la mémoire Peut on... wow wow wow... On peut beaucoup, il y a deux limitations, la carte Arduino et l'imagination. Mais on peut ajouter une seconde carte Arduino, utiliser plusieurs ports de sorties, utiliser le connecteur USB aussi, y mettre un affichage LCD (14 euros). Interface sans fil, ajouter un joystick, un ruban ou un écran tactile.
35
Et ici une petite vidéo vite faite sur l'interface en opération:

36
Un très beau travail, un projet abordable en comparaison des contrôleurs sur le marché.
Je joins des cours pour la programmation de l'Arduino : http://fr.openclassrooms.com/sciences/cours/arduino-pour-bien-commencer-en-electronique-et-en-programmation

Et un projet pour un controleur MIDI via USB : https://2froblog.wordpress.com/2012/07/19/controleur-midi-via-lusb-avec-arduino-49/
37
hello
super intéressant...
bon c'est un peu dur à comprendre pour moi ..mais bon...grâce à vous je commence à entre-apercevoir l’intérêt d'arduino.
D'où ma question.

Serait ce possible ( et pas trop galére) de créer un patch contrôlé par arduino.
en gros pouvoir faire un routing classique de patch mais sans les câbles.(avec des relais j'imagine)

j’espère être un peu clair.
merci.
jf

[ Dernière édition du message le 19/09/2013 à 21:34:36 ]

38
J'imagine que c'est possible oui.
Maintenant les relais sont électriquement bruyant.
Il faudrait regarder du coté des 74HC4066 ou 67 pour le routage, mais là ça dépasse encore ma sphère de compétence.
Un petit dessin de ce que tu veux faire ?
39
Citation :
Serait ce possible ( et pas trop galére) de créer un patch contrôlé par arduino.
en gros pouvoir faire un routing classique de patch mais sans les câbles.(avec des relais j'imagine)

Tout à fait !

Relais possibles pour de l'audio ou du MIDI : exemple pour une grille / patch 4*4
(ici pilotée par un PIC, mais Arduino ou autre uC conviennent)

Commutateurs analogiques pour audio :
- CD4016 / CD4066 / CD4067 / CD4097 pour "qualité standard";
- autres spécialisés style MAX335 pour "qualité supérieure"

Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com

40
secmast, tu vas mettre ton controlleur dans un boitier?
41
C'est en cours, en effet, j'attend une livraison pour l'instant.

C'est une interface qui me servira pour les réglages cachés du Moog Minitaur, ainsi plus besoins d'ordinateur.
J'y ai ajouté deux potentiomètres ainsi que 4 LED qui m'indique la position MIDI des boutons temporaire.

Voici la sérigraphie pour le face avant.

image.php

[ Dernière édition du message le 24/09/2013 à 13:36:50 ]

42
super interessant !

du coup le projet finale aura la carte arduino directement ou bien tu vas programmé un autre atmega pour un gain de place ?

j'ai un arduino également mais je trouve que ca fait vite cher si ont doit a chaque fois racheter une carte. Mais pourtant beaucoup le font , comprends pas...

rumorofsmoke.github.io/

43
Dans le proto que je monte, il y a aura une carte complète.
Ensuite je pense refaire le circuit et n'y mettre qu'un atmega328 pour un gain de place et d'argent. Le but étant ici de démontrer que pour par cher il est possible de faire une interface midi qui tient la route.
Je prépare d'ailleurs le code sur une configuration dynamique et non plus statique des CC en utilisant soit l'EEPROM soit une carte SD.
44

Salut Secmast,

 

Super projet, as tu vu ceux que proposer e-licktronic.

Ils ont aussi des libraires bien pratique pour utiliser des potentiomètres multiplexer comme sur ton projet.

Tu peux trouver des infos ici.

 

45
J'avais vu
Citation de Xarolium :
Salut Secmast, Super projet, as tu vu ceux que proposer e-licktronic. Ils ont aussi des libraires bien pratique pour utiliser des potentiomètres multiplexer comme sur ton projet. Tu peux trouver des infos ici.
Salut et merci, J'ai fais le tour et pour moi la solution la plus économique reste le 4051 qui coute 30 centimes pièces. La solution e-licktronick fait 12 euros pour 16 entrée, moi 60 centimes. Et je n'utilise aucune librairie. Le but étant de pouvoir gérer au maximum la SRAM et ne pas se laisser surprendre par des variables "inconnues" . Avec le 4051 et l'Arduino j'ai un temps de réponse de 1ms entre chaque scan avec 10 controleurs, je pourrais améliorer cette performance en utilisant du code hors IDE Arduino et même changer la résolution en passant de 10 bits a 7 bits ce qui accélère aussi le processus. Mais le code est plus complexe a comprendre. J'en suis pas encore là. Car pour mon utilisation 5 ms reste acceptable. Maintenant les solutions "clef en main" c'est parfais pour celui qui ne veux pas se prendre la tête, mais le cout en terme de flexibilité est énorme. Et c'est 5 fois plus cher.
46
Il est certain que les solutions toutes faites coûtent plus cher et ça se comprend puisqu'il n'y a pas que le prix des composants eux-mêmes à intégrer dans le total. L'approche de secmast est intéressante, il a déjà en tête des évolutions possibles et il sait où il met les doigts. L'intérêt de développer ses propres routines est de pouvoir tester plus loin les limites : puis-je réellement faire bosser mes commutateurs analogiques à 1 MHz sous 5 V ? A 1,2 MHz ? à à 1,5 MHz ? etc. Bon, dans le cas présent on n'a pas besoin de pousser les CI aux limites, mais ça ne fait pas de mal de les connaître.

Sans compter le fait qu'avec les modules d'extension tout faits, il faut toujours espérer qu'ils existent encore le jour (4 ans après ? ) où on décide d'étendre les fonctions de l'engin... Je pense qu'un 4051 se trouvera encore dans 10 ans (mais je sais, il ne faut jamais jurer de rien).

x
Hors sujet :
J'ai terminé hier soir un petit contrôleur midi 7 voies que j'avais commencé en 2009, un peu continué en 2011, et que j'avais laissé de côté pour X raisons. Je publierai le détail du truc le WE prochain sur mon site.

Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com

47
Pour 0.30€ le composant tu peux te faire un petit stock...
48

Citation de : adrienf

Pour 0.30€ le composant tu peux te faire un petit stock...

 Si tu en achète 100 chez Farnell ils sont a 0.125 euros pièce, ça fait la commande a 12,5 euros sans les frais de ports.  mrgreen

 

49
Voici le circuit terminé, il n'y manque que le jumper des boutons et bien entendu les boutons, potentiomètres, LED, connecteur DIN et connecteur alimentation qui vont venir sur le boitier. Boitier que j'attend toujours pour l'instant.

image.php
50
L'interface que je monte en ce moment est une interface dont les CC sont statique, le code que j'ai fournit peu néanmoins être modifié pour inclure une fonction de configuration des CC pour chaque controleur.

Je vous donne un code que j'ai testé et est relativement simple a mettre en oeuvre.
L'astuce ici est de détecter au moment de la mise en route si le bouton 1 est presser pour entrer en mode configuration.
Ensuite il suffit de tourner le potentiomètre 1 pour afficher la valeur du CC voulu pour le premier controleur de presser le bouton 2 pour passer au suivant et ainsi de suite jusqu'à la fin des contrôleurs.

Si le bouton un n'est pas presser au moment de la mise en route, l'Arduino lit l'EEPROM et prend les valeurs stockés.

Je vous donne le code brute fait pour 3 potentiomètres et deux boutons.

/* Bouton de config pin 2
Bouton de menu pin 3
Potentiometre de config A0*/
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2);

int controleur[5];
int boucle;
int potentiometre[3];

void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(2, INPUT);
pinMode(3, INPUT);

// Si le bouton 2 est poussé entré en mode configuration
if (digitalRead(2) == HIGH) {
Serial.println("Mode Configuration");
lcd.setCursor(0,0);
lcd.print(" Configuration");
lcd.setCursor(0,1);
lcd.print("Controle");
{
for (boucle=0; boucle < 5; boucle++){
lcd.setCursor(10,1);
lcd.print(boucle+1);
lcd.print(" ");

Serial.println("--------------------------");
Serial.print("Entree donnee controleur ");
Serial.println(boucle+1);
Serial.println("--------------------------");
delay(250);

// Passage au controleur suivant
while (digitalRead(3) == LOW){
controleur[boucle] = EntreeControleur();

//Affichage sur le port série et l'écran LCD

Serial.print("Controleur : ");
Serial.print(boucle+1);
Serial.print(" > ");
Serial.println(controleur[boucle]);
lcd.setCursor(13,1);
lcd.print(controleur[boucle]);
lcd.print(" ");
}
}

//Fin de la boucle de configuration

Serial.println("Ecriture EEPROM");
lcd.clear();
lcd.print("Ecriture EEPROM");

//Ecriture dans l'EEPROM

for (boucle=0; boucle < 5; boucle++){
EEPROM.write(boucle, controleur[boucle]);


Serial.print("Ecrite controleur : ");
Serial.print(boucle+1);
Serial.print(" > ");
Serial.println(controleur[boucle]);
delay(250);
}
}
}

// Si le bouton 2 n'est pas pressé passage en mode normal

else {
Serial.println("Mode Normal...");
lcd.setCursor(0,0);
lcd.print("Mode Normal");

//Lecture dans l'EEPROM des valeurs CC pour les controleurs

for (boucle=0; boucle < 5; boucle++){
controleur[boucle]=EEPROM.read(boucle);
}

//Affichage des valeurs CC des controleur sur le port série et l'écran LCD

}
for (boucle=0; boucle < 5; boucle++){
Serial.print("Controleur : ");
Serial.print(boucle+1);
Serial.print(" > ");
Serial.println(controleur[boucle]);
lcd.clear();
lcd.print("Mode normal...");
lcd.setCursor(0,1);
lcd.print("..MIDI CRTL pret");

}
}

//Boucle principale de fonctionement où les controleurs sont lu et les données envoyées vers le port série si il y a un changement.

void loop() {
for(int boucle=0; boucle < 3; boucle++){
if (analogRead(boucle)/8 != potentiometre[boucle]){
potentiometre[boucle] = analogRead(boucle)/8;
Serial.print("1 ");
Serial.print(controleur[boucle]);
Serial.print(" ");
Serial.println(potentiometre[boucle]);
}
delay(1);
}
}

//Fonction de lecture du potentiometre 1 pour selection CC

int EntreeControleur()
{
int valeur = analogRead(0)/8;
return valeur;
}