Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i2s audio test fails on Raspberry Pi Pico and PCM5102A DAC #9910

Closed
stanelie opened this issue Dec 24, 2024 · 5 comments
Closed

i2s audio test fails on Raspberry Pi Pico and PCM5102A DAC #9910

stanelie opened this issue Dec 24, 2024 · 5 comments
Labels
Milestone

Comments

@stanelie
Copy link

CircuitPython version

Adafruit CircuitPython 9.2.1 on 2024-11-20; Raspberry Pi Pico with rp2040

Code/REPL

import audiobusio
import audiocore
import board
import array
import time
import math

I2S_CLK = board.GP2
I2S_WS = board.GP3
I2S_DATA = board.GP4

# Generate one period of sine wave.
length = 8000 // 440
sine_wave = array.array("H", [0] * length)
for i in range(length):
    sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15)

sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
i2s = audiobusio.I2SOut(I2S_CLK, I2S_WS, I2S_DATA)
i2s.play(sine_wave, loop=True)
time.sleep(1)
i2s.stop()

Behavior

This sounds like the busy tone on a phone in north america, not the pure sine wave I should be getting.

I've used this DAC on a ESP32-C3 chip with no issue, I know it works fine. There have been other issues a bit similar to this in the past with the Pi Pico, not sure if it's related. Should I be using those pins?

Description

No response

Additional information

No response

@stanelie stanelie added the bug label Dec 24, 2024
@stanelie
Copy link
Author

Also, I notice that the bit clock signal looks like this (example pulled off the net, not actual signal) instead of a true square wave :
response-to-square-wave-T=10RC
On my other ESP32 board, it is a true square wave, with sharp corners.

@relic-se
Copy link

The sine wave data that you're generating is unsigned 16-bit ("H"). I believe that the PCM5102A is expecting signed data ("h"). I'd try changing the array format and remove + 2 ** 15. It might also be a good idea to take down the amplitude a bit. If your going straight from the DAC into headphones, I find it can struggle at high volumes since that chip does not actually have a headphone amp built-in. It outputs line level audio. I can test your code later today otherwise.

As for the shape of the clock signal, most all digital signals are not going to have perfect edges for a variety of reasons. I'm not an expert on that topic, and its "fix" is outside of the scope of CircuitPython. Most likely, it will not make a difference unless you're operating at very high sample rates. The PCM5102A tops out at 384Khz, which would require a bit clock rate of 24.5Mhz.

@stanelie
Copy link
Author

Hum... If the unsigned or signed 16bit were the issue, shouldn't it also not work with the other board? Since it works with the ESP32 with the exact same code (aside from the pins assignment), doesn't that indicate that the PCM5102A is compatible with unsigned and that the issue lies elsewhere? Same thing with the amplitude?

On the ESP32, the bit clock is very square. I would expect a "sawtooth" waveform like this if I were trying to go too fast for the chip I use (RP2040).

@dhalbert
Copy link
Collaborator

I tried the program above on four boards, all running CircuitPython 9.2.1. All sounded the same:

  • Feather RP2040 Prop-Maker, using the built-in I2C amplifier
  • Using a MAX98357A outboard I2S amp:
    • Feather RP2040
    • Feather ESP32-S3
    • Feather nRF52840

In addition, I looked at all the I2S signal waveforms coming out of the RP2040, using a 100MHz oscilloscope. The bit clock was a square wave (and so were the other signals).

Looking at the actual audio waveform is a mess, because it's not low-pass filtered.

BTW, in the program above, you'll get a "doesn't fit in 2 bytes error" if the frequency is exactly divides into 8000, because the largest sample will be 65536. I changed the code slightly to int(math.sin(math.pi * 2 * i / length) * (2 ** 15 - 1) + 2 ** 15) to fix that.

So I'm not sure why you're seeing the issue you're seeing. What are you using to look at the waveform? A shape like what you see would indicate inadequate drive or excessive capacitance on the driven line.

@dhalbert dhalbert added this to the Support milestone Dec 24, 2024
@stanelie
Copy link
Author

Damn it. My fault.
The board I was using already had something connected to the GPIO I was using, hence, the deformed signal.
So sorry about the wasted time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants