fabriquer un controleur midi (footswitch)

Bonjour à tous,
Mon probleme est assez simple, je désire fabriquer un controleur midi (genre pédale pour guitarite) avec un minimum de 24 switch.
Car cela doit s'adapter a un patch max/msp ou je doit tout avoir sous le pied.
Avec arduino cela semple possible ? quel carte il faut avoir pour pouvoir brancher 24 switch ? est ce que je pourrais utiliser ca en cc ?
et pour finir est ce vraiment compliqué pour quelqu'un qui n'a fait que souder des jack ?
merci de votre compréhension je ne veux pas me lancer la dedans si c'est trop ardu.
à bientôt
Pascal

Merci pour ta réponse Alien,
mais je n'y vois pas beaucoup plus clair pour l’instant.
J' ai fait un tour par ci par la et j'ai bien vu qu'il y as des projets en midi.
si je comprend bien la carte "mega" correspond à mon projet car elle a un nombre suffisant d'entrée ?
Si quelqu'un a une idée ?
merci de votre réponse
Pascal

Bonjour,

Une carte arduino mega pour "lire" 24 interrupteurs est une bonne idée, coté soudure/montage à part les 24 fils à souder à chaque interrupteurs il n'y as besoin d'aucun autre matériel (si ce n'est une prise midi).
Après c'est de la programmation, et sur ce point il y a sur le playground arduino et sur le web énormément de tuto/doc sur le sujet.

Salut,
pour un projet midi je ne partirais pas sur l'arduino comme base, mais sur une midibox: http://www.ucapps.de/

J'en avais monter une (midibox 64) et c'est remarquablement bien foutu.

merci de vos réponses,
je dois dire que Skywodd m'a remonter le moral effectivement si il s'agit de souder seulement les boutons poussoir, pas de souci.
Je suis aller voir sur le site de midibox et pour moi ca a l'air encore moins clair, quel carte choisir ?
je suis aller voir aussi sur le site interfacez, il font aussi ce genre de choses (allez y faire un tour, je pense que cela devrait intéresser pas mal de gens ici).
a bientôt
Pascal

L'arduino peut être une bonne base si ton projet est de charger une banque d'effets via midi dans un appareil. Tout dépen du message midi que tu dois envoyer en fonction des appuis sur les boutons...

salut a tous,
En fait, je veux envoyer des messages de type control change, tout les poussoirs doivent avoir des numéros différent mais peuvent être sur le même canal midi.
Après cela, je fais ce que je veux avec max/msp.
Je pensais aussi mettre une (ou 2) entrée jack femelle pour une pédale d'expression midi (en control change aussi avec une course de 0 à 127).

Si c'est pas trop compliquer de rajouter 2 boutons pour changer les numéros des control changes (ce qui ce trouve sur la plupart des contrôleurs midi), pourquoi pas ? mais cela implique un petit écrans pour afficher ou on en est etc...
donc je préfère rester simple
Ce qui est sur c'est que j'ai besoin d'avoir 3*8 boutons disponible en même temps (pour contrôler un patch Max/Msp de 24 loop audio)
merci en tout cas de vos réponse.
Pascal

Bonjour à tous,
donc il est temps de passer à l'acte, j'ai fais des recherches et je me demande si c'est bien c'est produit donc j'ai besoin, pour la méga j'ai trouvé ca==>
http://www.alyasoft.com/catalog/product_info.php?products_id=96&alyasoftsid=96f7fe4a757135d35cda4835789aeacc
est ce que c'est bien la méga qu'il me faut ?
Après pour les boutons poussoir, je veux un boutons qui fait juste un contact et qui reviens à ca position initiale (pas un interrupteur), j'ai été affolé par le prix presque 9€ ttc en france, donc j'ai trouvé ceci==> http://www.nowyelektronik.pl/searchsklep.php?mode=opis&nr=50714
ou bien cela==> Eltronix - sklep elektroniczny
et oui vive l'europe en pologne c'est 7 fois moins cher.
Est ce que j'ai tout le matériel ici pour commencer mon projet?
merci de vos réponses
Pascal

frascal:
donc il est temps de passer à l'acte, j'ai fais des recherches et je me demande si c'est bien c'est produit donc j'ai besoin, pour la méga j'ai trouvé ca==>
http://www.alyasoft.com/catalog/product_info.php?products_id=96&alyasoftsid=96f7fe4a757135d35cda4835789aeacc
est ce que c'est bien la méga qu'il me faut ?

Oui (sinon moins chére http://www.lextronic.fr/P5072-platine-arduino-mega-2560.html)

frascal:
Après pour les boutons poussoir, je veux un boutons qui fait juste un contact et qui reviens à ca position initiale (pas un interrupteur), j'ai été affolé par le prix presque 9€ ttc en france, donc j'ai trouvé ceci==> http://www.nowyelektronik.pl/searchsklep.php?mode=opis&nr=50714
ou bien cela==> Eltronix - sklep elektroniczny

Pour les interrupteurs momentané autant les acheter chez un vendeurs de composants :astonished:
http://www.lextronic.fr/R2508-pour-chassis.html

frascal:
Est ce que j'ai tout le matériel ici pour commencer mon projet?

Normalement oui, tout le reste c'est de la programmation.

Salut a tous,
j'ai donc commandé la méga (chouette!).
j'ai téléphoné à lextronic et il ne font pas de bouton poussoir pour mettre mes gros pieds dessus je l'ai est donc commandé en pologne 5 zl piéce (1,5€).
voila, maintenant je me penche sur le code ...
a bientôt
Pascal

Salut a tous,
J'ai beaucoup de questions:
J'ai bien fouillé sur le net pour trouver un code qui m'enverrait des "controls changes" en midi quant j’appuie sur un bonton poussoir.
j'ai trouvé ceci:

// midi.controller
// written by The Cat Herder
// Sends midi program change and control change messages based on foot pedal pressed

// Constants
#define SWITCH1 2
#define SWITCH2 3
#define SWITCH3 4
#define SWITCH4 5
#define SWITCH5 6
#define LED1 7
#define LED2 8
#define LED3 9
#define LED4 10
#define LED5 11
#define BOUNCEDELAY 25

// Variables:
int switches[5] = { SWITCH1, SWITCH2, SWITCH3, SWITCH4, SWITCH5 };
int switchState[5] = { HIGH, HIGH, HIGH, HIGH, HIGH };
// Initial state of switch is high due to internal pullup
int leds[5] = { LED1, LED2, LED3, LED4, LED5 };
int currentSwitch = 0;
int currentProgram = 22; // current program - sent to the output
int bypassState = LOW; // state of bypass pedal
int pedalActiveFlash = 50; // Delay for flash when pedal is pressed

void setup() {
// Set MIDI baud rate:
Serial.begin(31250);

// Setup Switches and activation LEDs
for( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
pinMode( switches[currentSwitch], INPUT ); // Set pin for switch
digitalWrite( switches[currentSwitch], HIGH ); // Turn on internal pullup
pinMode( leds[currentSwitch], OUTPUT ); // Set pin for LED
flashPin( leds[currentSwitch], 100 ); // Flash LED
}
}

void loop() {
for( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
if((digitalRead(switches[currentSwitch]) != switchState[currentSwitch] )&&(switchState[currentSwitch] == HIGH)){
switch( currentSwitch ) {
case 0:
//Bypass
if( bypassState == LOW ) {
bypassState = HIGH;
midiSend( 0xB0, 0x5B, 0x00 ); // bypass off
digitalWrite( leds[currentSwitch], LOW );
}
else {
bypassState = LOW;
midiSend( 0xB0, 0x5B, 0x7F ); // bypass on
digitalWrite( leds[currentSwitch], HIGH );
}
break;
case 1:
//Prev Program
currentProgram = currentProgram--;
if( currentProgram < 1 )
currentProgram = 0; // Don't go lower than 0
midiProg( 0xC0, currentProgram );
flashPin( leds[currentSwitch], pedalActiveFlash );
break;
case 2:
// Next Program
currentProgram = currentProgram++;
if( currentProgram > 96 )
currentProgram = 97; // Don't go lower than 97
midiProg( 0xC0, currentProgram );
flashPin( leds[currentSwitch], pedalActiveFlash );
break;
case 3:
// Favourite 1
currentProgram = 22;
midiProg( 0xC0, currentProgram );
flashPin( leds[currentSwitch], pedalActiveFlash );
break;
case 4:
// Favourite 2
currentProgram = 27;
midiProg( 0xC0, currentProgram );
flashPin( leds[currentSwitch], pedalActiveFlash );
break;
}
delay( BOUNCEDELAY );
}
switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
}
}

// Send a three byte midi message
void midiSend(char status, char data1, char data2) {
Serial.print(status, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}

// Send a two byte midi message
void midiProg(char status, int data ) {
Serial.print(status, BYTE);
Serial.print(data, BYTE);
}

void flashPin( int ledPin, int flashDelay ) {
digitalWrite( ledPin, HIGH );
delay( flashDelay );
digitalWrite( ledPin, LOW );
}

Dans ce cas il y a des leds, et je n'en ai pas besoin, en revanche j'ai besoin de 24 boutons poussoir et non 6 ?
quand il est écris dans le code présent: 0xB0, 0x5B, 0x7F, est ce que c'est un message midi en hexadécimal ?
Aprés sur la carte "mega" les entrées des boutons poussoir seront sur les entrée digitale de 1 à 53 ?
(un cable sur l'entrée 1 et un cable sur le gnd j'imagine).

Le port usb de la carte pourrait il alimenter la méga et en même temps m'envoyer les message midi (en port série) que je transforme avec un patch max)
sinon j'ai un transfo 3v-12v continue 1000mA, est ce que ca vas ?

voila... j’attends vos réponse avec impatience avant de faire des bétises.
merci de votre patience.
Pascal

Dans ce cas il y a des leds, et je n'en ai pas besoin, en revanche j'ai besoin de 24 boutons poussoir et non 6 ?
quand il est écris dans le code présent: 0xB0, 0x5B, 0x7F, est ce que c'est un message midi en hexadécimal ?

Oui c'est un message midi en hexa.

Aprés sur la carte "mega" les entrées des boutons poussoir seront sur les entrée digitale de 1 à 53 ?
(un cable sur l'entrée 1 et un cable sur le gnd j'imagine).

Il faudra mettre un coté de l'interrupteur au gnd et l'autre coté sur une entrée, il faudra aussi activer les résistances de "pull-up".
Exemple :

for(byte i = 2 ; i <= 54 ; i++) {
   pinMode(i, INPUT); // mise en entrée
   digitalWrite(i, HIGH); // active pull-up
}

EDIT: de 2 à 54 ce serait mieux, D1 est utilisé pour l'upload du sketch.

Le port usb de la carte pourrait il alimenter la méga et en même temps m'envoyer les message midi (en port série) que je transforme avec un patch max)
sinon j'ai un transfo 3v-12v continue 1000mA, est ce que ca vas ?

Le port usb suffira largement, il n'y rien de connecter à pars les boutons donc aucun soucis de ce coté là :wink:

Re,

Je t'ai fait un squelette de sketch à remplir selon tes besoins.
Les boutons sont cablé comme ceci :
BP 1 à 8 sur D35 à D42,
BP 9 à 16 sur D43 à D50,
BP 17 à 24 sur D53 à D60.
Edit: petite erreur port <> broche arduino ... oups!

Pour chaque BP tu n'as plus qu'as ajouter les commandes midi que tu souhaite (avec un delay après si besoin):

if(bitRead(PINL, 0)) { // BP 1
   midiCmd(.........);
}

Le delay final en fin de loop() est juste là pour éviter de répéter des 10aines de fois la même commande midi, la valeur est à adapter selon les besoin :wink:

void setup() {
  DDRL = 0x0;
  PORTL = 0xFF; // PORT L -> INPUT + Pull-up
  DDRD = 0x0;
  PORTD = 0xFF; // PORT D -> INPUT + Pull-up
  DDRC = 0x0;
  PORTC = 0xFF; // PORT C -> INPUT + Pull-up

  Serial.begin(31250); // Serial -> midi
}

void loop() {
  if(bitRead(PINL, 0)) { // BP 1

  }
  if(bitRead(PINL, 1)) { // BP 2

  }
  if(bitRead(PINL, 2)) { // BP 3

  }
  if(bitRead(PINL, 3)) { // BP 4

  }
  if(bitRead(PINL, 4)) { // BP 5

  }
  if(bitRead(PINL, 5)) { // BP 6

  }
  if(bitRead(PINL, 6)) { // BP 7

  }
  if(bitRead(PINL, 7)) { // BP 8

  }
  if(bitRead(PIND, 0)) { // BP 9

  }
  if(bitRead(PIND, 1)) { // BP 10

  }
  if(bitRead(PIND, 2)) { // BP 11

  }
  if(bitRead(PIND, 3)) { // BP 12

  }
  if(bitRead(PIND, 4)) { // BP 13

  }
  if(bitRead(PIND, 5)) { // BP 14

  }
  if(bitRead(PIND, 6)) { // BP 15

  }
  if(bitRead(PIND, 7)) { // BP 16

  }
  if(bitRead(PINC, 0)) { // BP 17

  }
  if(bitRead(PINC, 1)) { // BP 18

  }
  if(bitRead(PINC, 2)) { // BP 19

  }
  if(bitRead(PINC, 3)) { // BP 20

  }
  if(bitRead(PINC, 4)) { // BP 21

  }
  if(bitRead(PINC, 5)) { // BP 22

  }
  if(bitRead(PINC, 6)) { // BP 23

  }
  if(bitRead(PINC, 7)) { // BP 24

  }
  delay(1000); // Evite le flood 
}

void midiCmd(byte db1, byte db2, byte db3) {
  Serial.write(db1);
  Serial.write(db2);
  Serial.write(db3);
}

void midiCmd(byte db1, byte db2 ) {
  Serial.write(db1);
  Serial.write(db2);
}

Merci beaucoup Skywodd j'essaie cela desuite. :astonished:

Bon eh bien j'ai écrit ton code dans le logiciel arduino et je fais une vérification, cela me dit :

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x11
avrdude: stk500v2_disable(): failed to leave programming mode

voilà :fearful:
a +
Pascal

frascal:
Bon eh bien j'ai écrit ton code dans le logiciel arduino et je fais une vérification, cela me dit :

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
(...)

C'est qu'il y a eu un probléme lors de l'envoi sur l'arduino, essaye d'uploader le sketch blink en appuyant sur reset lorsque "binary done ..." s'affiche.
Ps: ce n'est pas une vérification que tu as fait mais un upload vu que avrdude à était lancé :wink:

Par contre je viens de me rendre compte que j'ai utilisé la mauvaise version du pinmapping pour mega 2560 (le fichier tableur sur le playground) et pas la version finale ... donc mes correspondance broches <> port sont fausse, je vais corriger tout ça désolé :. (en réalité sur la version tableur c'est la correspondance broches ATmega <> port et non broche "arduino" <> port :stuck_out_tongue_closed_eyes:) ou plus simplement je vais faire une version avec digitalRead (ce sera plus simple pour toi).

Voila ce coup ci c'est le bon pinmapping :slight_smile:

/*
 *
 * 24 BP Midi Footswitch by SkyWodd
 *
 * Boutons :
 * 1 ~ 8 : D22 ~ D29 (PORTA)
 * 9 ~ 16 : D37 ~ D30 (PORTC)
 * 17 ~ 24 : A8 ~ A15 (PORTK)
 *
 * Dx -> BP -> GND
 */

void setup() {
  DDRA = 0x0;
  PORTA = 0xFF; // PORT A -> INPUT + Pull-up
  DDRC = 0x0;
  PORTC = 0xFF; // PORT C -> INPUT + Pull-up
  DDRK = 0x0;
  PORTK = 0xFF; // PORT K -> INPUT + Pull-up

  Serial.begin(31250); // Serial -> midi
}

void loop() {
  if(bitRead(PINA, 0)) { // BP 1

  }
  if(bitRead(PINA, 1)) { // BP 2

  }
  if(bitRead(PINA, 2)) { // BP 3

  }
  if(bitRead(PINA, 3)) { // BP 4

  }
  if(bitRead(PINA, 4)) { // BP 5

  }
  if(bitRead(PINA, 5)) { // BP 6

  }
  if(bitRead(PINA, 6)) { // BP 7

  }
  if(bitRead(PINA, 7)) { // BP 8

  }
  if(bitRead(PINC, 0)) { // BP 9

  }
  if(bitRead(PINC, 1)) { // BP 10

  }
  if(bitRead(PINC, 2)) { // BP 11

  }
  if(bitRead(PINC, 3)) { // BP 12

  }
  if(bitRead(PINC, 4)) { // BP 13

  }
  if(bitRead(PINC, 5)) { // BP 14

  }
  if(bitRead(PINC, 6)) { // BP 15

  }
  if(bitRead(PINC, 7)) { // BP 16

  }
  if(bitRead(PINC, 0)) { // BP 17

  }
  if(bitRead(PINK, 1)) { // BP 18

  }
  if(bitRead(PINK, 2)) { // BP 19

  }
  if(bitRead(PINK, 3)) { // BP 20

  }
  if(bitRead(PINK, 4)) { // BP 21

  }
  if(bitRead(PINK, 5)) { // BP 22

  }
  if(bitRead(PINK, 6)) { // BP 23

  }
  if(bitRead(PINK, 7)) { // BP 24

  }
  delay(1000); // Evite le flood 
}

void midiCmd(byte db1, byte db2, byte db3) {
  Serial.write(db1);
  Serial.write(db2);
  Serial.write(db3);
}

void midiCmd(byte db1, byte db2 ) {
  Serial.write(db1);
  Serial.write(db2);
}

Ou sinon version digitalRead :

/*
 *
 * 24 BP Midi Footswitch by SkyWodd
 *
 * Boutons :
 * 1 ~ 24 : D22 ~ D45
 *
 * Dx -> BP -> GND
 */

void setup() {
  for(byte i = 22 ; i < 46 ; i++) {
    pinMode(i, INPUT); // mise en entrée
    digitalWrite(i, HIGH); // active pull-up
  }

  Serial.begin(31250); // Serial -> midi
}

void loop() {
  if(digitalRead(22)) { // BP 1

  }
  if(digitalRead(23)) { // BP 2

  }
  if(digitalRead(24)) { // BP 3

  }
  if(digitalRead(25)) { // BP 4

  }
  if(digitalRead(26)) { // BP 5

  }
  if(digitalRead(27)) { // BP 6

  }
  if(digitalRead(28)) { // BP 7

  }
  if(digitalRead(29)) { // BP 8

  }
  if(digitalRead(30)) { // BP 9

  }
  if(digitalRead(31)) { // BP 10

  }
  if(digitalRead(32)) { // BP 11

  }
  if(digitalRead(33)) { // BP 12

  }
  if(digitalRead(34)) { // BP 13

  }
  if(digitalRead(35)) { // BP 14

  }
  if(digitalRead(36)) { // BP 15

  }
  if(digitalRead(37)) { // BP 16

  }
  if(digitalRead(38)) { // BP 17

  }
  if(digitalRead(39)) { // BP 18

  }
  if(digitalRead(40)) { // BP 19

  }
  if(digitalRead(41)) { // BP 20

  }
  if(digitalRead(42)) { // BP 21

  }
  if(digitalRead(43)) { // BP 22

  }
  if(digitalRead(44)) { // BP 23

  }
  if(digitalRead(45)) { // BP 24

  }
  delay(1000); // Evite le flood 
}

void midiCmd(byte db1, byte db2, byte db3) {
  Serial.write(db1);
  Serial.write(db2);
  Serial.write(db3);
}

void midiCmd(byte db1, byte db2 ) {
  Serial.write(db1);
  Serial.write(db2);
}

Grand merci Skywodd,
donc si je comprend bien je dois rejouter cela

if(bitRead(PINA, 0)) { // BP 1
midiCmd(0xb0,0x5b,0x00);
}

et cela m'enverra le message midi 0xb0,0x5b,0x00 ?

donc si je comprend bien je dois rajouter cela

if(bitRead(PINA, 0)) { // BP 1
midiCmd(0xb0,0x5b,0x00);
}

et cela m'enverra le message midi 0xb0,0x5b,0x00 ?

Voila c'est ça ^^

Salut,
Donc j'ai rentré le code dans la carte et ... tout a l'air de bien ce passer.
maintenant il faut que je me penche sur le patch max et l'objet [serial].
est ce que la ligne:
Serial.begin(31250); // Serial -> midi

veux dire que je dois mettre l'argument 31250 dans mon objet [serial] ?
en tout cas merci de la précieuse aide.
à bientôt
Pascal