Das Theremin (auch: Thereminvox, Thereminovox, Termenvox, ursprünglich Aetherophon, genannt auch Ätherwelleninstrument) ist ein 1920 erfundenes elektronisches Musikinstrument. Es ist das einzige verbreitete Musikinstrument, das berührungslos gespielt wird und dabei direkt Töne erzeugt. Sein Name geht auf den Erfinder, den Russen Lew Termen, zurück, der sich in den USA Leon Theremin nannte.
Ein Theremin besitzt ursprünglich zwei Antennen, wobei eine für die Veränderung der Lautstärke (engl. volume) und die andere für die Veränderung der Tonhöhe (engl. pitch) zuständig ist. Durch Annäherung/Entfernung der Hand verändert man leicht die Kapazität eines elektrischen Schwingkreises. Dadurch ändert sich auch die Frequenz des Schwingkreises. Mittels eines zweiten, unbeeinflussten Schwingkreises wird dann diese Frequenzänderung hörbar gemacht.
Mein mit dem Arduino umgesetztes Theremin verwendet anstelle der elektrischen Schwingkreise Abstandssensoren. Diese bestimmen den Abstand der Hände zum Sensor. Die beiden Abstände werden dann in eine Tonhöhe bzw. Lautstärke umgewandelt. Um die Lautstärke des Tons zu verändern, kommt ein digitales Potentiometer vom Typ MCP41010 zum Einsatz. Über dieses Potentiometer wird der auszugebende Ton an einen Audioverstärker (mit dem Chip LM386) weitergeleitet.
Als Abstandssensoren können entweder die beliebten Ultraschallsensoren vom Typ HC-SR04, oder Abstandssensoren vom Typ Sharp GP2Y0A41SK0F verwendet werden.
Bildquelle: https://artmargins.com/between-bad-things-good-vibrations-leon-theremin-t-vox/
Arduino-Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#include <SPI.h> // include the SPI library #define CS_Pin 10 // CS_Pin of MCP41010 #define ECHOPIN_volume 2 // Pin to receive echo pulse #define TRIGPIN_volume 3 // Pin to send trigger pulse #define ECHOPIN_pitch 4 // Pin to receive echo pulse #define TRIGPIN_pitch 5 // Pin to send trigger pulse #define SPEAKER_Pin 6 // Pin für Lautsprecher float frequency; // put out frequency float volume; // put out volume float distance_pitch; // distance for pitch-control float distance_volume; // distance for volume-control // =================== // ====== SETUP ====== // =================== void setup() { Serial.begin(9600); pinMode (CS_Pin, OUTPUT); // CS_Pin is an output pinMode(ECHOPIN_volume, INPUT); pinMode(TRIGPIN_volume, OUTPUT); pinMode(ECHOPIN_pitch, INPUT); pinMode(TRIGPIN_pitch, OUTPUT); pinMode(SPEAKER_Pin, OUTPUT); SPI.begin(); // initialize SPI: } // =========================== // ========== LOOP =========== // =========================== void loop() { // ============================== // ultra sonic distance for pitch // ============================== digitalWrite(TRIGPIN_pitch, LOW); // Set the trigger pin to low for 2uS delayMicroseconds(2); digitalWrite(TRIGPIN_pitch, HIGH); // Send a 10uS high to trigger ranging delayMicroseconds(10); digitalWrite(TRIGPIN_pitch, LOW); // Send pin low again distance_pitch = pulseIn(ECHOPIN_pitch, HIGH) / 58.0; // Read in times pulse frequency = 4000.0 / (distance_pitch + 1.0); //frequency = (1500.0 / 23.0) * (25.0 - distance_pitch); // points (2/1500) and (25/0) if (frequency < 30) { frequency = 0.0; } if (frequency > 1400) { frequency = 1400.0; } // =============================== // ultra sonic distance for volume // =============================== digitalWrite(TRIGPIN_volume, LOW); // Set the trigger pin to low for 2uS delayMicroseconds(2); digitalWrite(TRIGPIN_volume, HIGH); // Send a 10uS high to trigger ranging delayMicroseconds(10); digitalWrite(TRIGPIN_volume, LOW); // Send pin low again distance_volume = pulseIn(ECHOPIN_volume, HIGH) / 58.0; // Read in times pulse /* volume = 255.0 / (distance_volume + 1.0); if (volume > 255.0) { volume = 255.0; } */ volume = (255.0 / 23.0) * (25.0 - distance_volume); // points (2/255) and (25/0) if (volume > 255.0) { volume = 255.0; } if (volume < 0) { volume = 0.0; } Serial.print("d = "); Serial.print(distance_pitch,0); Serial.print(" f = "); Serial.print(frequency,0); Serial.print(" volume = "); Serial.println(volume,0); tone(SPEAKER_Pin,(int)frequency); // sending the pitch to the speaker-pin digitalPotWrite((int)volume); // sending the volume to the digital poti //delay(50); // Wait 50mS before next ranging } // ============================ // ======== SUBROUTINE ======== // ============================ void digitalPotWrite(byte value) { // take the SS pin low to select the chip: digitalWrite(CS_Pin,LOW); SPI.transfer(B00010001); // The command byte SPI.transfer(value); // The data byte // take the SS pin high to de-select the chip digitalWrite(CS_Pin,HIGH); } |