Hello,
so I'm doing a little experiment to see whether the project I have in mind can be pulled out or not. I have the idea of coding a simple piano, but with the ability of playing chords. Doing a little research I've come to understand (correct me if I'm wrong though, please!) that Arduino is not able to generate two squarewaves of different frequencies at a time.
With that in mind, I thought it should be possible to trick the human ear by playing two notes, one after another, but very quickly. That is, quickly enough to make our brain think both sounds are playing at the same time. I'm pretty much new into coding. Arduino has been my first approach to coding languages, so I'm not really used to thinking in the way it's needed in order not to leave any blank holes where the code doesn't know what to do, you know, those things we humans use to take for granted such as what do we do if "x" condition is not reached. I guess it takes a little time and practice to get the hang of it.
To give a more detailed explanation of what I intend: imagine i'd like to play a simple C-E-G major chord. i'd like to implement a code that's able to:
- Play a C4 note (262Hz) for a very short time (let's say 50ms). Then stop.
- Automatically after that, play an E4 note (329Hz) for another 50ms. Then stop again.
- Automatically after stopping, play a G4 note (391Hz) for another 50ms. Stop again.
- Repeat this process until I release my finger from any of the buttons that form the C-E-G chord.
If you think about it, it can also be understood as a very fast paced arpeggio. I'd like to know if this is possible, and if so, what is the correct syntax in order to implement it. I have a little draft here where I've got a piano able to play these C, E and G notes separately. However, I've no idea how to properly implement my idea of chords. Here's the code:
//Define digital i/o 1,2 and 4 as musical notes C, E and G.
int C = 1;
int E = 2;
int G = 4;
//Define i/o 3 as the speaker.
int OUT = 3;
int i;
//Define inputs and outputs.
void setup() {
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, OUTPUT);
pinMode(4, INPUT);
}
void loop() {
while (digitalRead(C) == 1) {
tone(OUT, 262);
}
while (digitalRead(E) == 1) {
tone(OUT, 329);
}
while (digitalRead(G) == 1) {
tone(OUT, 391);
}
while ((digitalRead(C) == 1) && (digitalRead(E) == 2)) {
tone(OUT, 262, 50);
tone(OUT, 329, 50);
}
noTone(OUT);
}
I tried using while with two variables (C and E) playing together. The way I understand it, what I'm saying is "while C and E are on a HIGH level, play C for 50ms, then play G for another 50ms, then repeat"
I have also attatched a schematic made in Proteus. It is 100% functional both there and in my Arduino Uno board (excepting the issue I'm explaining here of course). Both act the same way so I guess there are no issues with any of them :).
Thanks a lot beforehand! May you all need any other sort of information, I'll be glad to provide it.
Kind regards