Saturday, September 16, 2023

Driving a Max98357 with an ESP32C3 single processor arduino


For part of a hobby project, I wanted to replace a piezo buzzer with a speaker. I have heard Arduino can drive speakers directly with PWM (never done it myself), but instead I decided to add a max98357 amp and leverage the ESP32 I2S capabilities to drive it using the Arduino Audio Tools library. 

After first connecting things up, as most people do (all GPIOs should work the same for ESP32), I went to play an audio file from littlefs. The noise produced sounded nothing like the MP3 I was trying to play. To remove some complexity, I changed my code to instead produce a sine wave using the libraries generator functions. The result of this was kind of a really crackly sine tone. One thing I noticed early on was that there was a periodic clicking/popping sound that seemed pretty consistent. I went through and switched out the amp, the Arduino, and the speaker in an attempt to figure out what was causing the problem. A larger speaker helped add some clarity to the tone, but didn't get rid of the clicking noise. I also reduced the sine wave amplitude effectively reducing its volume to make sure it wasn't something to do with peaking. My code looked kind of like this at the time:

AudioInfo info(44100, 2, 16); // sample_rate, channels, bits_per_sample
SineWaveGenerator<int16_t> sineWave(32000);                // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave);             // Stream generated from sine wave
// CsvOutput<int32_t> out(Serial);
I2SStream out;  // Output via I2S
VolumeStream volume(out);
StreamCopy copier(out, sound);

The VolumeStream did not work at the moment, not sure why. Changing the 32000 value reduced the volume of the tone just fine. 

The speakers I ultimately wanted to use for this project were tiny 10mm or 15mm loud speakers, which seem to get hot after running for some time. I guessed that the crackling sound could be straining the speaker and contributing to this issue. 

Finally, after playing around with DMA buffer counts and sizes, I tried reducing the sample rate (as referenced by the author of Arduino Audio Tools blog). That seemed to help solve the crackling/popping issue.

After running the tiny speakers for a little bit with the sine wave tone, they still seem to get hot, but if I only use the speaker periodically and for short form things, I think that will work ok. 

Next I needed to get audio files playing back from littlefs, and possibly using the MP3 decoder or Orvis decoder to keep my file sizes small. We'll see how this little chip can handle loading and playing back files with decoding on top of the other processes. 

No comments: