Featured Posts

PComp | Week 5 | Theremin v.3

October 10, 2017

This is my 3rd week working on this (see previous week and the previous previous post).

 

 

 

Last week I managed to somewhat smoothen the value given by the IR sensor, and controlled the value using a pot and Volume 3 library.

 

This was my "note to self" for next iteration:

  • Consider using other sensors, maybe stretch sensor to get more stable output

  • Try using another value-smoothing algorithm

  • Have another sensor as vibrato control

  • Consider using mp3 shield to output less-annoying sounds

 

 

Here was my approach to improving the theremin* with what we learned in class.

 

  1. Get new sensors: I bought short-distance IR sensor (8-30cm) for hopefully more stable values & photo cell meant for vibrato control.

  2. Apply new sensors to existing build from last week, make sure the values are smooth and I can get glissando pitch output.

  3. Use mp3 shield to play background music, so that the theremin* does not sound that annoying.

 

 

Theremin v3.1 (First attempt)

 

Function 1: Theremin simulator

  • New IR short distance sensor

  • Simple averaging/smoothing algorithm to avoid program getting stuck in a “for loop”

  • Photo cell as vibrato control

 

 

 

#include <TimerOne.h>
#include <Volume3.h>

#define photoPin A1
#define IRPin A5
#define potPin A0
#define speakerPin 3

 

int photoRead = 0;
int prevPhoto = 0;
int diff = 0;

int IRRead = 0;
int avgIR = 0;

int potVal = 0;
int volume = 0;

int pitch = 0;

 

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

 

void loop() {

  photoRead = analogRead(photoPin);
  IRRead = analogRead(IRPin);
  potVal = analogRead(potPin);

  volume = map(potVal, 0, 1023, 0, 1000);  
  
  diff = photoRead - prevPhoto;
  //Serial.println(diff);
  prevPhoto = photoRead;

  avgIR = 0.95 * avgIR + 0.05 * IRRead;
  //Serial.println(IRRead);

  //diff = 0;
  pitch = avgIR + (diff*3);
  pitch = 800 - pitch;

  Serial.println(IRRead);

  //vol.tone(speakerPin, pitch, volume);
  tone(speakerPin, pitch);
  delay(5);
}

 

 

But unfortunately when I ran pot and photocell together the photocell became very erratic. In the video it can be seen that the photocell fluctuates when I turn up the pot. I suspected that having so many things connected to the breadboard / arduino kind of messes with the current / voltage. I could not figure it out :(

 

I ended up factoring out the photocell values / vibrato.

 

 

 

 

Theremin v3.2 (Second Attempt)

 

Function 1: Theremin simulator

  • IR short distance sensor -> pitch control

  • pot -> volume control

  • photo cell ->  vibrato control

 

Function 2: Background music player

  • DFPlayer Mini + speaker -> background music output

  • switch -> background music control (pause & play)

  • LED -> indicator of playing / not playing music

 

Building this was a nightmare....

 

There were so many inputs and outputs it was super hard to troubleshoot. My first speaker was busted (I think cos of the overclocking by Volume 3 library). My breadboard was so small often I got confused which pin connects to which. Even my button switch behaved erratically and I had to debounce it with a crude delay function.

 

And here's the source code:

 

#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <TimerOne.h>
#include <Volume3.h>

 

#define photoPin A1
#define IRPin A5
#define potPin A0
#define speakerPin 9
#define buttonPin 8
#define ledPin 7

#define C4 261
#define C5 523
#define C6 1046

 

SoftwareSerial mySerial(10, 11); //RX TX Pins
DFRobotDFPlayerMini myDFPlayer;

 

int photoRead = 0;
int prevPhoto = 0;
int vibrato = 0;

int IRRead = 0;
int avgIR = 0;

int potVal = 0;
int avgPot = 0;
int volume = 0;

int pitch = 0;

int switchState = 0;
boolean isPlaying = false;
boolean isFirstTime = true;


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

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  myDFPlayer.enableLoop(); //enable loop
}

 

 

void loop() {

 

//THEREMIN FUNCTIONS
  // 1. Read all the inputs
  photoRead = analogRead(photoPin);
  IRRead = analogRead(IRPin);
  potVal = analogRead(potPin);

  // 2. Vibrato control value (photo cell)
  vibrato = photoRead - prevPhoto;
  if (vibrato > 10 || vibrato < -10) {
    vibrato = 0;
  }
  prevPhoto = photoRead;
  //Serial.println(vibrato);

  // 3. Smoothing IR & Pot Values
  avgIR = 0.95 * avgIR + 0.05 * IRRead;
  avgIR = constrain(avgIR, 170, 540);
  //Serial.println(avgIR);
  avgPot = 0.99 * avgPot + 0.01 * potVal;

  // 4. Theremin output logic (Volume & Pitch)

  avgPot = constrain(avgPot, 100, 1000);
  volume = map(avgPot, 100, 1000, 0, 1000);
  //Serial.println(volume);

  pitch = map(avgIR, 170, 540, 0, C6 - C5);
  pitch = C6 - pitch;
  //pitch += vibrato * 10;

  vol.tone(speakerPin, pitch, volume);
  //tone(speakerPin, pitch);
  //Serial.println(pitch);
  delay(1);

 

 

//BG MUSIC PLAYER
  switchState = digitalRead(buttonPin);
  //Serial.println(switchState);

  if (switchState && isFirstTime) {
    myDFPlayer.volume(20);  //Set volume value. From 0 to 30
    myDFPlayer.playMp3Folder(2);
    digitalWrite(ledPin, HIGH);
    Serial.println("HELLO");
    isFirstTime = false;
    isPlaying = true;
    delay(2000);
    switchState = LOW;
  }

  if (switchState && isPlaying && !isFirstTime) {
    myDFPlayer.pause();
    digitalWrite(ledPin, LOW);
    isPlaying = false;
    Serial.println("PAUSING");
    delay(2000);
    switchState = LOW;
  }

  if (switchState && !isPlaying && !isFirstTime) {
    myDFPlayer.start();
    digitalWrite(ledPin, HIGH);
    isPlaying = true;
    Serial.println("RESUMING");
    delay(2000);
    switchState = LOW;
  }
}

 

 

 

Share on Facebook
Share on Twitter
Please reload

Related Posts
Please reload

Generative Music | Latent Space Sequencer

December 13, 2018

1/10
Please reload

Recent Posts