Catégories
Liens
Contrôleur MIDI réalisé avec six capteurs piézo-électriques.
L'idée est de fabriquer un contrôleur MIDI sensible, peu cher et configurable, le tout reproductible dans un fablab. Avec les capteurs piézo on peut récupérer la vélocité de la frappe de façon très sensible, ce qui en fait un bon candidat pour l'expression musicale. Bien souvent les pads vendus dans le commerce sont très peu sensibles. Une solution aussi très intéressante aurait été d'utiliser l'effet capacitif, le projet Touches tactiles en Midi explique la démarche. Mais dans ce cas, la captation ne permet pas d'avoir la force de frappe.
Voir aussi notre page sur les Capteurs DIY.
Le circuit est vraiment très simple, il s'agit plus ici de proposer un kit modulaire qui facilite la connection et simple à fabriquer. Par exemple on pourrait imaginer mettre deux ou trois contrôleurs comme ceci pour augmenter le nombre de touches.
Avec deux résistances (1MΩ et 1KΩ) et une diode Zener 5V1, le signal d'un piézo peut être utilisé par un micro-contrôleur Arduino ou Teensy. Les résistances lissent un peu le signal et la diode limite la tension du capteur. Car ce type de capteur génère de l'électricité et la tension peut dépasser celle prévue pour les entrées des micro-contrôleur, il faut donc bien faire attention à limiter la tension à 5V.
Les capteurs piézo sont sensibles à la vibration de la surface sur laquelle ils sont posés. On peut les utiliser en tant que microphones. Un projet de cinq documentaires autour de la musique à Marseille utilise cette technique : Watt Archipels. Pour éviter que le signal des piézo n'interfère les autres à côté, l'idée est de les contenir dans un matériau qui absorbe les chocs, comme ça on isole les signaux.
Dans un premier temps, il faut créer une forme très simple en 3D, voir six pour aller plus vite.
// P6 project // http://reso-nance.org/wiki/projets/p6/accueil // Moule 3D pour un capteur piézo-électrique // Moulage en silicone // mars 2016 // Variables $fn=80; // résolution epaisseur=3; interieur=6; // Affichage de l'objet p6_mold(); // Objet 3D module p6_mold(){ container(); piezo(); } // Modules module container(){ difference(){ cylinder(r = 26, h = epaisseur+interieur); translate([0,0,epaisseur]) cylinder(r = 23, h = interieur+1); } } module piezo(){ cylinder(r = 23, h = epaisseur); cylinder(r = 20, h = epaisseur + 3); cylinder(r = 14, h = epaisseur + 4); // pour les fils //translate([14,0,0]) cylinder(r = 2, h = epaisseur + interieur); rotate([90,0,0]) translate([-2,7,0]) cube([4,2,20]); }
Ensuite, il faut déposer du silicone dans les trous de la forme et laisser sécher une journée. On peut imaginer colorer le silicone à cette étape.
Le boîtier est configurable avec OpenScad. L'idée ici était aussi de voir comment passer d'une forme 3D à une forme découpée en tranche, typiquement usinable par une machine à découpe laser.
/* * P6 Box * Laser cuttable box for 6 piezo sensors * * http://reso-nance.org - 03/2016 * GNU/GPLv3 license */ /////////////////////////////////////////////// thickness = 3; // épaisseur contreplaqué de 3mm piezo_r = 23; // rayons des trous pour les piezo margin = 10; // marges nblayers = 8; // 8 couches grid_unit = margin + piezo_r * 2; length = 3*grid_unit+margin;//178mm = 3 piezos width = 2*grid_unit+margin;//122mm = 2 piezos height = nblayers * thickness; //24mm $fn = 90; /////////////////////////////////////////////// p6_3d(); // 3d view //p6_dxf(); // export to dxf /////////////////////////////////////////////// module p6_dxf(){ for (layer=[0:nblayers-1]){ //x=layer*(width+margin); x=(layer%2)*(width+margin); y=round(layer/2)%(nblayers/2)*(length+margin); z=(layer*thickness)-height+1; rotate([0,0,-90]) projection(cut=true) translate([x,y,z]) //plate(height); p6_3d(); } } module p6_3d(){ piezos(thickness,20); pcb_mount(20); //plate_drills(4*thickness,20); // Holes difference() { plate(height); // Box shape plate_drills(3*thickness+0.05,4,5*thickness); piezos(2*thickness); wires(6*thickness); pcb(); translate([margin,margin,thickness]) plate(4*thickness, width-2*margin, length-2*margin); translate([margin,margin,1]) linear_extrude(height = 2) text("P6", size = 60, font = str("Liberation Sans", ":style=Bold")); plate_drills(4*thickness+0.05,8,thickness); } difference(){ plate_drills(4*thickness,20); plate_drills(4*thickness+0.05,8,thickness); } } /////////////////////////////////////////////// module piezos(h=thickness, r=piezo_r) { z = height - h; for (row=[1:3]){ // Grid of 2x3 piezos for (col=[1:2]){ translate([col*grid_unit-piezo_r ,row*grid_unit-piezo_r, z]) cylinder(h=h+0.05,r=r); } } } module plate(h=thickness, w=width, l=length, mink_r=10) { translate([mink_r,mink_r,0]) minkowski() { cube([w-mink_r*2,l-mink_r*2,h]); cylinder(r=mink_r,h=0.01); } } module wires(h=thickness,w=7,l=4) { z = height - thickness - h; for (row=[1:3]){ for (col=[1:2]){ translate([col*grid_unit-piezo_r-w/2 ,row*grid_unit-(piezo_r*2+l)+1, z]) cube([w,l,h+0.05]); } } } module pcb() { w=74; l=65; w2=24; margin=5; l2=15+margin; translate([(width-w2)/2,length-l2,3*thickness]) cube([w2,l2,2*thickness]); // plug difference(){ translate([(width-w)/2,length-l-margin,thickness]) cube([w,l,2*thickness]); translate([(width-w+20)/2,length+10-l-margin,thickness]) cube([w-20,l-20,2*thickness]); } } module pcb_mount(){ w=74; l=65; difference(){ translate([(width-w)/2,3*margin,thickness]) cube([w,l,2*thickness]); translate([(width-w)/2+10,3*margin+10,thickness]) cube([w-20,l-20,2*thickness]); } } module plate_drills(h=thickness,d=3,z=thickness) { translate([width-10,margin+2,z]) cylinder(d=d,h=h); translate([margin+2,length-10,z]) cylinder(d=d,h=h); }
Voir la page Teensy pour configurer Arduino. Ici in récupère les 6 entrées analogiques et, après un petit traitement sur les données, on les envoie en MIDI, de façon à les recevoir par n'importe quel logiciel.
/* * P6 project * Teensy MIDI with 6 analog sensors * */ boolean DEBUG = false; // Analog sensors int anaPins[] = {21,20,19,18,17,16}; // analog pins const int anaNb = 6; int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // MIDI const int channel = 1; int anaCtl[] = {1,2,3,4,5,6}; // midi mapping // Sampling rate const long interval = 30; unsigned long currentMillis; unsigned long previousMillis = 0; void setup() { if (DEBUG) Serial.begin(9600); } void loop() { currentMillis = millis(); if(currentMillis - previousMillis >= interval) { previousMillis = currentMillis; for (int i = 0; i < anaNb; i++) { anaValues[i] = analogRead(anaPins[i]) / 4 ; if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); if (DEBUG)Serial.print(anaValues[i]); if (DEBUG)Serial.print("\t"); anaLastValues[i] = anaValues[i]; } } if (DEBUG)Serial.println(); } // MIDI Controllers should discard incoming MIDI messages. while (usbMIDI.read()) { } }