Noob need help - RPI Pico - howto generate Sound / play mp3?

Hello,
have a Raspberry Pi Pico with a Speaker at GPIO15.

Did not understand how to generate Tones - could someone be so kind and explain
with a Example please ?

Is it possible to play mp3 files ?

Thank you

what does that mean? can you describe the circuit more clearly?

a speaker uses AC signals, and requires two wires. although it's possible to tie one of the signal to ground and treat it like a single ended signal, you have to offset your driving voltage (and preferably use a coupling capacitor to connect the speaker).

but all in all, I don't think GPIO15 (or any of the rp2040 IO pins, IIRC) can output analog signal directly. in theory it maybe possible to use PWM and a filter circuit to generate some analog signal, but I have not done it before, and I don't know what frequency of the spectrum can you actually get.

so if you don't have any special audio driver chip (a.k.a. audio DAC) and the speaker is connected directly to the GPIO pin, the only signal you can generate is square waves.

1 Like

what does that mean? can you describe the circuit more clearly?

This is what I got from device manufacturer

pico_speaker

speaker

The speaker is connected via a low-pass filter, so that sounds can also be generated via PWM:

  • Speaker → GPIO 15
  • Note: Be careful not to leave the pin HIGH for too long. Although there is a low-pass filter to enable the output of PWM signals, there is no high-pass filter!

I’m fairly sure the Pico isn’t nearly powerful enough to decode MP3 at real time, especially given that the ARMv6-M CPU doesn’t have any hardware DSP capabilities. So you’d have to use an uncompressed format, or perhaps some really lightweight compression.

@jdahlstrom ok thanks but genrate some simple tone is possible ?

that looks like a buzzer, you can start with square waves. it might be able to play other waveforms, but I doubt it will have good sound quality.

as a start point, just to generate a 50% duty square wave, say, at 440Hz, just toggle the GPIO pin output use the same code as the blinky example.

to use pwm, you'll have to calculate the value for the clock divider and the counter wrapping value. for the simplest case, the divider default to 1, meaning the counter runs at the same clock rate as the system clock (typically 125MHz), and the wrapping value (the TOP register) is approximately 125MHz / freq. if you need to generate signal with more accurate freqencies, the equation is in section "4.5.2.6. Configuring PWM Period" of rp2040 datasheet. you can also take the micro python pwm driver code as a reference:

1 Like

thank you I will try.... hop my very low knowledge is enough

The suggestion to start with a square wave sounds like a good start to me: You can produce tones that way and confirm that everything is working.


That said, PWM should work OK for producing more "analog" signals, not just square waves. To make the more analog-like signals, the PWM frequency needs to be higher than what we can hear (like 100kHz+).

Then, ~8000-48,000 times per second, update the value being output by PWM. Eg, you could start with sine wave values, where the sine wave has a period of 440Hz. And/or read from a WAV file.

Often there is a way to do this from a buffer - but worst-case you can use a timer interrupt. (again, not sure about RP2040 specifics.) When doing the update with an interrupt, don't calculate anything in the interrupt, just use it to grab the next value from a pre-computer buffer.


There's also protocol called "I2S" which works well for embedded audio purposes. You'll need a separate I2S DAC, which you can find in AliExpress, Adafruit, etc. That's what I personally use (w/ ESP32)


If I remember correctly, PDM (pulse-density-modulation) works better for audio than PWM. I'm sure an RP2040 can do PDM with its PIO, but I have no experience with that, just something you might want to research.


As for MP3, the RP2040 should be powerful enough for that, even with no FPU. But... I don't know of any libraries to recommend. Uncompressed PCM WAV files are typically the best starting place. They are what I use. When I need to convert, I use "Audacity" (https://www.audacityteam.org/)

@tschundler
thank you for the information

thanks it is a device I dont wanna modify ... wanna use as it is

Now have a beep from buzzer

Source: rp-hal-boards/boards/rp-pico/examples/pico_pwm_blink.rs at main · rp-rs/rp-hal-boards · GitHub

PWM info: ValidPwmOutputPin in rp2040_hal::pwm - Rust

// Init PWMs
let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS);

// Configure PWM7
let pwm_speaker = &mut pwm_slices.pwm7;
pwm_speaker.set_ph_correct();
pwm_speaker.enable();

// Output channel B on PWM7 to the Speaker pin gpio15
let channel_speaker = &mut pwm_speaker.channel_b;
channel_speaker.output_to(pins.gpio15);


// Ramp buzzer up
for i in (LOW..=HIGH).skip(100) {
    delay.delay_us(8);
    channel_speaker.set_duty(i);
}
delay.delay_ms(500);

// Ramp buzzer down
for i in (LOW..=HIGH).rev().skip(100) {
    delay.delay_us(8);
    channel_speaker.set_duty(i);
}
delay.delay_ms(500);
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.