Error message

Deprecated function: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in drupal_session_initialize() (line 245 of /var/www/blog.mechanicape.nl/includes/session.inc).

Pseudo Midi Theremin met Arduino

Een theremin is een elektronisch muziekinstrument dat bespeeld wordt door de afstand tussen de handen en twee antennes te variëren. De speler raakt het instrument niet aan. De theremin werd uitgevonden door Léon Theremin in 1919. In 1923 kwam dan de opvolger van de theremin; de Aetherophone, een soortgelijk instrument, dat lang niet zo populair werd als de theremin.

De rechterhand beïnvloedt de toonhoogte en de linkerhand het geluidsvolume. Doordat minimale bewegingen al hoorbaar zijn, klinkt het instrument bijzonder expressief. De klank lijkt op die van een vrouwelijke operastem of een viool.

Bekende bespelers van de theremin zijn Clara Rockmore (een studente van Léon Theremin), Fay Lovsky, Thorwald Jørgensen, Jean-Michel Jarre, Carolina Eyck, Pamelia Kurstin en Lydia Kavina.

In de jaren 50 werd dit instrument vaak gebruikt in sciencefiction-films, als er een UFO of vliegende schotel in beeld voorbij kwam. En ook in de herkenningsmelodie van de originele serie van "Star Trek" -met onder meer Captain Kirk en Mister Spock- was de theremin overduidelijk te horen.

 

De pseudo theremin

De pseudo theremin werkt qua bediening hetzelfde als de originele theremin. Met één hand wordt de toonhoogte aangestuurd met met de andere hand het volume. Onze theremin werkt alsvolgt

  • Door middel van Sharp afstandssensoren wordt de positie (hoogte) van de handen bepaald.
  • Een microcontroller zet het signaal van de Sharpsensoren om naar het MIDI protocol
  • Het midi-signaal wordt via een kabel doorgegeven aan een synthesizer

Hieronder volgen de instructies om zelf eeen pseudo midi theremin te bouwen.

 

Onderdelenlijst

  •  2 x Sharp afstandssensor (met bijbehorende kabeltjes)
  • 1 x Midi-connector (vrouwtje)
  • 1 x Midi-kabel (mannetje/mannetje)
  • 3 rolletjes draad (1 x rood, 1 x zwart, 1 x grijs)
  • 1 x Arduino board

Deze onderdelen aansluiten volgens het onderstaande schema.


aansluitschema theremin

 

 

Sourcecode

Hieronder de broncode voor de Arduino software.

//Pseudo MIDI theremin for Arduino v1.0
//Rein Velt - Theo's Mechanic Ape - http://mechanicape.com
//15 january 2012 


#include 
NewSoftSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code

int note=0;
int instrument=0;
int volume=0;


void setup() {
  delay(3000);
  instrument=117;
  
  Serial.begin(57600);

  //Setup soft serial for MIDI control
  mySerial.begin(31250);

  //channel 0
  talkMIDI(0xB0, 0x07, 127); //0xB0 is channel message, set channel volume to near max (127)
  talkMIDI(0xB0, 0,0x78); //Select the bank of melodic sounds
 
  
  //Set the instrument for channel 0
  talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command  
}

void loop() {
 int oldnote=note;
 note=getSensorValue(0);   //get value from first sensor (port A0)
 volume=getSensorValue(1); //get value from second sensor (port A1)
 noteOn(0,note,volume);    //play it
}

//Send a MIDI note-on message.  Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note, byte attack_velocity) 
{
  talkMIDI( (0x90 | channel), note, attack_velocity);
}

//Send a MIDI note-off message.  Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) 
{
  talkMIDI( (0x80 | channel), note, release_velocity);
}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) 
{
  mySerial.print(cmd, BYTE);
  mySerial.print(data1, BYTE);
  //Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes 
  //(sort of: http://253.ccarh.org/handout/midiprotocol/)
  if( (cmd & 0xF0) <= 0xB0)
   mySerial.print(data2, BYTE);
}


//read converted value from the specified sensor
int getSensorValue(int analogPort)
{
    int intval=0;
    int result=0;
  
    intval=analogRead(analogPort);
    delay(40);
    float volts=(intval)*0.0048828125;
    int distance = round(65*pow(volts, -1.10));
    if (distance>0 and distance<150)
    {
      result=map(distance,0,150,0,127);
    }
    return  result;
}

Heb je nog vragen of opmerkingen over dit ontwerp? Neem dan vooral contact op of laat een bericht achter.