I was measuring the speed of the analogWrite() on an STM32 Black Pill on some PWM pins and I was getting a result of around 48697 samples per second. This is enough for one line of hifi data: but I wanted to provide at least 4 channels!

This is not good enough: so I generated some new code with 4 PWM output pins using the STMCubeIDE and measured how many duty cycle updates we can do on these 4 channel: I was getting more the 1.2 millions!

This seems to be a much better option. Next I tried to do the same in the STM32 Arduino Timer API and integrated this into my PWMAudioStream version for the STM32: I was using the TIM2 to generate the PWM and TIM3 for driving the sample rate.

Finally, here is an example sketch that tests with 2 output channels:

#include "AudioTools.h"

int channels = 2;
uint16_t sample_rate=44200;
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave);  // Stream generated from sine wave
PWMAudioStream pwm; // Analog output simulated by PWM                 
StreamCopy copier(pwm, sound); // copy in to out

void setup() {
  AudioLogger::instance().begin(Serial, AudioLogger::Warning);  

  // setup sine wave
  sineWave.begin(channels, sample_rate, N_B4);

  // setup PWM output
  auto config = pwm.defaultConfig();
  config.sample_rate = sample_rate;
  config.channels = channels;  

void loop(){

The output goes to the pins PA0, PA1 and to PA2 and PA3 if we would use all 4 channels.


Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *