Wiki

Reso-nance numérique | Arts et cultures libres

Outils du site


Panneau latéral

projets:brutbox:dev:accueil

Ceci est une ancienne révision du document !


BrutBox / Développements

Cahier des charges

Janvier 2015 : cahierdescharges-2015-01.pdf

  • Nom : BrutBox
  • État de l'art : Orgue Sensoriel. Refaire sensiblement la même chose en moins cher, en libre/reproductible, (en moins bien ergonomiquement ?) mais en plus intéressant musicalement. Les capteurs sont distingués pour les animateurs : déclencheurs/variateurs, afin qu'ils s'accaparent le dispositif. Notez la taille des capteurs, les couleurs, la fixation, la connectique en Jack et l'utilisation avec 1 seul handicapé et 1 animateur.
  • Entrées : kinect, accéleromètre sans fil, neurosky (sans routage), capteur distance, piezo pince, micro, crayon graphite, conductivité corps (genre makey makey), webcam (face tracking, fiducials, …), gros boutons, pavé XY façon kaospad, tapis XY
  • Minimiser le champs d’intervention à un seul capteur. Possibilités de séries de capteurs identiques (ex:touches).
  • Interface : patchs musicaux (faible programmation) : Pure Data ou MaxMSP
  • Sorties : VST, sortie Midi (vers synthétiseur), 3D (Pure Data)
  • Production : Armada

État de l'art

Logiciel

PARTHENAY - OCTOBRE 2016

Résidence de développement au Foyer de vie Les Genêts. Cas d'empechements lourds.

version en cours :

Brutbox simplifiée - version intermédiaire - semaine n°2

POINTS ABORDÉS :
Recherche de simplification du logiciel pour des personnels encadrants ne pratiquant pas ou peu l'informatique musicale:

  • Création d'une collection d'objets “débutant” contenant chacun un selecteur de son pré-établis;
  • Simplification des entrées audio présnetes par défaut sur les patchs vierges (bb-micro-in.pd)
  • Simplification des sorties audio (bb-audio-out-simple.pd)
  • Renforcer la distinction entre instruments à simple déclenchement (bouton action unique) et instruments à variations (progressif);
  • Simplification de l'interface pour la fenêtre menu débutant. cf proposition ci-dessous.

COLLECTION DÉBUTANT

INSTRUMENTS (noms et système de typage à définir)

à action simples

  • synth-batterie (a faire)
  • synth-bouton
  • synth-percussion

à variations

  • synth-mono
  • synth-organ
  • synth-sirene
  • synth-mouche

EFFECTS (ergonomie a voir)

  • delay
  • flanger
  • pitch

GANTNER - FEVRIER 2016

(résidence à l'Espace Gantner) :bb-2016-02-24-gantner.zip

Nouveautés :

  • Partition commune entre les collections d'objets communs à Brutbox et Malinette.
  • Sous menu dans le menu projet pour organiser les créations par dossier
  • intégration de l'objet IN “faceOSC” des petits debrouillards
  • intégration du bloc video dans les entrées bb

!temporairement : les enregistrements Brutbox arrivent dans le dossier media/recording de la Malinette

Cette version contient la séquence d'une dizaine d'exemples pour quelques heures d'atelier avec différents exercices : voix, effets audio, ondes cérébrale, guitare électronique, loopsampler, capteur lumière et sons binauraux…

Électronique

Capteurs

  • Externe : Joystick Thrustmaster®
  • Externe : Wiimote® (mac) » Voir la page ressource Wiimote
  • Infrarouge 3/30cm : 1 ana
  • infrarouge 20/150cm : 1 ana
  • Piezo (plaque) : 1 ana
  • Pression carré (plaque) : 1 ana
  • Micro electret : 1 ana
  • Gros bouton (~buzzer) : 1 ana
  • Module Joystick : 2 ana (prise dédiée)
  • Accéléromètre ou gyroscope ? : 2 ana (prise dédiée)
  • Touch : MPR121 prises dédiées SCL/SDA - entrées digitales 5 & 6 D0/D1
  • Encodeur potentiomètre (+ robinet ?) : prises dédiées “INTERRUPTION” - entrées digitales 7 & 8 D2/D3

MindWave

Nous utilisons un casque Mindwave neurosky pour capter les donnéees (médiation et concentration) d'un utilisateur. Nous utilisons Processing qui envoie les données en OSC à PureData (les bibliothèques oscP5 et MindsetProcessing sont nécessaires).

Le code pour processing

Wiimote

Une piste d'utiliser la manette Wiimote pour creer un dispositif ou l'on peut changer de capteur. En démontant le nunchuk et en retirant le joystick nous pouvons utiliser deux entrées analogiques. Attention la wiimote est alimenté en 3.3v, donc nous sommes limité aux capteurs resistifs qui fonctionnent à cette tension.

On utilise ensuite OSCULATOR (sur macOS) pour recevoir les données et les transformer en midi. Voir page ressource Wiimote

Carte électronique

Nous utilisons pour le moment, la carte Teensy 2.0 qui permet de convertir en MIDI les données de nos capteurs. En guise de connectique nous avons opté pour des connecteurs USB (pour éviter les faux contacts).

VERSION 1

VERSION 2

Fournisseurs discounts (connecteurs et cables usb)

Firmware Teensy

Février 2016

teensy-8-in.ino

Olds Firmwares Teensy 2

Réception des données MIDI à partir de Pure Data {{.:pd-brutbox-help.png|} Envoie en 10 bits et réception avec pd avec la boite [<< 7] : <code cpp> int value = 1023; Serial.begin(9600); Serial.println(value >> 7); // ou Serial.println(value & 0x7F); </code> ++++ teensy_brutbox.ino (12 ana + encoder,sans on/off, sans capa) | <code cpp> /* * TEENSY 2 for BRUTBOX * Analog sensors + encoder + touch * * Licence : GNU/GPL3 * Date : 12/06/2015 * Website : http://reso-nance.org/wiki/projets/malinette-brutbox * * Hardware add-on : the MPR121 module for touch sensors * * Midi mapping : * 12 analog sensors (midi controller from 0 to 11) * 1 encoder (midi controller 12) */ // Include libraries #include <Encoder.h> // Midi channel const int channel = 1; // Analog setup int anaPins[] = {22,11,12,13,14,15,16,17,18,19,20,21}; // analog pins const int anaNb = 12; // number of inputs int anaCtl[] = {11,10,9,8,7,6,5,4,3,2,1,0}; // controller in int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // Encoder setup Encoder encoderSensor (7, 8); long encoderOldPosition = -999; long encoderNewPosition; long encoderLastPosition; // Sampling rate elapsedMillis msec = 0; void setup() { } void loop() { if (msec >= 40) { msec = 0; // Analog sensors loop for (int i = 0; i < anaNb; i++) { anaValues[i] = (int) analogRead(anaPins[i]) / 8 ; if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); anaLastValues[i] = anaValues[i]; } } // Encoder loop encoderNewPosition = encoderSensor.read(); if (encoderNewPosition != encoderOldPosition) { if (encoderNewPosition > encoderOldPosition) {usbMIDI.sendControlChange(12, 0, channel);} else if (encoderNewPosition < encoderOldPosition) {usbMIDI.sendControlChange(12, 127, channel);} encoderOldPosition = encoderNewPosition; } } while (usbMIDI.read()) { // Discard incoming MIDI messages. } } </code> ++++ ++++ teensy_brutbox.ino (8 analogique simple , pas de librairie encoder, wire, capacitif...) | <code cpp> // the MIDI channel number to send messages const int channel = 1; // the MIDI continuous controller for each analog input const int controllerA0 = 0; // 10 = pan position const int controllerA1 = 1; // 11 = volume/expression const int controllerA2 = 2; // 91 = reverb level const int controllerA3 = 3; // 93 = chorus level const int controllerA4 = 4; // 93 = chorus level const int controllerA5 = 5; // 93 = chorus level const int controllerA6 = 6; // 10 = pan position const int controllerA7 = 7; // 11 = volume/expression const int controllerA8 = 8; // 91 = reverb level const int controllerA9 = 9; // 93 = chorus level const int controllerA10 = 10; // 93 = chorus level const int controllerA11 = 11; // 93 = chorus level void setup() { } // store previously sent values, to detect changes int previousA0 = -1; int previousA1 = -1; int previousA2 = -1; int previousA3 = -1; int previousA4 = -1; int previousA5 = -1; int previousA6 = -1; int previousA7 = -1; int previousA8 = -1; int previousA9 = -1; int previousA10 = -1; int previousA11 = -1; elapsedMillis msec = 0; void loop() { // only check the analog inputs 50 times per second, // to prevent a flood of MIDI messages if (msec >= 50) { msec = 0; int n0 = analogRead(A0) / 8; int n1 = analogRead(A1) / 8; int n2 = analogRead(A2) / 8; int n3 = analogRead(A3) / 8; int n4 = analogRead(A4) / 8; int n5 = analogRead(A5) / 8; int n6 = analogRead(A6) / 8; int n7 = analogRead(A7) / 8; int n8 = analogRead(A8) / 8; int n9 = analogRead(A9) / 8; int n10 = analogRead(A10) / 8; int n11 = analogRead(A11) / 8; // only transmit MIDI messages if analog input changed if (n0 != previousA0) { usbMIDI.sendControlChange(controllerA0, n0, channel); previousA0 = n0; } if (n1 != previousA1) { usbMIDI.sendControlChange(controllerA1, n1, channel); previousA1 = n1; } if (n2 != previousA2) { usbMIDI.sendControlChange(controllerA2, n2, channel); previousA2 = n2; } if (n3 != previousA3) { usbMIDI.sendControlChange(controllerA3, n3, channel); previousA3 = n3; } if (n4 != previousA4) { usbMIDI.sendControlChange(controllerA4, n4, channel); previousA4 = n4; } if (n5 != previousA5) { usbMIDI.sendControlChange(controllerA5, n5, channel); previousA5 = n5; } if (n6 != previousA6) { usbMIDI.sendControlChange(controllerA6, n6, channel); previousA6 = n6; } if (n7 != previousA7) { usbMIDI.sendControlChange(controllerA7, n7, channel); previousA7 = n7; } if (n8 != previousA8) { usbMIDI.sendControlChange(controllerA8, n8, channel); previousA8 = n8; } if (n9 != previousA9) { usbMIDI.sendControlChange(controllerA9, n9, channel); previousA9 = n10; } if (n10 != previousA10) { usbMIDI.sendControlChange(controllerA10, n10, channel); previousA4 = n10; } if (n11 != previousA11) { usbMIDI.sendControlChange(controllerA11, n11, channel); previousA11 = n11; } } // MIDI Controllers should discard incoming MIDI messages. // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash while (usbMIDI.read()) { // ignore incoming messages } } </code> ++++ ++++ teensy_brutbox.ino (sans on off pour MAC) | <code cpp> /* * TEENSY 2 for BRUTBOX * Analog sensors + encoder + touch * * Licence : GNU/GPL3 * Date : 12/06/2015 * Website : http://reso-nance.org/wiki/projets/malinette-brutbox * * Hardware add-on : the MPR121 module for touch sensors * * Midi mapping : * 12 analog sensors (midi controller from 0 to 11) * 1 encoder (midi controller 12) * 12 touch sensors (midi note from 60 to 71) */ // Include libraries #include <Wire.h> #include "Adafruit_MPR121.h" #include <Encoder.h> // Midi channel const int channel = 1; // Analog setup int anaPins[] = {22,11,12,13,14,15,16,17,18,19,20,21}; // analog pins const int anaNb = 12; // number of inputs int anaCtl[] = {11,10,9,8,7,6,5,4,3,2,1,0}; // controller in int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // Encoder setup Encoder encoderSensor (7, 8); long encoderOldPosition = -999; long encoderNewPosition; long encoderLastPosition; // Capacitive Touch MPR121 module // Connection Teensy2 // USB wiring : d+ : SDA, d- : SCL, SCL = DO, SDA = D1 Adafruit_MPR121 cap = Adafruit_MPR121(); uint16_t lasttouched = 0; uint16_t currtouched = 0; const int touchNb = 12; // number of touch inputs int touchCtl[] = {60,61,62,63,64,65,66,67,68,69,70,71}; // note in // Sampling rate elapsedMillis msec = 0; void setup() { // Trying to connect to the capacitive module if (!cap.begin(0x5A)) { while (1); } delay(1000); } void loop() { if (msec >= 20) { msec = 0; // Analog sensors loop for (int i = 0; i < anaNb; i++) { anaValues[i] = (int) analogRead(anaPins[i]) / 8 ; if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); anaLastValues[i] = anaValues[i]; } } // Encoder encoderNewPosition = encoderSensor.read(); if (encoderNewPosition != encoderOldPosition) { if (encoderNewPosition > encoderOldPosition) {usbMIDI.sendControlChange(12, 0, channel);} else if (encoderNewPosition < encoderOldPosition) {usbMIDI.sendControlChange(12, 127, channel);} encoderOldPosition = encoderNewPosition; } // Capacitive loop currtouched = cap.touched(); for (uint8_t i=0; i < touchNb; i++) { if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {usbMIDI.sendNoteOn(touchCtl[i], 127, channel);} if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {usbMIDI.sendNoteOn(touchCtl[i], 0, channel);} } lasttouched = currtouched; // reset our state } while (usbMIDI.read()) { // Discard incoming MIDI messages. } } </code> ++++ ++++ teensy_brutbox.ino (avec on off) | <code cpp> /* * TEENSY 2 for BRUTBOX * Control inputs (sensors) with MIDI messages * * Licence : GNU/GPL3 * Date : 11/06/2015 * Website : http://reso-nance.org/wiki/projets/malinette-brutbox * * Hardware add-on : the MPR121 module for touch sensors * * Midi mapping : * 12 analog sensors (midi controller from 0 to 11) * 1 encoder (midi controller 12) * 12 touch sensors (midi note from 60 to 71) */ // Include libraries #include <Wire.h> #include "Adafruit_MPR121.h" #include <Encoder.h> // Midi channel const int channel = 1; // Capacitive Touch MPR121 module // Connection Teensy2 // USB wiring : d+ : SDA, d- : SCL, SCL = DO, SDA = D1 Adafruit_MPR121 cap = Adafruit_MPR121(); uint16_t lasttouched = 0; uint16_t currtouched = 0; const int touchNb = 12; // number of touch inputs const int touchThreshold = 60; int touchStateCtl[] = {40, 41, 42} ; // touch on/off int touchState[touchNb]; // state : on/off //int currentTouchValues[touchNb]; //int lastTouchValues[touchNb]; int touchCtl[] = {60,61,62,63,64,65,66,67,68,69,70,71}; // note in int touchOn = 0; // Analog setup int anaPins[] = {22,11,12,13,14,15,16,17,18,19,20,21}; // analog pins const int anaNb = 12; // number of inputs int anaCtl[] = {11,10,9,8,7,6,5,4,3,2,1,0}; // controller in int anaStateCtl[] = {20, 21} ; // sensor on (20), sensor off (21) int anaState[anaNb]; // state : on/off int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // Encoder setup Encoder encoderSensor (7, 8); long encoderOldPosition = -999; long encoderNewPosition; long encoderLastPosition; int encoderStateCtl = 13; // receive ctlout 13 int encoderOn = 0; // Sampling rate elapsedMillis msec = 0; int rate = 20; void setup() { // Midi receive : on/off sensors usbMIDI.setHandleControlChange(OnControlChange); } void loop() { if (msec >= rate) { msec = 0; // Analog sensors loop for (int i = 0; i < anaNb; i++) { if(anaState[i] == 1) { // check first if the sensor is on anaValues[i] = (int) analogRead(anaPins[i]) / 8 ; if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); anaLastValues[i] = anaValues[i]; } } } // Capacitive loop if(touchOn == 1){ currtouched = cap.touched(); for (uint8_t i=0; i < touchNb; i++) { if(touchState[i] == 1) { // check first if the sensor is on if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) { usbMIDI.sendNoteOn(touchCtl[i], 127, channel); } if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) { usbMIDI.sendNoteOn(touchCtl[i], 0, channel); } } } lasttouched = currtouched; // reset our state } // Encoder if (encoderOn == 1) { encoderNewPosition = encoderSensor.read(); if (encoderNewPosition != encoderOldPosition) { if (encoderNewPosition > encoderOldPosition) { usbMIDI.sendControlChange(12, 0, channel); } else if (encoderNewPosition < encoderOldPosition) { usbMIDI.sendControlChange(12, 127, channel); } encoderOldPosition = encoderNewPosition; usbMIDI.sendControlChange(12, encoderNewPosition, channel); } } } while (usbMIDI.read()) { // Discard incoming MIDI messages. } } // Receive Midi Control Change void OnControlChange(byte channel, byte control, byte value) { // Analog sensors on/off if (control == anaStateCtl[0]) {anaState[-value+(anaNb-1)] = 0;} else if (control == anaStateCtl[1]) {anaState[-value+(anaNb-1)] = 1;} else if (control == touchStateCtl[0]) {touchState[value] = 0;} else if (control == touchStateCtl[1]) {touchState[value] = 1;} else if (control == touchStateCtl[2]) { touchOn = value; if (touchOn == 1) {cap.begin(0x5A);} } else if (control == encoderStateCtl) {encoderOn = value;} } </code> ++++ ++++ teensy-onoff_no-capacitif.ino (cc de 20 à 31 - non attribués / sensor on(46), sensor off(47) ) | <code cpp> // Include libraries #include <Wire.h> //#include "Adafruit_MPR121.h" #include <Encoder.h> // Midi channel const int channel = 1; // Analog setup int anaPins[] = {22,11,12,13,14,15,16,17,18,19,20,21}; // analog pins const int anaNb = 12; // number of inputs int anaCtl[] = {20,21,22,23,24,25,26,27,28,29,30,31}; // cc non-attribués int anaStateCtl[] = {46, 47} ; // sensor on (46), sensor off (47) int anaState[anaNb]; // state : on/off int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // Encoder setup Encoder encoderSensor (7, 8); long encoderOldPosition = -999; long encoderNewPosition; long encoderLastPosition; int encoderStateCtl = 13; // receive ctlout 13 int encoderOn = 0; // Sampling rate elapsedMillis msec = 0; int rate = 20; void setup() { // Midi receive : on/off sensors usbMIDI.setHandleControlChange(OnControlChange); } void loop() { if (msec >= rate) { msec = 0; // Analog sensors loop for (int i = 0; i < anaNb; i++) { if(anaState[i] == 1) { // check first if the sensor is on anaValues[i] = (int) analogRead(anaPins[i]) / 8 ; if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); anaLastValues[i] = anaValues[i]; } } } // Encoder if (encoderOn == 1) { encoderNewPosition = encoderSensor.read(); if (encoderNewPosition != encoderOldPosition) { if (encoderNewPosition > encoderOldPosition) { usbMIDI.sendControlChange(12, 0, channel); } else if (encoderNewPosition < encoderOldPosition) { usbMIDI.sendControlChange(12, 127, channel); } encoderOldPosition = encoderNewPosition; usbMIDI.sendControlChange(12, encoderNewPosition, channel); } } } while (usbMIDI.read()) { // Discard incoming MIDI messages. } } // Receive Midi Control Change void OnControlChange(byte channel, byte control, byte value) { // Analog sensors on/off if (control == anaStateCtl[0]) {anaState[-value+(anaNb-1)] = 0;} else if (control == anaStateCtl[1]) {anaState[-value+(anaNb-1)] = 1;} else if (control == encoderStateCtl) {encoderOn = value;} } </code> ++++ ++++ test-nrpn.ino (sur 1 capteur analo A0) !! mais erreur de compilation… | <code cpp> // Fixed values, for demonstration uint32_t channel = 1; // channels are 1 to 16 uint32_t param = 0; // your parameter number here, 0 to 16k //uint32_t val = 2; // your value here, 0 to 16k // in actual use this would come from some physical controller like an analog value // or be computed by monitoring an encoder void sendNRPNHR(uint32_t parameter, uint32_t value, uint32_t channel) { // Send an arbitrary 14-bit value to an arbitrary 14-bit non-registered parameter // Note that param MSB and LSB are shared between RPN and NRPN, so set both at once // Also, null out the RPN (and NRPN) active parameter (best practice) after data is sent (as it persists) // Control change 99 for NRPN, MSB of param usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((99 & 0x7F) << 16) | ((parameter & 0x7F) << 24)); // Control change 98 for NRPN, LSB of param usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((98 & 0x7F) << 16) | (((parameter >>7) & 0x7F) << 24)); // Control change 6 for Data Entry MSB of value usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((6 & 0x7F) << 16) | ((value & 0x7F) << 24)); // Control change 38 for Data Entry LSB of param usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((38 & 0x7F) << 16) | (((value >>7) & 0x7F) << 24)); // Now null out active parameter by sending null (127, 0x7F) as MSB and LSB // Control change 101 for RPN, MSB of param usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((101 & 0x7F) << 16) | (0x7F << 24)); // Control change 100 for NRPN, LSB of param usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((100 & 0x7F) << 16) | (0x7F << 24)); } void setup() { } // store previously sent values, to detect changes int previousA0 = -1; elapsedMillis msec = 0; void loop() { // only check the analog inputs 50 times per second, // to prevent a flood of MIDI messages if (msec >= 80) { msec = 0; int n0 = analogRead(A0); if (n0 != previousA0) { //int valA0 = map(n0, 0, 1023, 0, 16383); sendNRPNHR(param, n0, 1); // channel 1 previousA0 = n0; } } } /////////////////////////////////// LOG ERREURS ////////////////////////////////////////////////////// Arduino : 1.6.7 (Mac OS X), TD: 1.27, Carte : "Teensy 2.0, MIDI, 16 MHz, US English" /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino: In function 'void sendNRPNHR(uint32_t, uint32_t, uint32_t)': /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:14:83: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((99 & 0x7F) << 16) | ((parameter & 0x7F) << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:14:115: error: 'usb_midi_write_packed' was not declared in this scope usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((99 & 0x7F) << 16) | ((parameter & 0x7F) << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:16:83: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((98 & 0x7F) << 16) | (((parameter >>7) & 0x7F) << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:18:82: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((6 & 0x7F) << 16) | ((value & 0x7F) << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:20:83: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((38 & 0x7F) << 16) | (((value >>7) & 0x7F) << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:23:84: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((101 & 0x7F) << 16) | (0x7F << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:23:99: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((101 & 0x7F) << 16) | (0x7F << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:25:84: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((100 & 0x7F) << 16) | (0x7F << 24)); ^ /Users/zinc5/Documents/Arduino/test-nrpn2/test-nrpn2.ino:25:99: warning: left shift count >= width of type [enabled by default] usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) | ((100 & 0x7F) << 16) | (0x7F << 24)); ^ exit status 1 Erreur lors de la compilation. </code> ++++ === Avec Encoder === * Ajouter la bibliothèque : http://www.pjrc.com/teensy/arduino_libraries/Encoder.zip ([[https://www.pjrc.com/teensy/td_libs_Encoder.html|source]]) {{.:rotary_encoder_arduino_hookup.png?200|}} === Avec capacitif MPR121 === * Module MPR121 : https://www.adafruit.com/products/1982. Alimention possible en 5V ou 3.3V * Ajouter la bibliothèque : https://github.com/adafruit/Adafruit_MPR121_Library ([[https://learn.adafruit.com/adafruit-mpr121-12-key-capacitive-touch-sensor-breakout-tutorial/wiring|source]]) {{.:mpr121.png?200|}} === Teensy for BrutBox === * Fichiers : {{.:pd-teensy-brutbox.zip|}} * Midi : https://www.pjrc.com/teensy/td_midi.html et https://www.pjrc.com/teensy/td_libs_MIDI.html **Avec Pure Data** : {{.:pd-brutbox.png|}} **Avec Arduino** : ++++ teensy_brutbox_2.ino | <code cpp> // TEENSY 2 - BRUTBOX // Control inputs (sensors) with MIDI messages // 08/06/2015 - http://reso-nance.org #include <Wire.h> #include "Adafruit_MPR121.h" #include <Encoder.h> // Capacitive apacitive MPR121 // Connection Teensy2 // USB wiring : d+ : SDA, d- : SCL, SCL = DO, SDA = D1 Adafruit_MPR121 cap = Adafruit_MPR121(); const int touchNb = 12; // number of touch inputs const int touchThreshold = 60; int touchStateCtl[] = {40, 41, 42} ; // touch on/off int touchState[touchNb]; // state : on/off int currentTouchValues[touchNb]; int lastTouchValues[touchNb]; int touchCtl[] = {60,61,62,63,64,65,66,67,68,69,70,71}; // note in int touchOn = 0; // Analog setup int anaPins[] = {22,11,12,13,14,15,16,17,18,19,20,21}; // analog pins const int anaNb = 12; // number of inputs int anaCtl[] = {11,10,9,8,7,6,5,4,3,2,1,0}; // controller in int anaStateCtl[] = {20, 21} ; // sensor on (20), sensor off (21) int anaState[anaNb]; // state : on/off int anaValues[anaNb]; // current analog values int anaLastValues[anaNb]; // previous analog values // Encoder setup Encoder encoderSensor (7, 8); long encoderOldPosition = -999; long encoderNewPosition; int encoderStateCtl = 13; // receive ctlout 13 int encoderOn = 0; const int channel = 1; // Sampling rate const long interval = 30; unsigned long currentMillis; unsigned long previousMillis = 0; void setup() { // Midi receive : on/off sensors usbMIDI.setHandleControlChange(OnControlChange); } void loop() { currentMillis = millis(); if(currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // Analog sensors loop for (int i = 0; i < anaNb; i++) { if(anaState[i] == 1) { // check first if the sensor is on anaValues[i] = (int) analogRead(anaPins[i]) / 8 ; Serial.println(anaValues[i]); if (anaValues[i] != anaLastValues[i]) { usbMIDI.sendControlChange(anaCtl[i], anaValues[i], channel); anaLastValues[i] = anaValues[i]; } } } // Capacitive loop if(touchOn == 1){ for (uint8_t i=0; i < touchNb; i++) { if(touchState[i] == 1) { // check first if the sensor is on currentTouchValues[i] = cap.filteredData(i); if ((currentTouchValues[i] - lastTouchValues[i]) < -touchThreshold) { usbMIDI.sendNoteOn(touchCtl[i], 127, channel); } if ((currentTouchValues[i] - lastTouchValues[i]) > touchThreshold) { usbMIDI.sendNoteOn(touchCtl[i], 0, channel); } lastTouchValues[i] = currentTouchValues[i]; } } } // Encoder if (encoderOn == 1) { encoderNewPosition = encoderSensor.read(); if (encoderNewPosition != encoderOldPosition) { encoderOldPosition = encoderNewPosition; usbMIDI.sendControlChange(12, encoderNewPosition, channel); } } } // Discard incoming MIDI messages. while (usbMIDI.read()) {} } // Receive Midi Control Change void OnControlChange(byte channel, byte control, byte value) { // Analog sensors on/off if (control == anaStateCtl[0]) {anaState[-value+(anaNb-1)] = 0;} else if (control == anaStateCtl[1]) {anaState[-value+(anaNb-1)] = 1;} else if (control == touchStateCtl[0]) {touchState[value] = 0;} else if (control == touchStateCtl[1]) {touchState[value] = 1;} else if (control == touchStateCtl[2]) { touchOn = value; if (touchOn == 1) { cap.begin(0x5A); for (uint8_t i=0; i<4; i++) {lastTouchValues[i] = cap.filteredData(i); } } } else if (control == encoderStateCtl) {encoderOn = value;} } </code> ++++ ===== Prototypes ===== ==== Prototype 0.1 - 03/2015==== * [[.:pistes:|Pistes initiales]] 2014 * [[.:v0.1|Protototype 0.1]] : Espace Gantner 06/03/2015 ==== Prototype 0.2 ==== **juin 2015 au LFO** : http://piratepad.net/brutbox * Sélection élargie de capteurs (sensibilités, capacités moteurs) * Design des capteurs plus gros, plus lourds, codes couleurs pour faciliter la compréhension et le maniement * Câblages plus longs pour s'installer confortablement dans un espace de jeu collectif * Patchs en forme de pièces musicales préconçues pour //X// capteurs/participants {{.:scenebrutbox.jpg|}} ==== Prototype v1 ==== * Pad de travail : http://piratepad.net/brutboxv1 ----- ===== Boites ===== Découpe de boîtes en bois contre-plaqué de 3mm avec une machine à découpe laser. <WRAP round important 80%> Attention certains fichiers ont des problèmes d'échelle (à multiplier par 125%), et d'autres sont outdatés... </WRAP> * {{.:brutbox-proto2.zip|fichiers de découpe des boites et PCB}} * {{.:bb-gaitelyrique.zip|fichiers de découpe des boites non corrects.}} Nous avons utilisé un générateur de boite : http://boxmaker.connectionlab.org

/home/resonancg/www/wiki/data/attic/projets/brutbox/dev/accueil.1477167666.txt.gz · Dernière modification: 2016/10/22 22:21 de resonance