Code: Select all
int PiezoPin = 9; // piezo output pin
//delay values in microseconds to produce standard octave of tones (C2 to B2)
int C = 7644;
int CS = 7216;
int D = 6811;
int DS = 6428;
int E = 6067;
int F = 5727;
int FS = 5406;
int G = 5102;
int GS = 4816;
int A = 4545;
int AS = 4290;
int B = 4050;
int rest = 0;
int period = 0;
//array holding one octave of notes + rest
int noteArray[13] = {C, CS, D, DS, E, F, FS, G, GS, A, AS, B, rest};
int noteValue = 50; //length of note to be played (100ms)
float note = 0; //value to hold note value
//these 2 variables are used to select the octave of the note to be played
int octave = 0;
int multiplier = 0;
//time counting variables (for note length)
long time = 0;
long newtime = 0;
void setup() {
pinMode(PiezoPin, OUTPUT); //piezo speaker connected to this pin
}
////////////////////////////////////////////////////////////////////////////
//function to measure time - compare current time with previous time value
int CompareTime()
{
newtime = millis();
newtime = newtime - time;
}
////////////////////////////////////////////////////////////////////////////
//function to play note selected (or rest) for a determined length of time
int PlayNote(float delaytime, float notelength)
{
time = millis(); //read current time and store for reference
newtime = millis(); //read new current time - for comparison
if (delaytime < 1) //this is true only if a rest value has been selected
{
do
{
CompareTime();
//wait, generate no sound until the duration of rest has been met
} while (newtime < notelength);
}
else
{
do
// This will toggle the output pin HIGH and LOW at a frequency to produce
// the selected note for the note duration.
// Turning on for a portion of the period(duty cycle) and then off for the
// remainder of the period produces pulse width modulation.
{
digitalWrite (PiezoPin, HIGH);
delayMicroseconds (delaytime);
digitalWrite (PiezoPin, LOW);
delayMicroseconds (period-delaytime);
CompareTime();
} while (newtime < notelength); //do this until reaching note duration
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void loop()
{
//following determines the octave of the note to be played
//using random function
octave = 1;
multiplier = (random(1,8));
for (int i=0; i<multiplier; i++){
octave = octave * 2;
}
//random choice of note value
note = (noteArray[(random(0,12))]/octave);
//max delay: 7644/2 = 3822 microseconds so we will say the period is 4000ms
period = 4000;
PlayNote (note, noteValue); //play note (50ms long)
PlayNote (rest, noteValue); //rest for same time
}