Incom ist die Kommunikations-Plattform der Fachhochschule Potsdam mehr erfahren

BeatBox

Ein MIDI Controller entstanden im Musical Interfaces Kurs WS 12/13.

Idee

In diesem Kurs wollten wir mit Hilfe der Arduino Entwicklungsumgebung und dem Teensy eigene Musikinstrumente entwickeln.
Mein Ansatz war es das „auf dem Tisch trommeln“ auf eine neue Ebene zu bringen. Wie wäre es, wenn man den Tisch durch verschiedene Instrumente und Effekte ersetzt. Was wird dann aus den kleinen, beiläufig entstehenden Rhythmen?

Konzept

Um verschiedene Instrumente in einer einfachen Form unterzubringen, habe ich mich für einen Würfel entschieden. Je nachdem auf welcher Seite die BeatBox liegt, werden andere Töne gespielt. So sind 6 verschiedene Konfigurationen nur einen Kipp weit entfernt. Und da immer 5 Seiten erreichbar sind, gibt es potenziell 30 Töne oder Melodien.
Wird der Würfel gekippt und bei ca. 45° ein Sensor berührt kann ein Effekt gesteuert werden.
Der Prozess ist folgendermaßen:
Wie ein Schlagzeuger gibt man mit den 4 ersten Schlägen das Tempo vor. Dann hat man in dem Tempo 2 Takte Zeit um die erste „Spur“ zu spielen. Anschließend können weitere Instrumente hinzugefügt und Effekte über das Ganze gelegt werden.
Hat man einen Fehler gemacht oder Lust auf einen neuen Beat kann man durch ein leichtes Schütteln der BeatBox zum Ausgangszustand zurückkehren.

Prototyp Video

Umsetzung

Um das Trommeln auf der BeatBox zu erkennen entschied ich mich für kapazitive Sensoren und einen FSR (Force Sensitive Resistor).
Beim kalibrieren der kapazitiven Sensoren viel mir auf, dass sie sich auch als Abstandssensoren eigenen die sogar durch opake Materialien hindurch funktionieren. Da sich das sehr gut für die Effektansteuerung im Zusammenspiel mit Tönen eigenet, entschied ich mich einen der Sensoren nicht als „Tipperkenner“, sondern als Abstandssensor zu verwenden.
Um die Lage der Box zu erkennen ist ein Accelerometer (Beschleunigungssensor) eingebaut. Wie in dem Fritzing Sketch zu erkennen ist, braucht das ADXL335 3,3V statt der 5V mit denen das Teensy operiert. Daher ist ein Spannungsregler eingebaut der sich um die passende Spannung kümmert.

Arduino Code

#include <CapSense.h>

CapSense cs_0 = CapSense(5,1);  //100k
CapSense cs_1 = CapSense(4,0);  //100k
CapSense cs_2 = CapSense(3,7);  //100k
CapSense cs_3 = CapSense(6,10); //5,1m
CapSense cs_4 = CapSense(6,9);  //100k
const int fsrPin = 18;
const int xPin = 21;
const int yPin = 20;
const int zPin = 19;
const int threshold = 60;
boolean fsrPressed = false;
boolean pressed0 = false;
boolean pressed01 = false;
boolean pressed1 = false;
boolean pressed11 = false;
boolean pressed2 = false;
boolean pressed21 = false;
boolean pressed22 = false;
boolean pressed3 = false;
boolean pressed4 = false;
boolean playing = false;
int cap = 0;
int oldCap = 0;
int oldUpSide = 0;
int init = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  // get location and filter ill readings
  int upSide  = getUpSide();  
  if(upSide == -1) upSide = oldUpSide;
  else if(upSide != oldUpSide) {
    if(upSide == 2 || oldUpSide == 2) {
      usbMIDI.sendControlChange(7,127,1);
      usbMIDI.sendControlChange(6,127,1);
    }
    oldUpSide = upSide;
  }

  /*  0: lid / cap 100k
   1: cap 100k
   2: cap 100k
   3: cap 5,1m
   4: cap 100k
   5: fsr */
  switch(upSide) {
  case 0:
    pressed0 = playTone(50,1,cs_0.capSense(100),pressed0);
    pressed01 = playTone(51,1,cs_1.capSense(100),pressed01);
    break;
  case 1:
    pressed1 = playTone(60,1,cs_1.capSense(100), pressed1);
    pressed11 = playTone(61,1,cs_2.capSense(100), pressed11);
    cap = cs_3.capSense(100);
    if(cap > 2000) cap = 2000;
    if(cap > 200 && oldCap != cap) {
      usbMIDI.sendControlChange(10, map(cap, 150, 2000, 0, 127), 1);
      oldCap = cap;
    } 
    break;
  case 2:
    pressed2 = playTone(46,1,cs_2.capSense(100), pressed2);
    pressed21 = playTone(49,1,cs_1.capSense(100), pressed21);
    pressed22 = playTone(51,1,cs_4.capSense(100), pressed22);
    break;
  case 3:
    break;
  case 4:
    pressed4 = playTone(30,1,cs_4.capSense(100), pressed4);
    break;
  case 5:
    int in = analogRead(fsrPin);
    if(in > 100 && !fsrPressed) {
      fsrPressed = true;
      int m = map(in,100,1023,20,127);
      usbMIDI.sendNoteOn(52, m, 1);
    } 
    else if(in < 10 && fsrPressed) {
      fsrPressed = false;
      usbMIDI.sendNoteOff(52, 0, 1);
    }
    break;
  }
}

int getUpSide() {
  int xRead = analogRead(xPin);
  int yRead = analogRead(yPin);
  int zRead = analogRead(zPin);

  if(xRead < 345 && xRead > 325 && yRead < 345 && yRead > 325 
      && zRead < 425 && zRead > 405) return 0;
  if(xRead < 275 && xRead > 255 && yRead < 345 && yRead > 325 
      && zRead < 360 && zRead > 340) return 1;
  if(xRead < 350 && xRead > 330 && yRead < 275 && yRead > 255 
      && zRead < 360 && zRead > 340) return 2;  
  if(xRead < 340 && xRead > 320 && yRead < 340 && yRead > 320 
      && zRead < 290 && zRead > 270) return 3;
  if(xRead < 410 && xRead > 390 && yRead < 340 && yRead > 320 
      && zRead < 355 && zRead > 335) return 4;
  if(xRead < 343 && xRead > 323 && yRead < 410 && yRead > 390 
      && zRead < 353 && zRead > 333) return 5;
  if(xRead > 550 || yRead > 550 || zRead > 550) {    
    // Stop music and reset BeatBox
    init = 0;
    usbMIDI.sendControlChange(126,1,1);
    usbMIDI.sendControlChange(127,1,1);
  }
  if(xRead < 400 && xRead > 375 && yRead < 340 && yRead > 320 
      && zRead < 405 && zRead > 380) {
    while(cs_0.capSense(100) > 40) {
      // MIDI Controlchanges while tilting the BeatBox
      usbMIDI.sendControlChange(2,map(analogRead(zPin),340,420,0,127),1);
    }
  }
  return -1;
}

boolean playTone(int ton, int channel, int val, boolean pressed) {
  if(val > threshold) { 
    if(!pressed) {
      if(init < 5) {
        // Send the first 4 hits to determine BPM
        if(init < 4) usbMIDI.sendNoteOn(1,127,1);
        init++;
        if(init == 5) {
          usbMIDI.sendControlChange(5,127,1);
          usbMIDI.sendNoteOn(ton,127,channel);
        }
        pressed = true;
      } 
      else {
        usbMIDI.sendNoteOn(ton,127,channel);
        pressed = true;
      }
    }
  } 
  else if(val < threshold - 40 && pressed) {
    usbMIDI.sendNoteOff(ton,0,channel);
    pressed = false;
  }
  return pressed;
}

Fazit

Mit meinem Endergebnis bin ich sehr zufrieden, alle Funktionen funktionieren wie ich es mir erhofft habe. Was die BeatBox allerdings nicht ersetzen kann ist Talent. Fehlendes Taktgefühl fällt sofort auf. Allerdings macht das spielen und experimentieren mit der BeatBox unheimlich viel Spaß. Da die BeatBox mit MIDI Befehlen mit der Audiosoftware kommuniziert ist sie extrem vielseitig einsetzbar, so können Musiker sicher noch sehr viel mehr raus holen.
Der Kurs ist eine fantastische Einführung in die große Welt von Arduino. Stefan ist mit allen Wassern der Microcontoller-Bastelei gewaschen und konnte alle Fragen bestens beantworten.

Ein Projekt von

Art des Projekts

Studienarbeit im Grundstudium

Betreuung

Stefan Hermann

Zugehöriger Workspace

Musical Interfaces 2012

Entstehungszeitraum

Wintersemester 2012 / 2013