Le but ultime (qui sera atteint, je l'espère, dans un prochain article) sera de construire moi-même un instrument à clavier complet: un clavier MIDI, un synthétiseur, une Keytar, peut-être?
J'ai déjà décrit le clavier et sa matrice dans un article précédent: il a été récupéré d'un vieil orgue électronique Yamaha Electone qui avait été fabriqué au début des années '80. Le clavier comporte 37 touches (3 octaves) et j'ai utilisé sans modification sa matrice de diodes.
Le schéma ci-dessous montre la matrice du clavier (dont je n'ai représenté que 4 des 37 touches). Il y a 4 entrées d'octaves. La première est reliée aux 8 premières touches du clavier (de FA à DO), la deuxième est reliée aux 12 touches suivantes (de DO# à DO), etc. Il y a 12 entrées de notes: une même entrée pour tous les "sol" , une autre entrée pour tous les "la", etc.
Pour identifier les touches qui sont enfoncées, j'ai opté pour le principe suivant (voir le circuit ci-dessous): si je veux vérifier l'état de la touche "sol 1" je place l'entrée "octave 1" à 5 volts, les autres entrées d'octave à 0 volts, l'entrée "sol" à 0 V et les autres entrées de notes (la, si, do, etc.) à 5 V.
De cette façon, la sortie "octave 1" sera à 5 V si la touche "sol 1" est enfoncée puisqu'aucun courant ne circule dans la résistance. Le voltage de la sortie "octave 1" deviendra (idéalement) 0 V lorsque la touche "sol 1" est enfoncée. L'état des autres touches du même octave ne change rien, puisque ces touches ne sont soumises à aucune différence de potentiel (5 volts de part et d'autre).
Il s'agit ensuite de tester l'état de chacune des 37 touches du clavier, l'une après l'autre, ce que l'Arduino pourra faire très rapidement.
Si vous n'êtes pas familiers avec les registres à décalage, je mentionne rapidement qu'il s'agit d'un circuit intégré qui transforme un signal numérique 8 bits reçu de façon séquentielle à son entrée en un signal équivalent étalé en parallèle sur 8 sorties. Par exemple, l'Arduino peut envoyer le message "11111111" à l'entrée du registre à décalage; sur réception de cette instruction, le régistre mettra ses 8 sorties à 5 volts. Si l'Arduino envoie le message "01010101", 4 sorties seront à 0 volt, les autres seront à 5 volts, etc.
Le schéma ci-dessous montre les branchements des deux registres à décalage.
Il restait ensuite à coder un sketch pour que l'Arduino vérifie les 37 touches du clavier l'une après l'autre. J'ai d'abord tenté de produire un programme élégant avec des boucles et des opérateurs "bitwise"...et je me suis lamentablement cassé la gueule: rien ne fonctionnait! Voici donc une version peu élégante, très répétitive, mais qui a l'avantage de fonctionner (et qui est facile à comprendre, je crois), dans laquelle je vérifie l'état de chaque touche une par une.
Notez qu'à deux endroits dans le code, j'ai dû ajouter un délai d'une milliseconde (pour do#2 et do#3): sans ces délais, ces deux notes étaient mesurées à 0 V (position "touche enfoncée") sans que la touche du clavier ne soit enfoncée. Je suppose qu'il faut laisser un peu de temps au circuit pour se stabiliser avant de prendre la mesure.
Dans cette version, le clavier ne produit aucun son: le nom de la note s'affiche tout simplement dans le "serial monitor", à l'écran de l'ordinateur. Et ça semble très bien fonctionner, même lorsqu'on fait un accord en enfonçant plusieurs touches simultanément.
Prochaine étape: la version MIDI!
Mise à jour (12 mai 2012): Cet article a maintenant une suite: Clavier MIDI à base d'Arduino
int latchPin = 8; //Pin de l'Arduino branchée à la Pin 12 du 74HC595 (Latch)
int clockPin = 12; //Pin de l'Arduino branchée à la Pin 11 du 74HC595 (Clock)
int dataPin = 11; //Pin de l'Arduino branchée à la Pin 14 du 74HC595 (Data)
int octave1In= 2; // pin de l'Arduino qui reçoit le voltage pour le 1er octave
int octave2In = 3; // pin de l'Arduino qui reçoit le voltage pour le 2e octave
int octave3In = 4; // pin de l'Arduino qui reçoit le voltage pour le 3e octave
int octave4In = 5; // pin de l'Arduino qui reçoit le voltage pour le 4e octave
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(octave1In, INPUT);
pinMode(octave2In, INPUT);
pinMode(octave3In, INPUT);
pinMode(octave4In, INPUT);
Serial.begin(9600); // pour le serial monitor
}
void loop() {
//Testons la touche FA1
shiftOut(B11110001,B11111110);
if (!digitalRead(octave1In))
{
Serial.println("FA1");
}
//Testons la touche FA#1
shiftOut(B11110001,B11111101);
if (!digitalRead(octave1In))
{
Serial.println("FA#1");
}
//Testons la touche SOL1
shiftOut(B11110001,B11111011);
if (!digitalRead(octave1In))
{
Serial.println("SOL1");
}
//Testons la touche SOL#1
shiftOut(B11110001,B11110111);
if (!digitalRead(octave1In))
{
Serial.println("SOL#1");
}
//Testons la touche LA1
shiftOut(B11110001,B11101111);
if (!digitalRead(octave1In))
{
Serial.println("LA1");
}
//Testons la touche SIb1
shiftOut(B11110001,B11011111);
if (!digitalRead(octave1In))
{
Serial.println("SIb1");
}
//Testons la touche SI1
shiftOut(B11110001,B10111111);
if (!digitalRead(octave1In))
{
Serial.println("SI1");
}
//Testons la touche DO1
shiftOut(B11110001,B01111111);
if (!digitalRead(octave1In))
{
Serial.println("DO1");
}
//Testons la touche DO#1
shiftOut(B11100010,B11111111);
if (!digitalRead(octave2In))
{
Serial.println("DO#1");
}
//Testons la touche RE1
shiftOut(B11010010,B11111111);
if (!digitalRead(octave2In))
{
Serial.println("RE1");
}
//Testons la touche RE#1
shiftOut(B10110010,B11111111);
if (!digitalRead(octave2In))
{
Serial.println("RE#1");
}
//Testons la touche MI1
shiftOut(B01110010,B11111111);
if (!digitalRead(octave2In))
{
Serial.println("MI1");
}
//Testons la touche FA2
shiftOut(B11110010,B11111110);
if (!digitalRead(octave2In))
{
Serial.println("FA2");
}
//Testons la touche FA#2
shiftOut(B11110010,B11111101);
if (!digitalRead(octave2In))
{
Serial.println("FA#2");
}
//Testons la touche SOL2
shiftOut(B11110010,B11111011);
if (!digitalRead(octave2In))
{
Serial.println("SOL2");
}
//Testons la touche SOL#2
shiftOut(B11110010,B11110111);
if (!digitalRead(octave2In))
{
Serial.println("SOL#2");
}
//Testons la touche LA2
shiftOut(B11110010,B11101111);
if (!digitalRead(octave2In))
{
Serial.println("LA2");
}
//Testons la touche SIb2
shiftOut(B11110010,B11011111);
if (!digitalRead(octave2In))
{
Serial.println("SIb2");
}
//Testons la touche SI2
shiftOut(B11110010,B10111111);
if (!digitalRead(octave2In))
{
Serial.println("SI2");
}
//Testons la touche DO2
shiftOut(B11110010,B01111111);
if (!digitalRead(octave2In))
{
Serial.println("DO2");
}
//Testons la touche DO#2
shiftOut(B11100100,B11111111);
delay(1);
if (!digitalRead(octave3In))
{
Serial.println("DO#2");
}
//Testons la touche RE2
shiftOut(B11010100,B11111111);
if (!digitalRead(octave3In))
{
Serial.println("RE2");
}
//Testons la touche RE#2
shiftOut(B10110100,B11111111);
if (!digitalRead(octave3In))
{
Serial.println("RE#2");
}
//Testons la touche MI2
shiftOut(B01110100,B11111111);
if (!digitalRead(octave3In))
{
Serial.println("MI2");
}
//Testons la touche FA3
shiftOut(B11110100,B11111110);
if (!digitalRead(octave3In))
{
Serial.println("FA3");
}
//Testons la touche FA#3
shiftOut(B11110100,B11111101);
if (!digitalRead(octave3In))
{
Serial.println("FA#3");
}
//Testons la touche SOL3
shiftOut(B11110100,B11111011);
if (!digitalRead(octave3In))
{
Serial.println("SOL3");
}
//Testons la touche SOL#3
shiftOut(B11110100,B11110111);
if (!digitalRead(octave3In))
{
Serial.println("SOL#3");
}
//Testons la touche LA3
shiftOut(B11110100,B11101111);
if (!digitalRead(octave3In))
{
Serial.println("LA3");
}
//Testons la touche SIb3
shiftOut(B11110100,B11011111);
if (!digitalRead(octave3In))
{
Serial.println("SIb3");
}
//Testons la touche SI3
shiftOut(B11110100,B10111111);
if (!digitalRead(octave3In))
{
Serial.println("SI3");
}
//Testons la touche DO3
shiftOut(B11110100,B01111111);
if (!digitalRead(octave3In))
{
Serial.println("DO3");
}
//Testons la touche DO#3
shiftOut(B11101000,B11111111);
delay(1);
if (!digitalRead(octave4In))
{
Serial.println("DO#3");
}
//Testons la touche RE3
shiftOut(B11011000,B11111111);
if (!digitalRead(octave4In))
{
Serial.println("RE3");
}
//Testons la touche RE#3
shiftOut(B10111000,B11111111);
if (!digitalRead(octave4In))
{
Serial.println("RE#3");
}
//Testons la touche MI3
shiftOut(B01111000,B11111111);
if (!digitalRead(octave4In))
{
Serial.println("MI3");
}
//Testons la touche FA4
shiftOut(B11111000,B11111110);
if (!digitalRead(octave4In))
{
Serial.println("FA4");
}
}
// la routine suivante n'est pas de moi...piqué quelque part...
void shiftOut(byte dataOut1,byte dataOut2) {
boolean pinState;
digitalWrite(latchPin, LOW);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, LOW);
for (int i=0; i<=7; i++) {
digitalWrite(clockPin, LOW);
if ( dataOut1 & (1 << i) ) {
pinState = HIGH;
}
else {
pinState = LOW;
}
digitalWrite(dataPin, pinState);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, LOW);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, LOW);
for (int i=0; i<=7; i++) {
digitalWrite(clockPin, LOW);
if ( dataOut2 & (1 << i) ) {
pinState = HIGH;
}
else {
pinState = LOW;
}
digitalWrite(dataPin, pinState);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, LOW);
digitalWrite(latchPin, HIGH);
}
Ou en est votre projet?
RépondreSupprimerJ'ai réalisé un clavier Midi 61 touches avec un seul 74HC595 et un uno.
si ça vous intéresse dites le moi
Delcano
Je suis intéressé. Si'l vous plait, email à drancope@gmail.com
Supprimerlas_lb@hotmail.com thanks!!!
SupprimerBonjour,
Supprimerje suis allé au Synthfest 2016 à Nantes ce week end et en discutant avec des geeks, on voulait faire un proto de Keytar de 37 touches pour l'exposer sur scene l'année prochaine. Donc 32 touches c'est bon je sais faire mais au delà avec un seul 74HC595 à premiere vue je sèche. Pourriez vous m'aider? laurentnowacki@hotmail.fr. Merci!
Mon clavier MIDI est maintenant parfaitement fonctionnel. Ça me rappelle que j'avais l'intention de lui ajouter quelques fioritures mais il traîne dans un coin depuis près d'un an: il faudrait que je m'y remette.
RépondreSupprimerDear Mr.Pelletier
SupprimerI start a project Arduino/Midi using the first part of your project.
I believe that at this time you have finalize your midi project.
If possible I will appreciate if you can supply more information so I cam complete also my initial project.
Tank you for your attention to my request,
Madison
mleapfrog@gmail.com
The complete project is here:
Supprimerhttp://electroniqueamateur.blogspot.ca/2015/06/clavier-midi-arduino-version-20.html
Bjr Delcano,
RépondreSupprimerMoi aussi je suis interessé par ton projet CLAVIER MIDI.
adamastor59@hotmail.com
Un grand merci...
bonsoir Delcano
RépondreSupprimerJe suis interresser par ton projet de clavier midi.
Voici mon adresse perceval.barreau.laetitia@gmail.com
merci pour ta réponse
Bonjour!
RépondreSupprimerJ'ai besoin de votre aide j'ai un clavier m-audio keystation 61es qui ne fonctionne plus je voulais utilisée juste les touches avec arduino.... Merci! Azur0821@gmail.com