For our project, Luke and I decided to use two infrared sensors to create a digital instrument. We wanted to use one on each hand so that a musician could use turntables or another instrument and then add more layers by using the Wearamin without it getting in the way.
After we had a working prototype with two filters (created using the Mozzi library) we decided that instead of moving our hands up and down, we could build a “staircase” setup that would let us move our hands horizontally along an X axis to make it easier and look a bit less nerdy. We also decided to embed lights beneath the apparatus to allow for a visual responsive element along with the audio.
We fabricated the boxes using opaque acrylic and embedded them in a black base that would allow us to reposition the blocks depending on the effect we wanted without changing the lighting in the base.
As we played with the Wearamin, we noticed a pretty nasty high-frequency buzz coming directly from the audio output. I was able to limit it using an audio filter in Logic, but having to run sound through the computer/sound card significantly limits the portability and flexibility of the instrument. After a lot of research, we built two different low-pass filter circuits to reduce this feedback, first from the audio output, seen here:
We also tried a filter on the Input (i.e. the Infrared sensors). This had a very strange effect, which was a sort of “phasing” of sound, but it didn’t cut out the feedback. This is the circuit that we used:
Unfortunately, neither of these filters worked as we hoped they would, and our time was running out. As such, we chose to temporarily ignore this issue and focus on the lighting, while continuing to use the computer/sound card to fine-tune the sound output.
For the lighting, we originally bought 16 RGB LEDs for flexibility, but we found out we couldn’t use a shift register with the Analog input from the IR sensors. As such, we decided to buy an RGB LED strip, but it didn’t arrive when we needed it. For the demo, I programmed a single RGB with a decibel sensor. That can be seen here:
Here’s a video of the dB sensor/light combo in action:
We’d like to continue working on this for our final project. Here’s a list of what we’d like to accomplish:
- Add more instruments/tones and filters, to allow for a wider range of expression
- Enable switching between different instruments using a pressure sensor
- Integrate RGB strip in the base of our structure and add the code onto the same Arduino with our instrument so we can trigger lights on volume and frequency and not on dB levels
- Build a filter that works correctly, allowing us to take the computer out of the equation entirely
- Integrate with a looping pedal to allow for on-the-fly layered compositions
Arduino Code:
// Arduino that generates sound (instrument effects): #include <MozziGuts.h> #include <Oscil.h> // oscillator template #include <tables/triangle_valve_2048_int8.h> // sine table for oscillator // use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above Oscil <TRIANGLE_VALVE_2048_NUM_CELLS, AUDIO_RATE> aSig(TRIANGLE_VALVE_2048_DATA); #define PIANO_PIN 0 // set the input for the knob to analog pin 0 #define FILTER_PIN 1 int frequency; // to convey the volume level from updateControl() to updateAudio() unsigned char vol; void setup(){ Serial.begin(115200); // set up the Serial output so we can look at the input values startMozzi(); // :)) } void updateControl(){ // read the variable resistor for volume int sensor_value = mozziAnalogRead(PIANO_PIN); // value is 0-1023 int filter_value = mozziAnalogRead(FILTER_PIN); vol = filter_value >> 2; // 10 bits (0->1023) shifted right by 2 bits to give 8 bits (0->255) vol = map(filter_value, 0, 800, 0, 255); if (sensor_value <= 70) { frequency = 0; } else if (sensor_value <= 200) { frequency = 523.25; } else if (sensor_value <= 240) { frequency = 440; } else if (sensor_value <= 280) { frequency = 392; } else if (sensor_value <= 360) { frequency = 329.63; } else if (sensor_value <= 410) { frequency = 293.66; } else if (sensor_value <= 480) { frequency = 261.63; } else if (sensor_value <= 575) { frequency = 196; } else if (sensor_value <= 700) { frequency = 130.81; } aSig.setFreq(frequency); // print the value to the Serial monitor for debugging Serial.print("Sensor = "); Serial.println((int)sensor_value); } int updateAudio(){ return ((int)aSig.next() * vol)>>8; // shift back into range after multiplying by 8 bit value } void loop(){ audioHook(); // required here }
Adafruit sound sensor code:
#include "SPI.h" #include "Adafruit_WS2801.h" uint8_t dataPin = 2; // Yellow wire on Adafruit Pixels uint8_t clockPin = 3; // Green wire on Adafruit Pixels #define PIN6 Adafruit_WS2801 strip = Adafruit_WS2801(30, dataPin, clockPin); int mappedMicValue; void setup() { strip.begin(); strip.show(); Serial.begin(9600); } void loop(){ int micPin = analogRead(0); Serial.println(micPin); delay(1); //map value , look up map function mappedMicValue = map(micPin, 0, 900, 0, 255); //blink on for (int i=0; i<=30; i++) { strip.setPixelColor (i,mappedMicValue,0,0); strip.show(); } //blink off // for (int i=0; i<=32; i++){ // strip.setPixelColor (i,0,0,0); // strip.show(); // } //delay (1); }
Student blogs:
http://www.samccarmichael.com/blog/
http://freerangeling.tumblr.com/
Leave a Reply