I couldn't find a library that could run a buzzer quartet so I decided to just make my own function for it with VirtualDelay. The problem is I can't really do that...but I got close! The only issue is that it's out of tune (at least a half step flat) and I'm not sure why. Here's the code:
#include <avdweb_VirtualDelay.h>
//stores every note frequency by note from O0 - O8
float C[9] = {16.35, 32.70, 65.41, 130.81, 261.63, 523.25, 1046.50, 2093, 4186.01};
float Db[9] = {17.32, 34.65, 69.30, 138.59, 277.18, 554.37, 1108.73, 2217.46, 4434.92};
float D[9] = {18.35, 36.71, 73.42, 146.83, 293.66, 587.33, 1174.66, 2349.32, 4698.63};
float Eb[9] = {19.45, 38.89, 77.78, 155.56, 311.13, 622.25, 1244.51, 2489.02, 4978.03};
float E[9] = {20.60, 41.20, 82.41, 164.81, 329.63, 659.25, 1318.51, 2637.02, 5274.04};
float F[9] = {21.83, 43.65, 87.31, 174.61, 349.23, 698.46, 1396.91, 2793.83, 5587.65};
float Gb[9] = {23.12, 46.25, 92.50, 185, 369.99, 739.99, 1479.98, 2959.96, 5919.91};
float G[9] = {24.50, 49, 98, 196, 392, 783.99, 1567.98, 3135.96, 6271.93};
float Ab[9] = {25.96, 51.91, 103.83, 207.65, 415.30, 830.61, 1661.22, 3322.44, 6644.88};
float A[9] = {27.50, 55, 110, 220, 440, 880, 1760, 3520, 7040};
float Bb[9] = {29.14, 58.27, 116.54, 233.08, 466.16, 932.33, 1864.66, 3729.31, 7458.62};
float B[9] = {30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07, 7902.13};
float q = 1000; //quarter note in milliseconds
VirtualDelay d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21;
VirtualDelay m[8] {(micros), (micros), (micros), (micros), (micros), (micros), (micros), (micros)};
int buzzer[4] = {3, 5, 6, 9};
void setup()
{
pinMode(buzzer[0], OUTPUT);
pinMode(buzzer[1], OUTPUT);
pinMode(buzzer[2], OUTPUT);
pinMode(buzzer[3], OUTPUT);
}
void loop()
{
/* I'm testing how the note() function sounds different
from the tone() function by playing them one after another */
tone(3, A[4]);
delay(1000);
noTone(3);
delay(1000);
note(1, A[4], 1000, d1);
delay(1000);
}
void note(int buzz, float freq, int length, VirtualDelay l)
{
bool first = true;
int delay1 = (buzz*2)- 1;
int delay2 = (buzz*2)- 2;
l.start(length);
m[delay1].start(1);
while (!l.elapsed())
{
if (first)
{
if (m[delay1].elapsed())
{
digitalWrite(buzzer[buzz-1], HIGH);
m[delay2].start(500000/freq);
first = false;
}
}
else
{
if (m[delay2].elapsed())
{
digitalWrite(buzzer[buzz-1], LOW);
m[delay1].start(500000/freq);
first = true;
}
}
}
digitalWrite(buzzer[buzz-1], LOW);
}
Edit: Some users pointed out some missing code so I added it in, I'm not sure how I missed it