Theremin . Crea Música con tus manos usando Arduino

El Theremin es uno de los primeros instrumentos musicales electrónicos, que se empezó a desarrollar en los años 20. Consta de dos antenas: una controla el volumen y la otra el tono.

COMPONENTES Y SUMINISTROS

Arduino UNO×1
Sensor ultrasónico – HC-SR04 (genérico)×2
Tablero de pan (genérico)×3
Potenciómetro digital no volátil, 10 kohmusamos un modelo x9c103×1
Amplificador operacional, Op Amp + Comparador + ReferenciaOpcional×1
Cables de puente (genéricos)×1
Altavoz: 3W, 4 ohmios×1
LED (genérico)×1
Resistencia 475 ohmios×1

HERRAMIENTAS Y MÁQUINAS NECESARIAS

Hy gluegunPistola de pegamento caliente (genérica)

SOBRE ESTE PROYECTO

Un theremin es un instrumento musical electrónico controlado sin contacto físico por el thereminista (intérprete). Fue patentado por Leon Theremin en 1928 y su sección de control generalmente consiste en dos antenas metálicas que detectan la posición relativa de las manos del thereminista y osciladores de control para la frecuencia con una mano, y la amplitud (volumen) con la otra. En el siguiente proyecto tratamos de emular el funcionamiento de este instrumento utilizando dos sensores ultrasónicos que son capaces de detectar distancias y en función de esto le decimos al Arduino que emita sonido a diferentes frecuencias y amplitudes a través de un altavoz. Aquí hay una explicación detallada.

Frecuencia:

Usamos un sensor ultrasónico con cuatro pines. Dos son para entrada de voltaje y tierra. Otro llamado disparador se utiliza para enviar un pulso ultrasónico a través de una escritura digital en el programa. El último pin se llama eco y recibe el pulso ultrasónico cuando rebota. El tiempo que tarda el pulso en volver a la placa se lee y se almacena en una variable, luego lo convertimos en unidades de distancia (cm). Finalmente usamos la biblioteca TonePlayer para convertir cada distancia a una frecuencia diferente. Estamos usando el sistema de temperamento igual para calcular notas musicales exactas, así que para cada valor diferente de distancia tenemos una nota musical diferente.

Amplitud:

Para controlar la amplitud utilizamos otro sensor ultrasónico, pero esta vez decidimos utilizar la biblioteca NewPing y la función sonar.ping_cm() que envía un ping, devuelve la distancia en centímetros o 0 (cero) si no hay eco de ping dentro del límite de distancia establecido. Esta información se almacena en la distancia variable. Luego hicimos dos funciones especiales llamadas incremento y decremento. Estas funciones indican al potenciómetro digital si debe aumentar o disminuir el valor de su resistencia en función de la información de distancia. Si la distancia aumenta también la resistencia, si la distancia disminuye, la resistencia también disminuirá.

Salida:

Un altavoz común está conectado directamente a los pines de salida del potenciómetro digital. Los diferentes valores de resistencia se percibirán como variaciones de volumen. Opcionalmente podemos utilizar un amplificador para el altavoz, pero realmente no es necesario.

Remarks:

1) We used a common led as an indicator of the variation of resistance.

2) You gotta use the special TonePlayer library (link provided) cause any other similar library will crash Arduino whenever if runs with the NewPing library.

3) Tone functions only works on Arduino Uno. I’m not exactly sure why.

Here’s the final result:

CÓDIGO

Arduino ThereminArduino

Es un código para el arduino theremin

//In this project we create a theremin with two ultrasonic sensors, one for volume and another for tone. We use the digital potentiometer X9C103P.
/*                                                                                                                                                                                                                                               
 * Potentiometer conecctions:
 * 1 - INC - Arduino pin 2
 * 2 - U/D - Arduino pin 3
 * 3 - VH  - 5V
 * 4 - VSS - GND
 * 5 - VW  - Output
 * 6 - VL  - GND
 * 7 - CS  - Arduino pin 4
 * 8 - VCC - 5V
 *
 */
//Note: we include two libraries: NewPing and TonePlayer because if we use the library NewPing with a tone function, the sketch doesnot compile. 
#include <NewPing.h> 
#include <TonePlayer.h>
#define MIN_DISTANCIA 35 
TonePlayer tone1(TCCR1A, TCCR1B, OCR1AH, OCR1AL, TCNT1H, TCNT1L); 

NewPing sonar(10, 11, 35); //The first and the second number are the pins of the sensor of volume, the third is the maximum distance 

// name pins for sensors and the potentiometer
int echo = 12;                            
int trigger = 13;
int INC = 2;
int UD = 3;
int distancia;
int actual, anterior;
// necessary variables
unsigned long tiempoRespuesta;
float distancia2;
float tono1;

void setup() {
// set all the pins 
Serial.begin(9600); //use of monitor serie for check the distance
pinMode(trigger, OUTPUT); //Tone sensor                    
pinMode(echo, INPUT); //Tone sensor    
pinMode(2, OUTPUT); //Potentiometer
pinMode(3, OUTPUT); //Potentiometer
//pinMode (speaker, OUTPUT);

for(int j=0; j<90; j++){ //As we do not know in what value the potentiometer is, we place the value at the minimum
     decremento(); 
  }  
  
}

void loop() {
  
  digitalWrite(trigger, HIGH);           
  delayMicroseconds(10);   // Pulse of ten microseconds                      
  digitalWrite(trigger, LOW);                   
  tiempoRespuesta = pulseIn(echo, HIGH);  // Echo of the pulse
  distancia2 = tiempoRespuesta/58;  //Calculation of the distance in centimeters

  if (distancia2 < MIN_DISTANCIA) { 
  //Conversion of distance into a value for a sound 
  tono1 = 50.0*pow(2,(distancia2/12.0));  //pow alculates the value of a number raised to a power
  pinMode(9, OUTPUT);
  tone1.tone(tono1);  //Generates the tone with the previous value (220 Hz) 
  delay(10); 
  }

distancia = sonar.ping_cm(); //Calculation of the distance in centimeters (with the library NewPing)
Serial.print(distancia); //Check the distance
//Change the value "distancia", to values that are useful for the rise and fall of the potentiometer
actual = map(distancia, 0, 35, 0, 200);

//Compares the mapped values to raise or lower the potentiometer
if(actual > anterior){
  for(int i = 0; i< (actual - anterior); i++){
  decremento();
  }
}

else{
  for(int i = 0; i <= (anterior - actual); i++)
  {
  aumento();
  }
}

anterior = actual; //The value is updated with each loop
delay(1);

  
}

//The U/D input controls the direction of the wiper movement and whether the counter is incremented or decremented
//The INC input is negative-edge triggered. Toggling INC will move the wiper and either increment or decrement the counter in the direction indicated by the logic level on the U/D input.
//The next two functions produce these toggling in the two directions (increment, decrement)

void aumento(){ //aumento == increment
digitalWrite(UD, HIGH);
digitalWrite(INC, LOW);
digitalWrite(INC, HIGH);
delay(10);
digitalWrite(INC, LOW);
}

void decremento(){ //decremento == decrement
digitalWrite(UD, LOW);
digitalWrite(INC, LOW);
digitalWrite(INC, HIGH);
delay(10);
digitalWrite(INC, LOW);
}

ESQUEMAS

Circuito de Theremin

DESCARGAREs un esquema para el theremin Arduino. Sólo copia la configuración.

Captura de pantalla 2019 06 11 22 tanukzctvq