strange pulses in PWM signal when using ST Arduino core on STM32F103C8T6

I have an optical quadrature encoder connected to a Bluepill STM32F103C8T6 and I can read it just fine.

I have two LEDs connected to PA8 and PA9 and I wanted to use the 16bit PWM of the STM32 to control the brightness of the LEDs because I’ve only ever used the 8bit PWM of regular AVRs.

If I compile my code with…
Using board ‘genericSTM32F103C’ from platform in folder: C:\Users\dentaku\Documents\Arduino\hardware\Arduino_STM32\STM32F1
Using core ‘maple’ from platform in folder: C:\Users\dentaku\Documents\Arduino\hardware\Arduino_STM32\STM32F1
In void setup ()
I set the outputs as PWM (this is a Maple specific thing)

  pinMode(LED1, PWM); // set pin mode led as PWM output (16bit on STM32 with Maple core)
  pinMode(LED2, PWM); // set pin mode led as PWM output

It does exactly what I expect and I get smooth PWM out of PA8 and PA9 that makes the LEDs change brightness.

PROBLEM: This will only work for a few seconds and then the encoder value stops changing the brightness UNLESS I have Serial Monitor or Serial Plotter open displaying the value being sent to PA8 and PA9. It’s quite strange.
This is the main loop code with all my comments so I don’t forget how this works when I come back to it later :slight_smile: . It checks if the encoder has incremented or decremented, Serial.prints and pwmWrites two the two pins with LEDs on them.

void loop() {
  int encoderValue = encoderRawValue * clickSteps;

  if (lastValue != encoderValue) { //only print if encoderValue has changed
    Serial.print(encoderValue); //NOT println to create two seperate traces in Serial Plotter
    pwmWrite(LED1, encoderValue); //set PWM amount for LED1 linearly
    Serial.print(","); //divider to create two seperate traces in Serial Plotter
    pwmWrite(LED2, ceil(pow(/*1.02189*/1.000169, encoderValue) - 1)); // --set PWM amount for LED2 pin exponentially
    // 256th root of 256 is 1.02189, -1 so encoderValue reaches 0 when turned all the way down, ceil rounds down
    Serial.println(ceil(pow(/*1.02189*/1.000169, encoderValue) - 1));
    lastValue = encoderValue;
  }
}

SO…

I decided to use the ST Arduino core instead of Maple.
This doesn’t understand pwmWrite so you need to set the analogWriteResolution to (16) in setup.

void setup() {
  analogWriteResolution (16); //"C:\Users\dentaku\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.7.0\cores\arduino\wiring_analog.h"
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(PB8), encoderRead, CHANGE); //encoderRead when PB8 changes state
  Serial.begin(9600);
}

void loop() {
  int encoderValue = encoderRawValue * clickSteps;

  if (lastValue != encoderValue) { //only print if encoderValue has changed
    Serial.print(encoderValue); //NOT println to create two seperate traces in Serial Plotter
    analogWrite(LED1, encoderValue); //set PWM amount for LED1 linearly
    Serial.print(","); //divider to create two seperate traces in Serial Plotter
    analogWrite(LED2, ceil(pow(/*1.02189*/1.000169, encoderValue) - 1)); // --set PWM amount for LED2 pin exponentially
    // 256th root of 256 is 1.02189, -1 so encoderValue reaches 0 when turned all the way down, ceil rounds down
//use 1.000169 for 16bit/65536
    Serial.println(ceil(pow(/*1.02189*/1.000169, encoderValue) - 1));
    lastValue = encoderValue;
  }
}

This works even if Serial Monitor/Plotter isn’t open but the output looks horrible on my scope with strange downgoing blips in the trace while the PWM value is changing.
It looks fine when it’s not changing though.
The rising and falling edges of every pulse also have a strange 100kHz blip that happens while the PWM value is changing.
About 2.3us after a pulse rises it goes back to 0 for 2.3us then back up where it’s supposed to be.

I even tried removing all the encoder code and just making the LEDs fade up using a for loop to increment the value and the same thing happens so it doesn’t seem to have anything to do with an interrupt being used to do the encoder reading.

The first two images show the strange behaviour and the third shows what it looks like when the PWM value is NOT changing. This is also what it looks like all the time when using Maple core, in other words, it looks fine.