mercoledì 1 giugno 2016

ArduinoTheremin

Questo progetto e' stata soltanto una occasione per usare la libreria Mozzi e non puo' considerato completo e finito.
Con Mozzi e' possibile trasformare Arduino in un sintetizzatore usando semplicemente il pin 9 ed il Ground collegandoli ai pin di un jack audio da pcb. Fra le altre cose il segnale in uscita e' cosi' alto che puo' essere direttamente mandato in cuffia senza necessita' di amplificazione


L'idea e' quella di usare due sensori ultrasonici SR-04 per controllare la frequenza ed il volume. Il problema e' che Mozzi usa i timer di Arduino per la propria necessita' di produzione audio e quindi SR-04 non e' il componente piu' adatto per interfacciarsi a Mozzi




le frequenze sono scalate da 4 a 40 cm con frequenze da 100 a 660 Hz (la frequenza e' stata poi portata 4 ottave piu' alto) mentre il volume va da 0 al massimo passando da 4 a 40 cm

la base utilizzata deriva da questo sketch
---------------------------------------------------------
/*
This file uses a Ultrasonic Sensor code that was
 modified from the a code found on: 
 http://winkleink.blogspot.ca/2012/05/arduino-hc-sr04-ultrasonic-distance.html
 and modified codes from Mozzi examples and reference documentation.
 */

// Include Mozzi Classes
#include <MozziGuts.h>;
#include <mozzi_config.h>
#include <Oscil.h>;
#include <tables/sin1024_int8.h>;
#include <tables/saw2048_int8.h>;
#include <tables/cos2048_int8.h>;
#include <mozzi_rand.h>;
#include <LowPassFilter.h>;

#define CONTROL_RATE 64

Oscil <2048, AUDIO_RATE> osc(SAW2048_DATA); // Oscilator waveform
Oscil <COS2048_NUM_CELLS, CONTROL_RATE> filterMod(COS2048_DATA); // Low Pass Filter waveform
Oscil <2048, CONTROL_RATE> kvib(SAW2048_DATA); // Vibrato Waveform
LowPassFilter lpf;

// Ultrasonic Sensor Pins
int trigPin = 11;
int echoPin = 12;
// Ultrasonic Sensor Pins
int trigPin2 = 8;
int echoPin2 = 7;

byte volume;

void setup(){
  Serial.begin(115200);
  startMozzi(CONTROL_RATE);
  //lpf.setResonance(20);
  kvib.setFreq(16.5f);
  filterMod.setFreq(1.3f);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
}

void updateControl(){

  // Distance Sensor
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(100);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  int freq = map(distance, 4, 40, 100, 660);
  /*
  C = 261
  C#= 277
  D = 293
  D#= 311
  E = 329 
  F = 349
  F#= 369
  G = 391
  G#= 415
  A = 439
  A#= 466
  B = 493
  C = 523
  */
  
  
  int duration2, distance2;
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(100);
  digitalWrite(trigPin2, LOW);
  duration2 = pulseIn(echoPin2, HIGH);
  distance2 = (duration2/2) / 29.1;
  volume = map(distance2, 4, 40, 0, 255);
  
  byte cutoff_freq = 100 + filterMod.next()/2;
  lpf.setCutoffFreq(cutoff_freq);
  osc.setFreq(freq*2);

  //float depth = 1; // vibrato depth
  //float vibrato = depth * kvib.next();

  /*if (rand(CONTROL_RATE/2) == 0) // Low Pass Filter Frequency
  {
    filterMod.setFreq((float)rand(255)/64);
  }
  byte cutoff_freq = 100 + filterMod.next()/2;
  lpf.setCutoffFreq(cutoff_freq);

  if(xRead > 500){
    osc.setFreq(freq);
  }
  else if(xRead < 500){
    osc.setFreq(freq*4);
  } */
}

int updateAudio(){
  char audio = (lpf.next(osc.next())*volume)>>8;
  return (int) audio;
}

void loop(){
  audioHook(); 
}