r/arduino • u/CodingKing256 • 6d ago
Can anyone please help with a polyphonic buzzers project?
I've been trying to make a project with multiple buzzers, my goal is at least three, using an Arduino R4 WiFi board. I've read some information, and downloaded the MusicWithoutDelay tone library, but can't seem to get it started because it's a bit out of my league, especially with manually updating the Tone library, which the MusicWithoutDelay library says to do with a this link. It would be much appreciated if anybody could help!
3
u/ripred3 My other dev board is a Porsche 6d ago edited 6d ago
I have not worked with that specific library although it looks interesting and fairly well supported
A couple of other libraries (one includes a C support program) come to mind when you mention polyphonic sound:
Len Shustek's miditones software (a simple ANSI C program - works everywhere) and his arduino_playtune library. The code is brilliant and his implementation of the arduino_playtune runtime supports polyphonic output using anywhere from 1 to 8 output pins! Even on the Arduino Uno!
2
u/CodingKing256 6d ago
Thank you for your response! I currently do not know any C and have seen the Mozzi platform before while researching this project, but it's kind of out of my goal for the project, which was to use the piezoelectric buzzers and take them to their capacity with vibrato, dynamics, etc. because of the distinctive sound they produce. This is a YouTuber I found with a similar idea.
1
u/ripred3 My other dev board is a Porsche 6d ago
yeah either of those libraries can be fun to experiment with using multiple piezo discs. By the way if you have the flat piezo discs you can superglue the flat brass side to the bottom of a plastic cup (like the thin plastic disposable bathroom cups) to get a megaphone type amplification and make the output easier to hear without needing electrical amplification. It's not high fidelity but it works in a pinch. some plezos also come enclosed in a small disc housing with a small hole in the center and that amplifies the sound much more
1
u/adderalpowered 6d ago
You should check out JME (the link you provided) on his github. It has the answers to most of your questions.
2
u/Timmah_Timmah 6d ago
Would you be ok using an esp32? I would just bit bang them and not use the hardware timers.
1
u/CodingKing256 6d ago
As of now, I don't own an ESP32, and the only boards I have are an Arduino R3 and the R4 WiFi.
1
u/Timmah_Timmah 6d ago
I'm not sure they are fast enough. But you could try. I would structure the loop like blink without delay and add two more ifs that toggle the same pin, but at different intervals.
1
u/CodingKing256 6d ago
I see how this would work, but I think that with LEDs updating their state very quickly is less obvious than a buzzer. It would attempt to power one buzzer at a time in rapid succession, instead of controlling them together, and doing that at the same time as gathering current note data and volume might not work at all or run very well.
1
u/Timmah_Timmah 6d ago
You're not powering a buzzer you are driving a speaker coil in and out.
Don't underestimate how fast these things are.
1
u/CodingKing256 6d ago
In that case, is it possible to do the same with only one buzzer and create the illusion of multiple notes? I tried doing this once before but after a certain speed they didn't produce the correct sound anymore.
1
u/Timmah_Timmah 6d ago
Yes, with one speaker. If you are using a piezo speaker the resonant frequency will play a big part in the sound. You might have also run out of cycles in the main loop. Don't use digitalWrite because it is very slow. Instead write directly to the output register. If you get to the end of the loop and you haven't toggled the pin write a high to another pin. This way you can see if you are running too much during the loop.
1
u/CodingKing256 6d ago
I haven't ever used anything other than DigitalWrite to control the pitch; how do you write to the output register?
1
u/Timmah_Timmah 6d ago
From. Deep seek: You can achieve much faster pin control by writing directly to the microcontroller's port registers. The exact method depends on your board's architecture, but the two main approaches are direct register manipulation or using fast I/O libraries.
🎯 For Classic AVR Boards (Uno, Nano, Mega)
These boards use 8-bit ports (e.g., PORTB, PORTC, PORTD). Use DDRx to set direction and PORTx to set values:
cpp // Set pin 13 (Port B, bit 5) as OUTPUT DDRB |= (1 << 5); // Set pin 13 HIGH PORTB |= (1 << 5); // Set pin 13 LOW PORTB &= ~(1 << 5);⚠️ Warning: PORTB |= (1 << 5) is non-atomic. If an interrupt fires mid-operation, it can corrupt the port's state .
⚡ For Modern AVR Boards (Uno R4, Nano Every)
These use modern megaAVR architecture with dedicated registers for atomic, safer updates:
cpp // Configure pin 4 on PORTA as output PORTA.DIRSET = PIN4_bm; // Set pin 4 HIGH (atomic) PORTA.OUTSET = PIN4_bm; // Set pin 4 LOW (atomic) PORTA.OUTCLR = PIN4_bm; // Toggle pin 4 (atomic) PORTA.OUTTGL = PIN4_bm;Atomic operations prevent interrupts from corrupting the pin state and are generally faster .
🚀 For ARM Boards (Due, Zero)
On 32-bit ARM boards, use the PIO (Parallel I/O) controller registers:
cpp // Set bit 1 on PORTC HIGH (Atomic) REG_PIOC_SODR = 0x00000002; // Set bit 1 on PORTC LOW (Atomic) REG_PIOC_CODR = 0x00000002; // Write all 32 bits at once (Use with OWSR for specific pins) [citation:9] REG_PIOC_ODSR = 0x00000002;📚 Easier Alternative: Fast I/O Libraries
If mapping pins to registers feels too complex or error-prone, consider using a library that handles it automatically:
· digitalWriteFast : Popular library that provides digitalWriteFast(pin, state), compiling to single-instruction port access for compile-time known pins . · Arduino-GPIO : Template-based library for safe, fast, portable GPIO access without manual register calculations . · Built-in digitalWriteFast (Some cores) : Boards like Nano Every with MegaCoreX include direct functions like digitalWriteFast() .
⚠️ Critical Warning: Direct register access is non-portable—code written for an Uno will not work on a Due or ESP32 without rewriting. Libraries offer a safer balance of speed and portability .
To provide the exact code for your setup, could you tell me which specific Arduino board you are using?
1
u/Delta_G_Robotics 6d ago
Just a heads up, none of this code works on the UNO R4. I guess DeepSeek missed the board type. There are direct port manipulations that look a lot like what is there for 32-bit ARM boards. But none of that stuff at the top. That all applies to AVR boards. The R4 has much more powerful port functions.
→ More replies (0)

5
u/Delta_G_Robotics 6d ago
On your R4 WiFi, every single pin is backed by a 16 bit timer with a waveform generator. You could just use the regular timer setup to output whatever square wave you want on each pin independently and from hardware. You could even set up to load the registers from an array with DMA and the whole song uses no code and just runs in the background.