And now for something completely different...
From Physical Programming
Ok so a week after being introduced to the Arduino and all of its potential, i started to realise that the project i was originally intending on doing has really already been done. Lets do something that would be original and 'exciting' (in some respects of course).
There are a limited number of users that have used sound successfully with the Arduino. This was something worth investigating....
Contents |
INTRODUCTION
Having considered the project proposal once again, I found that I would be simply replicating something that has already been achieved and is at the disposal of the general public. Being introduced to the Arduino, it opened up a huge amount of potential to what can be achieved through simple programming.
Now, as a kid I was introduced to a simple toy called the Stylophone. Using a metal keyboard in conjunction with a stylus; which acts as a switch, the device was able to generate raw frequencies that are sent to a speaker. This allows the user to general sounds simply in order to orchestrate their own tunes. Sadly this was to come to an end when the company stopped production. It was remade but the quality of the product isn’t anything to be proud of.
A seedy Rolph Harris Promoting the Stylophone back in the Hay-Day
Using the interface of the Stylophone has a few advantages:
- very flexible in the construction of the components
- simple relay of sound scales
- potential to change the pitch with a switch
There are a few existing projects that have used a similar configuration to achieve the same result: usually using a keyboard for the switches. This works the same way as the stylus and the keypad, except I felt the need to construct the whole product from scratch.
RESEARCH AND CONSTRUCTION
Though the Arduino website, there are several links that refer to the various ways in which you can work with audio through the Arduino and programming. Through a combination of using the Reference page directly from www.arduino.cc and something that turned out to be very similar to my project; only without the finesse of course. (http://narbotic.net/?p=95)
What was also needed in regards to research were the location of the parts that were to be used. These included:
- Arduino unit
- Arduino software
- speaker output
- copper plate
- stylus
- copious amounts of wire
A Sexy Pezzo (speaker)
Arduino on Breadboard (sexy)
The copper keys soldered onto rainbow wire (all sorts of sexy)
All of the electrical components were to be purchased from the “ever reliable” Jaycar, but in regards to the keyboard; this was a job for the workshop. I was able to obtain a sheet of copper and cut the keys to a desired shape. The backing for the unit was also manufactured here: helping to keep the keys in line and not contacting each other, avoiding interference. The stylus was a simple use of connecting a wire to a piece of copper then insulating it with lengths of electrical tape.
Next, with the rainbow wire strip, each key was soldered onto the end of each individual wire; which in turn was to connect to the Arduino unit. Using a rainbow strip instead of individual wires made sure all the cables were different colours, avoiding confusion.
Following this, it was as easy as wiring up the desired wire to its corresponding input port, and the speaker to the output port; grounding each as we go. While doing so, I came to the conclusion that there was a need to put the output on one of the analog pins; for the reason being that it was to be a variable pitch going from a corresponding switch to the output. The use of an analog pin allows for a series of frequencies to be used rather than a single bland note. However this was a discovery that was found during troubleshooting. More of that later.
With the combination of these references, I went about scripting the code.
SCRIPTING
Using the references and some tenacity, I was able to create a code that would read the status of a pin and project a frequency to the output. Let me walk you through the entire code:
Each note has a different pitch to create a certain note. These figures were projected from a site that has done all the hard work for everyone (http://www.phy.mtu.edu/~suits/notefreqs.html) . However this could also be done by linking a keyboard up to a computer, playing a note, and use MIDI software to analyse the different frequencies produced.
Oh The Pain!!
Since I would to be mimicking a similar styled program as Cunningham of Narbotic.net, I felt it would be wise to use the same frequencies as him. Using the float function allowed for the precision of a frequency, rather than just using integers:
float noteval;
float c = 130.8; float d = 146.8; float e = 164.8; float f = 174.6; float g = 196; float a = 220; float b = 246.9; float C = 261.6;
Set the speaker output to any of the analog pins:
#define speakerPin 9
Define the input pins on the digital side (considering they will be either on or off):
#define cPin 1 #define dPin 2 #define ePin 3 #define fPin 4 #define gPin 5 #define aPin 6 #define bPin 7 #define CPin 8
Variable for reading the pin status (needed in a switch):
int val = 0;
The speaker would let out a drone of all the notes unless it was told not to; in this case turning all the switches off to cut the sound out:
int Statec=LOW; int Stated=LOW; int Statee=LOW; int Statef=LOW; int Stateg=LOW; int Statea=LOW; int Stateb=LOW; int StateC=LOW;
int currenetSwitchState = HIGH;
Defining what pin is an input and output:
void setup(){
pinMode(c, INPUT);
pinMode(d, INPUT);
pinMode(e, INPUT);
pinMode(f, INPUT);
pinMode(g, INPUT);
pinMode(a, INPUT);
pinMode(b, INPUT);
pinMode(C, INPUT);
pinMode(speakerPin, OUTPUT);
Instead of spending more time and money buying resistors and soldering the whole unit together, the Arduino allows for it to act as a pull-up resistor for all of the pins. This prevents the unit shorting out when the current in the switches are deactivated:
digitalWrite(c, HIGH); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, HIGH); digitalWrite(a, HIGH); digitalWrite(b, HIGH); digitalWrite(C, HIGH); }
The program itself. Basically it tells the Arduino what frequency to play once a certain switch is activated, and when to be quiet:
void loop(){
//c
val = digitalRead(cPin);
if (val == HIGH){
digitalWrite(speakerPin, Statec);
} else {
analogWrite(speakerPin, c);
}
val = digitalRead(dPin);
if (val == HIGH){
digitalWrite(speakerPin, Stated);
} else {
analogWrite(speakerPin, d);
}
val = digitalRead(ePin);
if (val == HIGH){
digitalWrite(speakerPin, Statee);
} else {
analogWrite(speakerPin, e);
}
val = digitalRead(fPin);
if (val == HIGH){
digitalWrite(speakerPin, Statef);
} else {
analogWrite(speakerPin, f);
}
val = digitalRead(gPin);
if (val == HIGH){
digitalWrite(speakerPin, Stateg);
} else {
analogWrite(speakerPin, g);
}
val = digitalRead(aPin);
if (val == HIGH){
digitalWrite(speakerPin, Statea);
} else {
analogWrite(speakerPin, a);
}
val = digitalRead(bPin);
if (val ==HIGH){
digitalWrite(speakerPin, Stateb);
} else {
analogWrite(speakerPin, b);
}
val = digitalRead(CPin);
if (val == HIGH){
digitalWrite(speakerPin, StateC);
} else {
analogWrite(speakerPin, C);
}
}
TESTING
Now came the fun part: troubleshooting. For starters, the program was, for some strange reason, playing all the frequencies at once, without anything being switched on. Some playing around with the switch conditions fixed this.
Next issue was nothing was playing at all. This was fixed by toggling the switch conditions again, still keeping the setting that had everything quiet until something was switched on. This fixed the problem and a sound was playing, regardless to the fact that it was just a single tone.
As I had explained earlier, using the analog pins instead of the digital pins allows for a variance in the frequency projected to the output; instead of being in an on or off state. For starters, I had programmed the output to be a simple on or off output; not allowing for that variable state to occur. This was the reason behind the single tone being generated regardless of what switch was connected. This was as simple a changing the program from “digitalWrite” to “analogWrite", at least that's what I thought.
Changing this stopped the speaker from turning on. Not sure why, so I went back to the wiring; where everything seemed fine. To test all the wiring I used a simple program to turn on a LED via each switch, then another program to run a simple sound pattern through the speaker. Looking further into the latter program, I realised that the basis of this program could be the reason for my program not to work.
The program by Paul Badger can be found on the Arduino website under references and is a great springboard to go from when something in your own audio program isn’t working: also good for testing all the wiring to the speaker. The main part of the program that allows for the variation of square waves is the “freqout” function. This function places timing and frequency together to produce variable sound waves. This was the missing feature in my program.
Using the basis of the existing program, slightly modifying the ‘freqout’ script, and changing around some other functions that related to the freqout script I came up with this:
//DEFINING THE PINS FOR EACH SWITCH #define switchBPin 1 #define switchCPin 2 #define switchDPin 3 #define switchEPin 4 #define switchFPin 5 #define switchGPin 6 #define switchHPin 7 #define switchIPin 8 #define switchJPin 9 #define pitchPin 0 #define speakerOut 13 //GIVING THESE COMMANDS SOME VALUE (SO TEMPREMENTAL) int pitchval = 1; int val = 0;
int freq,t;
float noteval; //VAUES OF EACH NOTE IN REGARDS TO FREQUENCY float C = 130.8; float D = 146.8; float E = 164.8; float F = 174.6; float G = 196; float A2 = 220; float B2 = 246.9; float C2 = 261.6; float D2 = 293.7;
//DESIGNATING PIN TYPES
void setup() {
pinMode(switchBPin, INPUT);
pinMode(switchCPin, INPUT);
pinMode(switchDPin, INPUT);
pinMode(switchEPin, INPUT);
pinMode(switchFPin, INPUT);
pinMode(switchGPin, INPUT);
pinMode(switchHPin, INPUT);
pinMode(switchIPin, INPUT);
pinMode(switchJPin, INPUT);
//TURNS ON PULL UP RESISTORS FOR EACH PIN, SAVING A TONNE OF SOLDERING AND RESISTORS
digitalWrite(switchBPin, HIGH);
digitalWrite(switchCPin, HIGH);
digitalWrite(switchDPin, HIGH);
digitalWrite(switchEPin, HIGH);
digitalWrite(switchFPin, HIGH);
digitalWrite(switchGPin, HIGH);
digitalWrite(switchHPin, HIGH);
digitalWrite(switchIPin, HIGH);
digitalWrite(switchJPin, HIGH);
}
//THE PROGRAMMING OF THE NOTES SCALED FROM LOW TO HIGH
void loop() {
if( analogRead(pitchPin) > 150)
{
pitchval = (analogRead(pitchPin) / 100); //MAKES IT REALLY REALLY QUIET UNTIL A SWITCH IS CONNECTED
}
else if( digitalRead(switchJPin) == LOW ) //HIGHEST NOTE
{
noteval = D2;
freqout((int)noteval, t);
}
else if( digitalRead(switchIPin) == LOW )
{
noteval = C2;
freqout((int)noteval, t);
}
else if( digitalRead(switchHPin) == LOW )
{
noteval = B2;
freqout((int)noteval, t);
}
else if( digitalRead(switchGPin) == LOW )
{
noteval = A2;
freqout((int)noteval, t);
}
else if( digitalRead(switchFPin) == LOW )
{
noteval = G;
freqout((int)noteval, t);
}
else if( digitalRead(switchEPin) == LOW )
{
noteval = F;
freqout((int)noteval, t);
}
else if( digitalRead(switchDPin) == LOW )
{
noteval = E;
freqout((int)noteval, t);
}
else if( digitalRead(switchCPin) == LOW )
{
noteval = D;
freqout((int)noteval, t);
}
else if( digitalRead(switchBPin) == LOW )
{
noteval = C;
freqout((int)noteval, t);
}
else
{
digitalWrite(speakerOut, LOW);
}
}
//FREQOUT CODE BY PAUL BADGER (SLIGHTLY MODIFIED TO SUIT THE SETUP)
void freqout(int freq, int t)
{
int hperiod; //calculate 1/2 period in us
long cycles, i;
hperiod = (500000 / ((freq - 7) * pitchval)); // subtract 7 us to make up for digitalWrite overhead - WAS A FLUKE JUST QUIETLY
// calculate cycles
cycles = ((long)freq * (long)t) / 1000; // calculate cycles
for (i=0; i<= cycles; i++){ // play note for t ms
digitalWrite(speakerOut, HIGH);
delayMicroseconds(hperiod);
digitalWrite(speakerOut, LOW);
delayMicroseconds(hperiod - 1); // - 1 to make up for fractional microsecond in digitaWrite overhead
}
}
Once competing all of this, I gave it a test run. SUCCESS!! (and the people rejoiced). The stylophone worked; in regards to giving out different frequencies for each key. The one thing that needs to be looked into is the continuation of sound once the switch is deactivated; as this occurs every so often.
The Completed Unit
The Make-shift Stylus
CONCLUSION
It was a worthwhile experiment to use sound with something that I had first associated with lights and movement alone. This project has opened my eyes to the many possibilities that can be achieved with the Arduino, and also places into perspective the amount of work that is placed into the construction of a product as simple a the stylophone. Hopefully with more development, I will acquire skills that could reach the unimaginable...









