[Résolu] mappage clavier piano (avec schema)

Bonjour,

Tout d'abord j'aimerais préciser que je suis nouveau dans la communauté Arduino (depuis 3 jours), donc si je m'y prends mal pour présenter mon problème, merci de me le signaler pour que je rende ce post plus clair.

J'essaye de modifier un clavier midi (Prodipe 25 C) pour en faire un instrument stand-alone avec mon arduino UNO:

L'objectif est de démonter le minimum de choses possibles pour garder le casing et les branchements. :slight_smile:
(fainéantise quand tu nous tiens ^^)

Je suis conscient que ce n'est pas forcément la solution la plus optimale mais elle me parait la plus simple (cela dit vu comment je galère je me trompe peut-être...)

C'est un clavier avec 25 touches (avec 2 niveaux d'appuie) et le connecteur qui en sort a 20 broches

J'aimerais y brancher mon Arduino pour lire les 25 touches et faire sortir du son sur une enceinte (mon but et d'ensuite moduler les sons avec les autres boutons mais ça on verra plus tard :P)

Le clavier à 25 touches et "découpé" en 4 parties:

Sous chaque touches il y a deux contacteurs avec une diode associé (bouton poussoirs):

  • un pour un appuie faible
  • un pour un appuie fort

Voici le cablage simplifé avec seulement 4x2 touches (au lieux de 3x8+1 ...)


(je me suis servi du SSOP20 pour représenter la broche ...)

Prenons l'exemple des 4 premières touches.

En connectant la broche 20 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le C.
En connectant la broche 19 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le CS.
En connectant la broche 18 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le D.
En connectant la broche 17 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le DS.

(C=do, CS= do#,D=ré;...)

(dans ce cas il s'agit d'un appuie sensible, si je connectais la masse à la broche 2 il me faudrait un appuie fort)
(j'utilise INPUT_PULLUP)

Les autres touches ne fonctionne pas.

Maintenant si je connecte la masse à la broche 3 (pour appuie sensible, 4 pour appuie fort) j'ai 8 touches qui fonctionne, sur seulement 4 inputs (dans l'exemple du cablage présenté ci-dessus)

Ca donne ça si on continu cette logique:

Le problème c'est que j'ai 3 (ou 4 pour le 20) fois la même note sur le clavier et je n'arrive pas a les différencier ... Je vois bien qu'il y a un "codage" avec le broches 1, 2, 3, 4, 5, 6, 7 et 8 mais si je les branches à une input plutôt qu'à la masse je ne reçois plus de signal sur mes inputs :frowning:

Je sens bien que c'est un truc "tout con" mais je n'arrive pas à mettre le doigt dessus...

Je sollicite donc vos esprit de bidouilleurs pour me donner des pistes d'investigations, car pour le moment je fonctionne en die'n'retry mais cette méthode montre déjà ses limites :stuck_out_tongue:

  • Comment récupérer l'information que c'est la première, deuxième, ... partie du clavier qui est joué?
  • Comment bien brancher le clavier à l'Arduino ?

Merci d'avance pour vos idées :slight_smile:

Comment bien brancher le clavier à l'Arduino ?

Je me demande si connecter les PINs de 1 à 10 en pull-up et de 11 à 20 en pull-down pourrait régler le problème ?

hello

lorsque l'on essaie de suivre tes tests, à la 1ere ligne
"En connectant la broche 20 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le C."

on constate que ton schéma est faux.

de plus selon ton schéma: si tu mets 1 a la masse, si avec ton voltmetre tu mets la point de touche positive sur du +5 V, et la point de touche négative sur 19, tu verras que ton multimetre t'annonces 5 volts en permanence, et ce sans appuyer sur touche.

je n'arrive pas a les différencier

Bonjour,

c'est parce qu'il te manque des entres ou (et) des sorties :
ton schéma m'a l'air correct : avec 4 sorties et 4 entrées tu as une matrice de 4*4 = 16 switches, ce qui correspond à 16/2 = 8 touches

pour 25 touches correspondant à 225 = 50 switches, il te faut une matrice de, par exemple, 8 sorties et 8 entrées. Comme 88 = 64, cela te laisse du rab pour les boutons en façade

mais dis nous stp, pourquoi ne pas récupérer la sortie midi de l'engin, où tous ces problmes sont déjà résolus ?

trimarco232:
Bonjour,

c'est parce qu'il te manque des entres ou (et) des sorties :
ton schéma m'a l'air correct : avec 4 sorties et 4 entrées tu as une matrice de 4*4 = 16 switches, ce qui correspond à 16/2 = 8 touches

pour 25 touches correspondant à 225 = 50 switches, il te faut une matrice de, par exemple, 8 sorties et 8 entrées. Comme 88 = 64, cela te laisse du rab pour les boutons en façade

mais dis nous stp, pourquoi ne pas récupérer la sortie midi de l'engin, où tous ces problemes sont déjà résolus ?

bonjour
+1

@ trimarco et Artouste

avez vous suivi le fil du "1" connecteur ?
sur quelle touche faut il appuyer pour établir une continuité jusqu'à la borne "20" du connecteur ?

Merci pour vos réponses :slight_smile:

dfgh:
lorsque l'on essaie de suivre tes tests, à la 1ere ligne

Oui désolé, j'ai essayé de faire le plus clair possible mais je me rends compte que ce n'est pas des plus lisibles, désolé.

dfgh:
"En connectant la broche 20 à une input de l'Arduino et la broche 1 à la masse j'obtient bien un signal quand j'appuie sur le C."

on constate que ton schéma est faux.

Il se peut qu'à cause de la nappe j'ai inversé les 1, 2, 3, ... avec les 20, 19, 18, ...
Car c'est pour l'instant la seule façon que j'ai trouvé pour pouvoir "lire" les appuies sur les touches (les inputs sont configuré en PULL_UP)

dfgh:
de plus selon ton schéma: si tu mets 1 a la masse, si avec ton voltmetre tu mets la point de touche positive sur du +5 V, et la point de touche négative sur 19, tu verras que ton multimetre t'annonces 5 volts en permanence, et ce sans appuyer sur touche.

Malheureusement (et j'imagine vos têtes quand vous allez lire ça) je n'ai pas encore de voltmètres... un amis doit m'en donner un mais je ne l'ai pas encore vu :s

Ce qui rends l'affaire un peu plus compliqué :stuck_out_tongue:

trimarco232:
c'est parce qu'il te manque des entres ou (et) des sorties :
ton schéma m'a l'air correct : avec 4 sorties et 4 entrées tu as une matrice de 4*4 = 16 switches, ce qui correspond à 16/2 = 8 touches

pour 25 touches correspondant à 225 = 50 switches, il te faut une matrice de, par exemple, 8 sorties et 8 entrées. Comme 88 = 64, cela te laisse du rab pour les boutons en façade

Qu'est-ce que tu appelle entrée/sortie? car si je branche tout sur l'Arduino en INPUT_PULLUP, le courant ne passe plus et je ne peux donc rien lire...
Faut-il en mettre une partie en pullup et l'autre en pulldown ?

trimarco232:
mais dis nous stp, pourquoi ne pas récupérer la sortie midi de l'engin, où tous ces problèmes sont déjà résolus ?

C'est un très bonne question ^^
Plusieurs réponses (toute aussi peu valables les unes que les autres):

  • Je n'y avais pas pensé :s
  • J'avais l'impression que ça me compliquerai la tache, grâce à toi je suis allé voir, le midi n'a pas l'air si compliqué...
  • Ça n'est pas assez de "bidouille", vu que je suis nouveau sur Arduino et en électronique (sauf quelques lointain cours. Je voulais profiter de ce projet pour toucher un peu à tout pour mieux comprendre comment gérer boutons poussoirs, potentiomètres, etc...
  • Le côté retro engineering me plait bien :slight_smile:

Mais je vais quand même me pencher sur la question :stuck_out_tongue:

En tout cas merci pour votre aide.

sur quelle touche faut il appuyer pour établir une continuité jusqu'à la borne "20" du connecteur ?

Hello dfgh !
on y arrive en enfilant S1 et S, les switches fonctionnant par paire. Cependant (pour ne pas m'enfoncer d'avantage) je te concède que le cas des fils 1 et 3 mérite d'être clarifié

@ trimarco232
:slight_smile:

dfgh:
@ trimarco et Artouste

avez vous suivi le fil du "1" connecteur ?
sur quelle touche faut il appuyer pour établir une continuité jusqu'à la borne "20" du connecteur ?

Bien vue,

En simplifiant je m'étais trompé dans le cablage ... désolé

Voici le cablage corrigé:

La touche C (do) est activé en "sensible" par S0' et en "fort" par S0 => continuité entre 20 et 1 ou 2
Pour CS (Do#) c'est S'1 et S1 => continuité entre 19 et 1 ou 2
Pour A (La) c'est S'7 et S7 => continuité entre 20 et 3 ou 4
Pour AS (La#) c'est S'7 et S7 => continuité entre 19 et 3 ou 4
ainsi de suite...

Mais mon problème est de récupérer l'information de 1, 2, 3, 4, ... tout en faisant passer un courant. Si je les branches sur des inputs (ainsi que que 20, 19, ...) aucun courant ne passe.

Autrement dit, je comprends le principe de matrice pour des LED mais pas pour des boutons poussoirs.

Merci

Bonsoir,
20, 19, 18 et 17 sont des entrées qui peuvent être mises tour à tour en pull up :
exemple :
pull up : 20 ; no pull up : 19, 18, 17 puis
pull up : 19 ; no pull up : 20, 18, 17 puis
pull up : 18 ; no pull up : 20, 19, 17 puis
pull up : 17 ; no pull up : 20, 19, 18 puis on recommence
pull up : 20 ; no pull up : 19, 18, 17 etc.

1, 2, 3 et 4 sont en output high

quand 20 est en pull up :
on met 1 à low : si 20 low, c'est que S0 est actionné et met 20 à low via D', si 20 est high, S0 est relâché
on remet 1 à high et on met 2 à low : si 20 est low, c'est que S'0 est actionné et met 20 à low via D', si 20 est high, S'0 est relâché
etc.

attention : un état prolongé de D' peut s'avérer néfaste !

Bonsoir bonsoir,

C'est avec un grand plaisir que je vous annonce que j'ai enfin réussi et c'est grâce à vous ! Merci !

Voici mon code:

#define  button1 3
#define  button2 4
#define  button3 5
#define  button4 6
#define  button5 7
#define  button6 8
#define  button7 9
#define  button8 10

#define  ecartPlage 11 // permet de ramener plageFort1 à 1, plageFort2 à 2, ...
#define  plageFort1 11
#define  plageFort2 12
#define  plageFort3 13
/*
  #define  plageFaible1 3
  #define  plageFaible2 3
  #define  plageFaible3 3
  #define  plageFaible4 3*/

#define  analogSpeaker A0

#define ledPin 2

float f0 = 440;
float fn = 0;
int duration = 100;
int sensorRead;

void setup()
{
  //initialisation des OUTPUTS
  pinMode(ledPin, OUTPUT);
  pinMode(plageFort1, OUTPUT);
  pinMode(plageFort2, OUTPUT);
  pinMode(plageFort3, OUTPUT);

  //initialisation des INPUTS
  pinMode(button8, INPUT_PULLUP);
  pinMode(button7, INPUT_PULLUP);
  pinMode(button6, INPUT_PULLUP);
  pinMode(button5, INPUT_PULLUP);
  pinMode(button4, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button1, INPUT_PULLUP);

  //initialisation des plages à LOW
  digitalWrite(plageFort1, LOW);
  digitalWrite(plageFort2, LOW);
  digitalWrite(plageFort3, LOW);

  //initialisation de la console
  Serial.begin(9600);
  Serial.println ("fn");

  // Fin d'initialisation LED + son
  digitalWrite(ledPin, HIGH);
  tone(analogSpeaker, 440, duration);
}

// Allume et éteind la LED
void ledControl() {
  digitalWrite(ledPin, HIGH);
  delay(10);
  digitalWrite(ledPin, LOW);
}

/*  fonction pour trouver les fréquences des notes en fonction
    de la frequence de reference (f0=440Hz)
    et du nombre n de demi-ton la séparant de cette dernière:
   fn =f0*2^(n/12)
*/
void sound(float touche, float plage) {

  fn = f0 * pow(2, ((touche + (plage - ecartPlage) * 8) / 12)); // calcule la fréquence en fonction de la touche et de la plage (les plages font 8 touches)
  /*Serial.print ("touche:");
  Serial.print (touche);
  Serial.print (" - plage:");
  Serial.print (plage);
  Serial.print (" - fn:");
  Serial.println (fn);*/
  ledControl();       //allume la LED
  while (digitalRead(touche) == LOW) {            // tant que la toouche est appuyé, ne pas jouer 2 notes en même temps
    tone(analogSpeaker, fn, duration);            // joue sur le speaker la fréquence fn pendant "duration" ms
  }
  // remet les plages à LOW pour pouvoir détecter un appuie
  digitalWrite(plageFort1, LOW);
  digitalWrite(plageFort2, LOW);
  digitalWrite(plageFort3, LOW);
}
void loop()
{
  for (int thisSensor = button1; thisSensor <= button8; thisSensor++) {      // scanne les diférentes touches
    for (int thisPlage = plageFort1; thisPlage <= plageFort3; thisPlage++) {        // scanne les diférentes plages
      digitalWrite(plageFort1, HIGH);
      digitalWrite(plageFort2, HIGH);
      digitalWrite(plageFort3, HIGH);
      digitalWrite(thisPlage, LOW); // test de la plage (toutes les autres sont désactivé sauf thisPlage
      if (digitalRead(thisSensor) == LOW) { //si la touche est appuyé
        sound (thisSensor, thisPlage);
      }
    }
  }
}

Avec le câblage (incomplet, il y a 24 touches divisés en 3 plages - oui j'ai eu la flemme de mettre la 25ème touche :P)
Pour le moment je ne me sert que de "l'appuie fort", soit les S sans apostrophes

Merci encore à vous !