I'm trying to replicate a short music clip with two piezos, and I want them to play at the same time. While the right piezo is playing, I want the left one to still be looping. The problem is, I'm not sure how.
//Left hand
const int leftPin = 10; /Left pin
const int leftTones[] = {123.4, 103.83, 138.59, 92.50}; //The looping left tones
const int leftDelays[] = {700, 1300, 900, 900}; //How long those tones last
const int leftNotes = 4; //How many left notes there are
//Right hand
const int rightPin = 2; //Right pin
const int rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, //The looping right tones
659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88,
554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99,
587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33,
659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99,
698.46, 1174.66, 1318.51};
const int rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, //How long those tones last
300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200,
700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300,
200, 400, 300, 200, 400, 300, 200};
const int rightNotes = 40; //How many right notes there are
void setup(){
pinMode(leftPin, OUTPUT);
pinMode(rightPin, OUTPUT);
delay(1000);
}
void loop(){
for (int i = 0; i < leftNotes; i++){
tone(leftPin, leftTones[i]);
delay(leftDelays[i]);
noTone(leftPin);
}
for (int i = 0; i < rightNotes; i++){
tone(rightPin, rightTones[i]);
delay(rightDelays[i]);
noTone(rightPin);
}
}
With this code, the left piezo plays first, and then the right piezo plays. It should be at the same time.
Edited Code:
long currentMillis = 0;
long leftPreviousMillis = 0; // previous time for left hand
long rightPreviousMillis = 0; // previous time for right hand
const int leftNotes = 4; // The amount of left notes
const int rightNotes = 40; // The amount of right notes
int leftIndex = 0; // The specific index for the left piezo
int rightIndex = 0; // The specific index for the right piezo
const int leftPin = 10; // The left piezo
const int rightPin = 2; // The right piezo
// The specific left pitches (as float)
const float leftTones[] = {123.4, 103.83, 138.59, 92.50};
// How long the left pitches last for
const long leftDelays[] = {700, 1300, 900, 900};
// The specific right pitches (as float)
const float rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88, 554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99, 698.46, 1174.66, 1318.51};
// How long the right pitches last for
const long rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, 300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200, 700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300, 200, 400, 300, 200, 400, 300, 200};
void setup() {
pinMode(leftPin, OUTPUT);
pinMode(rightPin, OUTPUT);
Serial.begin(9600);
delay(1000);
tone(rightPin, rightTones[rightIndex]);
tone(leftPin, leftTones[leftIndex]);
}
void loop() {
currentMillis = millis();
// Left hand notes
if (currentMillis - leftPreviousMillis >= leftDelays[leftIndex]) {
noTone(leftPin); // Turn off the left note
leftPreviousMillis = currentMillis;
leftIndex++;
if (leftIndex == leftNotes) // Reset left hand index
leftIndex = 0;
tone(leftPin, leftTones[leftIndex]); // Turn on the new left note
}
// Right hand notes
if (currentMillis - rightPreviousMillis >= rightDelays[rightIndex]) {
noTone(rightPin); // Turn off the right note
rightPreviousMillis = currentMillis;
rightIndex++;
if (rightIndex == rightNotes) // Reset right hand index
rightIndex = 0;
tone(rightPin, rightTones[rightIndex]); // Turn on the new right note
}
}
I've done some testing, and I think it's a problem with the tones function. Right now, this code only plays the right hand notes. The problem is this part:
tone(rightPin, rightTones[rightIndex]);
tone(leftPin, leftTones[leftIndex]);
When I do this:
tone(leftPin, leftTones[leftIndex]);
tone(rightPin, rightTones[rightIndex]);
Only the left hand notes are heard. But, it's not perfect. There's little beeps and buzzes every now and then. This leaves me with the conclusion that if there are two tones at the same time, it only plays the one it reads first. I've tested it with simpler code, and it stands true.
So that begs the question, is it even possible to use two piezos at the same time with one Arduino? I'm testing it with the Arduino simulator tinkercad, so maybe that's the problem? My code works for the left piezo, and the right piezo. But when you put them together, everything messes up.
