Super Super Electronic Faux-Tibetan Pseudo-Singing Bowl-vessel
From Physical Programming
Contents |
Overview
Although bowls are described as "containers" or "vessels", Tibetan Singing Bowls function as a musical instrument. I think this is an interesting take on the function of a bowl. The aim is to create a modern interpretation of this type of instrument, in a similar way to how an electric guitar is a reintrepetation of a classical guitar. The singing bowl is played by rubbing the sides to create friction and a complex tone much the same as rubbing the ring of a wine glass can produce a tone. I plan on using the arduino and analog data to create noises based on interaction with the "bowl".
Components
- Arduino
- 9v Battery pack
- Speaker (8Ω 0.5W)
- Resistors (I forget)
Arduino and sensor integration
Each touch sensor will have a set pitch, rising in a set interval around the circular rim of the bowl. Once a sensor is triggered, the destination variable is set to that variable, and the pitch variable slowly rises to the new destination pitch, changing the pitch of the synth.The destination pitch will be changed by touching any sensor regardless if the last destination pitch was reached or not.
Another variable will control the volume of the synth, the max volume will be set upon touching a sensor, and will decrease to zero when the synth is idle. This is a simple decay system, however, I may implement an ASD (attack, sustain, delay) system for more “realistic” and less abrupt sounds if I have time.
Optional: Additionally, a weight sensor would be put in the base that would control the master pitch which would pitch up or down octaves depending on the content (weight) inside the bowl - such as fruit, pebbles, herbs or car keys. Or perhaps change the fullness of the synth by raising the volume of a sine wave (which produces a pleasing tone) alongside something thinner sounding such as a saw or square wave, which are both slightly abrasive sounding.
Electronics
I started out trying to work out what sort of resistors and buttons I would need to get the arduino to work as I wanted to, but I stupidly wired it up with two buttons as a test, unaware that adding in more buttons would change the results of the other analog pins. Far too frustrating. From here I just started effectively messing around with various configurations until the Arduino started responding in a way that I liked. Given that my only experience with electronics is circuit bending I probably should of expected that.
Although the wiring was working as I wanted it to, the introduction of the battery pack as the power source seems to change all my thresholds and just generally run havoc with my code. The "sensors" are either too sensitive and all get triggered constantly, or are have their thresholds set too high meaning all "triggers" are dismissed.
Ultimately, the code works with the arduino plugged into a computer's USB port, but not when powered by a 9V battery. Therefor I will be using a different set of code just for the purpose of the exhibition (see below).
Processing
////////////////////////////////////////////////////////
//
// Title: Tibetan Singing Bowl Sketch
// Author: Daniel Kerris
// Description:
// Uses 5 analag pins to change between 5 frequencies
// Producing a tone that decays over time.
//
////////////////////////////////////////////////////////
//Initlialise variables
int speakerPin = 11;
//Frequency / Tone
int freq = 0;
int duration = 150;
//Volume
float vol = 0; //volume variable
int volmax = 20;
float fadeSpeed = 1; //interval at which vol decreases
//Debug mode
int debug = false; //whether or not to print to serial monitor (slows down code)
//NOTES
//Store all the notes of the C minor pentatonic scale (common 5 note scale)
#define NOTE_C4 262
#define NOTE_DS4 311
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_AS4 466
//define arrays for button data
int button[5] = { A0, A1, A2, A3, A4}; //holds the button pins
int buttonFreq[5] = { NOTE_C4, NOTE_DS4, NOTE_F4, NOTE_G4, NOTE_AS4}; //holds each buttons respective frequency
int sensor[5] = { 0, 0, 0, 0, 0}; //holds sensor data (the data from the analog pins)
int sensorThreshold = 150; //once sensor data goes over this, the button is "triggered"
//Setup
void setup() {
if (debug) { //if debugging
Serial.begin(9600); //begin serial
}
}
//PlayTone function
void playTone(int _tone, int duration) {
for (long i = 0; i < duration * 1000L; i += _tone * 2) {
analogWrite(speakerPin, vol);
delayMicroseconds(_tone);
analogWrite(speakerPin, 0);
delayMicroseconds(_tone);
}
}
//Loop
void loop() {
//read buttons
for (int i=0; i <= 5; i++) { //cycles through all buttons, storing their sensor info in corresponding sensor
//for instance, sensor[2] = button[2]'s data
sensor[i] = analogRead(button[i]);
if (sensor[i] > sensorThreshold) { //if sensor is triggered
freq = buttonFreq[i]; //change frequency to corresponding button
vol = volmax; //bump volume back up
}
}
//Adjust frequency - NOTE: Originally, I wanted the frequency to "slide" between notes
// The lack of clarity through the volume control created some interesting
// noise (aka garbled mess) that I eventually decided to avoid.
// Using the method I was below however, freq would never quite reach freqDest.
// which is probably why the sound was so crunchy.
//
/*if (freq > freqDest) {
freq -= (freq - freqDest)/8; //The distance between both frequencies divided by 8
}
if (freq < freqDest) {
freq += (freqDest - freq)/8;
} */
//Fade volume
if (vol > 0) {
//begin very dodgy two part "envelope"
if (vol > volmax/2) {
vol -= fadeSpeed; //decrease vol
}
else {
vol -= fadeSpeed/2; //decrease vol by half usual speed
}
}
else { //if vol is not greater than zero
vol = 0; //revert to zero (off)
}
//Play current frequency for duration
playTone(freq, duration);
if (debug) { //if debugging, print various data
/*Serial.print("S0: ");
Serial.print(sensor[0]);
Serial.print(" S1: ");
Serial.print(sensor[1]);
Serial.print(" S2: ");
Serial.print(sensor[2]);
Serial.print(" S3: ");
Serial.print(sensor[3]);
Serial.print(" S4: ");
Serial.println(sensor[4]);*/
Serial.print(" - Current Freq: ");
Serial.print(freq);
Serial.print(" - Current Vol: ");
Serial.println(vol);
delay(10); //delay avoids overloads
}
}
Alternative sketch which I will be using for the exhibition:
/////////////////////
//
// Name: Simple Melody Tone
// Author: Daniel Kerris
// Description:
// Produces a rising melody using a speaker/piezo connected
// from speakerPin to GRND.
//
// tone(speakerPin, freq, toneLength);
//
//
////////////////////
//Initialise variables
int freq = 50;
int freqmax = 160;
int freqmin = freq;
int freqspeed = 50; //interval to raise pitch by
int noteLength = 400;
int restLength = 600;
int count = 0;
int speakerPin = 11; //plug speaker/piezo between pin 8 and GRND
void setup() {
//nothing
}
void loop() {
//Frequency climb
if (freq < freqmax) {
freq += freqspeed; //Raises freq
}
else { //until freqmax is reached
freq = freqmin; //return to freqmin
}
if (count <= 2) {
//beat 1
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 2
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 3 (higher + longer note)
tone(speakerPin, freq*2, noteLength*2);
delay(restLength/2);
//beat 4
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 5 (two quick notes)
tone(speakerPin, freq*2, noteLength/2);
delay(restLength/2);
tone(speakerPin, freq*2, noteLength/2);
delay(restLength/2);
//beat 6
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 7 (higher + longer note)
tone(speakerPin, freq*2, noteLength*2);
delay(restLength/2);
//beat 8 (four quick notes)
tone(speakerPin, freq*3, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq*2, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq/2, noteLength/4);
delay(restLength/4);
count+=1;
}
else {
//beat 1
tone(speakerPin, freq, noteLength);
delay(restLength);
//Note 3 (higher + longer note)
tone(speakerPin, freq*2, noteLength*2);
delay(restLength/2);
//beat 2
tone(speakerPin, freq/2, noteLength/2);
delay(restLength/2);
tone(speakerPin, freq/2, noteLength/2);
delay(restLength/2);
//Note 4
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 2
tone(speakerPin, freq/2, noteLength/2);
delay(restLength/2);
tone(speakerPin, freq/2, noteLength/2);
delay(restLength/2);
//beat 6
tone(speakerPin, freq, noteLength);
delay(restLength);
//beat 7 + 8 (eight quick notes)
tone(speakerPin, freq*3, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq*2, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq*4, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq*3, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq*2, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq/2, noteLength/4);
delay(restLength/4);
tone(speakerPin, freq/4, noteLength/4);
delay(restLength/4);
count = 0;
}
}
Fibre integration
I will use yarn in the form of rope, threaded through the body of the bowl, converging at the base. When the rope is taught, the object takes the form of the bowl. When the rope is loose, the object takes the form of a wooden shaker.
Failing this, I will simply stitch the pieces of the bowl together permanently.
Timber integration
The bowl will be made of geometric pieces, stitched together to form a rudimentary bowl in the shape of a pentagon, as I am using a C minor pentatonic scale for my notes. 5 sides = 5 notes.


